---
title: Authentication SDK Reference
description: User authentication and profile management with the InsForge Kotlin SDK
---

import KotlinSdkInstallation from '/snippets/kotlin-sdk-installation.mdx';


## Installation

<KotlinSdkInstallation />

## signUp()

Create a new user account with email and password.

### Parameters

- `email` (String) - User's email address
- `password` (String) - User's password
- `name` (String?, optional) - User's display name

### Returns

```kotlin
SignUpResponse
```

### SignUpResponse

```kotlin
data class SignUpResponse(
    /** User object (null when email verification is required) */
    val user: User? = null,
    /** Access token (null when email verification is required) */
    val accessToken: String? = null,
    /** Indicates if email verification is required before sign-in */
    val requireEmailVerification: Boolean = false,
    /** Redirect URL (if applicable) */
    val redirectTo: String? = null,
    /** CSRF token (if applicable) */
    val csrfToken: String? = null,
    /** Refresh token (null when email verification is required) */
    val refreshToken: String? = null
)
```

### Example (Complete Flow with Verification)

```kotlin
class AuthViewModel : ViewModel() {

    // Sign up and handle verification requirement
    suspend fun signUp(email: String, password: String, name: String?) {
        try {
            val result = client.auth.signUp(
                email = email,
                password = password,
                name = name
            )

            if (result.requireEmailVerification) {
                // Show verification code input screen
                // User will receive a 6-digit code via email
                _uiState.value = AuthUiState.RequiresVerification(email)
            } else if (result.accessToken != null) {
                // Registration complete, user is signed in
                _uiState.value = AuthUiState.Authenticated
            }
        } catch (e: InsforgeHttpException) {
            _uiState.value = AuthUiState.Error(e.message ?: "Sign up failed")
        }
    }

    // Verify email with 6-digit code
    suspend fun verifyEmail(email: String, code: String) {
        try {
            client.auth.verifyEmail(email = email, code = code)
            // Verification successful, user can now sign in
            _uiState.value = AuthUiState.VerificationSuccess
        } catch (e: InsforgeHttpException) {
            _uiState.value = AuthUiState.Error("Invalid verification code")
        }
    }

    // Resend verification email
    suspend fun resendVerificationEmail(email: String) {
        try {
            client.auth.resendVerificationEmail(email = email)
            // Show success message
        } catch (e: InsforgeHttpException) {
            _uiState.value = AuthUiState.Error("Failed to resend verification email")
        }
    }
}

sealed class AuthUiState {
    object Initial : AuthUiState()
    object Authenticated : AuthUiState()
    object VerificationSuccess : AuthUiState()
    data class RequiresVerification(val email: String) : AuthUiState()
    data class Error(val message: String) : AuthUiState()
}
```

### Email Verification

For users who register with email, the InsForge backend provides three options:

1. **No email verification** - Users can sign in immediately after registration. `SignUpResponse` will have `accessToken != null`.
2. **Link-based verification** - Users must open their email and click the verification link before they can sign in.
3. **Code-based verification** - The InsForge backend sends a 6-digit verification code to the user's email. The client app needs to display a verification screen where users can enter the code, then call `verifyEmail(email, code)` to complete verification. Only after this can users sign in with email + password.

When `requireEmailVerification` is `true`, the response will have:
- `accessToken = null`
- `user = null`
- `requireEmailVerification = true`

This indicates that verification via option 2 or 3 is required before the user can sign in.

### Related Methods

| Method | Description |
|--------|-------------|
| `verifyEmail(email, code)` | Verify email with 6-digit code |
| `resendVerificationEmail(email)` | Resend verification email |

---

## signIn()

Sign in an existing user with email and password.

### Example

```kotlin
try {
    val result = client.auth.signIn(
        email = "user@example.com",
        password = "secure_password123"
    )

    result.user?.let { user ->
        Log.d("Auth", "Welcome back, ${user.profile?.name ?: user.email}")
    }
} catch (e: InsforgeHttpException) {
    Log.e("Auth", "Sign in failed: ${e.message}")
}
```

### Email Verification

If the sign in response is:
```json
{"error":"FORBIDDEN","message":"Email verification required","statusCode":403,"nextActions":"Please verify your email address before logging in"}
```
This indicates that verification via option 2 or 3 (link or code, see [signUp()](#email-verification)) is required before the user can sign in.

---

## signOut()

Sign out the current user.

### Example

```kotlin
try {
    client.auth.signOut()
    Log.d("Auth", "User signed out")
} catch (e: InsforgeException) {
    Log.e("Auth", "Sign out failed: ${e.message}")
}
```

---

## signInWithOAuthPage()

Sign in directly with a specific OAuth provider. This method opens the OAuth provider's authentication page directly in the system browser.

### Supported Providers

```kotlin
enum class OAuthProvider(val value: String) {
    GOOGLE("google"),
    GITHUB("github"),
    DISCORD("discord"),
    LINKEDIN("linkedin"),
    FACEBOOK("facebook"),
    INSTAGRAM("instagram"),
    TIKTOK("tiktok"),
    APPLE("apple"),
    X("x"),
    SPOTIFY("spotify"),
    MICROSOFT("microsoft")
}
```

### Parameters

- `provider` (`OAuthProvider`) - The OAuth provider to authenticate with
- `redirectUri` (`String`) - Callback URL where InsForge will redirect after authentication

### Returns

```kotlin
String  // The OAuth authorization URL (also opens in browser automatically)
```

### Example

1. Configure BrowserLauncher

When creating the InsForge client, configure the `browserLauncher` to handle opening URLs:

```kotlin
val client = createInsforgeClient(baseURL, anonKey) {
    install(Auth) {
        browserLauncher = BrowserLauncher { url ->
            val customTabsIntent = CustomTabsIntent.Builder()
                .setShowTitle(true)
                .build()
            // Handle non-Activity context safely
            if (context is Activity) {
                customTabsIntent.launchUrl(context, Uri.parse(url))
            } else {
                customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                customTabsIntent.launchUrl(context, Uri.parse(url))
            }
        }
        persistSession = true
        sessionStorage = mySessionStorage
    }
}
```

2. Configure App Link / Deep Link Callback

Configure your callback Activity in AndroidManifest.xml:

- Option A: Custom URL Scheme (for Development)

```xml
<activity
    android:name=".AuthCallbackActivity"
    android:launchMode="singleTask"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="yourapp" android:host="auth" android:path="/callback" />
    </intent-filter>
</activity>
```

- Option B: App Links (for Production)

```xml
<activity
    android:name=".AuthCallbackActivity"
    android:launchMode="singleTask"
    android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="yourdomain.com" android:path="/auth/callback" />
    </intent-filter>
</activity>
```

3. Initiate OAuth Login with Specific Provider

```kotlin
// Start OAuth flow with Google
fun startGoogleLogin() {
    lifecycleScope.launch {
        val authUrl = client.auth.signInWithOAuthPage(
            OAuthProvider.GOOGLE,
            "yourapp://auth/callback"
        )
        // Browser opens automatically via browserLauncher
    }
}
```

4. Handle OAuth Callback

```kotlin
class AuthCallbackActivity : AppCompatActivity() {
    // Example: read the shared InsForge client from your Application class.
    private val client by lazy { (application as MyApp).insforgeClient }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { handleIntent(it) }
    }

    private fun handleIntent(intent: Intent) {
        intent.data?.let { uri ->
            lifecycleScope.launch {
                try {
                    val result = client.auth.handleAuthCallback(uri.toString())

                    Toast.makeText(
                        this@AuthCallbackActivity,
                        "Success: ${result.email}",
                        Toast.LENGTH_SHORT
                    ).show()

                    startActivity(Intent(this@AuthCallbackActivity, MainActivity::class.java))
                    finish()
                } catch (e: Exception) {
                    Toast.makeText(
                        this@AuthCallbackActivity,
                        "Failed: ${e.message}",
                        Toast.LENGTH_LONG
                    ).show()
                    finish()
                }
            }
        }
    }
}
```

`client` should come from the same shared InsForge client instance you use elsewhere in the app, such as an `Application` singleton or your DI container.

---

## getCurrentUser()

Fetch the current authenticated user from the server. This is a suspend function that makes a network request.

### Returns

```kotlin
CurrentUserResponse  // Contains user data from server
```

### Example

```kotlin
try {
    val response = client.auth.getCurrentUser()
    Log.d("Auth", "Email: ${response.email}")
    Log.d("Auth", "Name: ${response.profile?.name ?: "N/A"}")
} catch (e: InsforgeHttpException) {
    Log.e("Auth", "Failed to get user: ${e.message}")
}
```

<Note>
This method makes a network request to fetch user data. For accessing locally cached user state, use `currentUser` StateFlow instead.
</Note>

---

## updateProfile()

Update current user's profile.

### Parameters

- `profile` (`Map\<String, Any\>`) - Profile fields to update

### Returns

```kotlin
ProfileResponse  // Updated profile data
```

### Example

```kotlin
try {
    val result = client.auth.updateProfile(
        mapOf(
            "name" to "JohnDev",
            "bio" to "Android Developer",
            "avatar_url" to "https://example.com/avatar.jpg"
        )
    )
    Log.d("Auth", "Profile updated: ${result.name}")
} catch (e: InsforgeHttpException) {
    Log.e("Auth", "Update failed: ${e.message}")
}
```

---

## Password Reset

InsForge supports two password reset methods, configured in the backend:

- **Code method**: User receives a 6-digit code via email, verifies it to get a reset token, then resets password
- **Link method**: User receives a magic link via email containing the reset token, then resets password directly

### sendPasswordReset()

Send a password reset email to the user. The email will contain either a 6-digit code or a magic link depending on the backend configuration.

#### Parameters

- `email` (String) - User's email address

#### Example

```kotlin
try {
    client.auth.sendPasswordReset(email = "user@example.com")
    // Show message to check email
    showMessage("If your email is registered, you will receive a password reset email.")
} catch (e: InsforgeHttpException) {
    Log.e("Auth", "Failed to send reset email: ${e.message}")
}
```

---

### exchangeResetPasswordToken()

Exchange a 6-digit reset code for a reset token. **This method is only used with the code-based reset flow.**

#### Parameters

- `email` (String) - User's email address
- `code` (String) - 6-digit numeric code received via email

#### Returns

```kotlin
ResetTokenResponse
```

#### ResetTokenResponse

```kotlin
data class ResetTokenResponse(
    /** Reset token to use with resetPassword() */
    val token: String,
    /** Token expiration timestamp */
    val expiresAt: String?
)
```

#### Example

```kotlin
try {
    val response = client.auth.exchangeResetPasswordToken(
        email = "user@example.com",
        code = "123456"
    )
    // Store the token and proceed to password reset screen
    val resetToken = response.token
    showPasswordResetScreen(token = resetToken)
} catch (e: InsforgeHttpException) {
    Log.e("Auth", "Invalid or expired code: ${e.message}")
}
```

---

### resetPassword()

Reset the user's password using a reset token.

#### Parameters

- `newPassword` (String) - New password meeting the configured requirements
- `otp` (String) - Reset token (from `exchangeResetPasswordToken()` for code flow, or from magic link URL for link flow)

#### Example

```kotlin
try {
    client.auth.resetPassword(
        newPassword = "newSecurePassword123",
        otp = resetToken
    )
    // Password reset successful
    showMessage("Password reset successfully. You can now sign in.")
    navigateToSignIn()
} catch (e: InsforgeHttpException) {
    Log.e("Auth", "Password reset failed: ${e.message}")
}
```

---

## Error Handling

```kotlin
import dev.insforge.exceptions.InsforgeHttpException
import dev.insforge.exceptions.InsforgeException

try {
    val result = client.auth.signIn(email, password)
} catch (e: InsforgeHttpException) {
    // HTTP errors from API with error codes
    when (e.error) {
        "INVALID_CREDENTIALS" -> showError("Invalid email or password")
        "USER_NOT_FOUND" -> showError("User not found")
        "EMAIL_NOT_VERIFIED" -> showError("Please verify your email")
        "INVALID_EMAIL" -> showError("Invalid email format")
        "WEAK_PASSWORD" -> showError("Password is too weak")
        else -> showError("Error: ${e.message}")
    }
} catch (e: InsforgeException) {
    // Other SDK errors (network, parsing, etc.)
    showError("Error: ${e.message}")
}
```

### Common Error Codes

| Error Code | Description |
|------------|-------------|
| `INVALID_CREDENTIALS` | Email or password is incorrect |
| `USER_NOT_FOUND` | No user with this email exists |
| `EMAIL_NOT_VERIFIED` | Email verification required |
| `INVALID_EMAIL` | Email format is invalid |
| `WEAK_PASSWORD` | Password doesn't meet requirements |
| `USER_ALREADY_EXISTS` | Email is already registered |
| `SESSION_EXPIRED` | Session has expired, re-login required |
