> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Android SDK

> Native Android Kotlin SDK for KYC, KYB, biometric liveness, and AML. Jetpack Compose, NFC, on-device capture. Pay-per-call from $0.30, 500 free/month.

export const AgentPromptAccordion = ({prompt, title = "AI Agent Integration Prompt"}) => {
  const [copied, setCopied] = React.useState(false);
  const handleCopy = e => {
    e.stopPropagation();
    if (!prompt) return;
    navigator.clipboard.writeText(prompt.trim()).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  const agents = ["Claude Code", "Codex", "Cursor", "Devin", "Windsurf", "GitHub Copilot"];
  return <div className="didit-agent-card">
      {}
      <div className="didit-agent-titlebar">
        <div className="didit-agent-dots" aria-hidden="true">
          <span className="didit-agent-dot didit-agent-dot-red"></span>
          <span className="didit-agent-dot didit-agent-dot-yellow"></span>
          <span className="didit-agent-dot didit-agent-dot-green"></span>
        </div>
        <span className="didit-agent-filename">{title}</span>
        <button type="button" className={`didit-agent-copy ${copied ? "didit-agent-copy-copied" : ""}`} onClick={handleCopy} title="Copy prompt to clipboard" aria-label={copied ? "Copied!" : "Copy prompt to clipboard"}>
          {copied ? <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <path d="M3 8.5l3.5 3.5L13 4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              <span>Copied</span>
            </> : <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5" />
                <path d="M11 5V3.5A1.5 1.5 0 0 0 9.5 2h-6A1.5 1.5 0 0 0 2 3.5v6A1.5 1.5 0 0 0 3.5 11H5" stroke="currentColor" strokeWidth="1.5" />
              </svg>
              <span>Copy</span>
            </>}
        </button>
      </div>

      {}
      <pre className="didit-agent-body"><code>{prompt.trim()}</code></pre>

      {}
      <div className="didit-agent-footer">
        <span className="didit-agent-footer-label">Paste into</span>
        <div className="didit-agent-chips">
          {agents.map(name => <span key={name} className="didit-agent-chip">{name}</span>)}
        </div>
      </div>
    </div>;
};

<AgentPromptAccordion
  title="Android SDK Integration Prompt"
  prompt={`Integrate Didit identity verification into my Android app using the native Kotlin SDK.

## Requirements
- Android API 21+ (Android 5.0 Lollipop). ML-based auto-detection (document/face) requires API 24+ and falls back to manual capture below that.
- Kotlin 1.9+
- NFC reading requires NFC-capable device hardware

## Installation

### Step 1: Add Maven Repository
In settings.gradle.kts:
dependencyResolutionManagement {
repositories {
    google()
    mavenCentral()
    maven { url = uri("https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository") }
}
}

### Step 2: Add Dependency
(!) Regarding the version ensure you check the [GitHub repository](https://github.com/didit-protocol/sdk-android) for the latest version.
In app/build.gradle.kts:
dependencies {
implementation("me.didit:didit-sdk:3.5.8")
}

### Step 3: Add Packaging Exclusion (required to avoid build conflicts)
In the android { } block of app/build.gradle.kts:
android {
packaging {
    resources {
        excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
    }
}
}

## Permissions (auto-merged from SDK manifest)
- INTERNET (required) — API communication
- ACCESS_NETWORK_STATE (required) — Network availability
- CAMERA (required) — Document scanning and face verification
- NFC (optional) — Read NFC chips in passports/IDs

Camera and NFC are declared as optional features (android:required="false"), so the app installs on all devices.

## Initialization (required)
In your Application class:
import me.didit.sdk.DiditSdk

class MyApp : Application() {
override fun onCreate() {
    super.onCreate()
    DiditSdk.initialize(this)
}
}

Register in AndroidManifest.xml:
<application android:name=".MyApp" ...>

## Backend: Create Session (your server)
POST https://verification.didit.me/v3/session/
Headers: { "x-api-key": DIDIT_API_KEY, "Content-Type": "application/json" }
Body: { "workflow_id": DIDIT_WORKFLOW_ID, "vendor_data": "user-id" }
Response: { "session_id": "uuid", "session_token": "short-token", "url": "https://verify.didit.me/session/short-token", "status": "Not Started" }
Send session_token to the Android app (never expose DIDIT_API_KEY to the device).

## Jetpack Compose Integration
import me.didit.sdk.DiditSdk
import me.didit.sdk.DiditSdkState
import me.didit.sdk.VerificationResult

// Observe SDK state and launch UI when ready
LaunchedEffect(Unit) {
DiditSdk.state.collect { state ->
    when (state) {
        is DiditSdkState.Ready -> DiditSdk.launchVerificationUI(activity)
        is DiditSdkState.Error -> Log.e("Didit", "Error: state.message")
        else -> { /* Loading, Idle, CreatingSession */ }
    }
}
}

// Start verification with session token from backend
import me.didit.sdk.VerificationStatus

fun startVerification(token: String) {
DiditSdk.startVerification(token = token) { result ->
    when (result) {
        is VerificationResult.Completed -> when (result.session.status) {
            VerificationStatus.APPROVED -> { /* grant access */ }
            VerificationStatus.DECLINED -> { /* show retry */ }
            VerificationStatus.PENDING  -> { /* under review */ }
        }
        is VerificationResult.Cancelled -> { /* user cancelled */ }
        is VerificationResult.Failed    -> { /* show error: result.error.message */ }
    }
}
}

## Result Statuses (VerificationStatus enum; .rawValue gives "Approved" / "Pending" / "Declined")
- VerificationStatus.APPROVED — user identity verified, grant access
- VerificationStatus.DECLINED — verification failed, show retry or contact support
- VerificationStatus.PENDING  — needs manual review by your compliance team

## Full Verification Results
The SDK only returns the status. Full decision data (document fields, face match scores, AML hits, etc.) arrives via webhook to your backend.
Set up webhooks: https://docs.didit.me/integration/webhooks

## Rate Limits (session creation)
- 600 session-create requests / minute per x-api-key (see https://docs.didit.me/integration/rate-limiting)
- On 429, retry honouring Retry-After / X-RateLimit-* headers

## Environment Variables (backend only — never expose in the Android app)
- DIDIT_API_KEY — from Didit Console > API & Webhooks
- DIDIT_WORKFLOW_ID — from Didit Console > Workflows

## Docs
- Android SDK: https://docs.didit.me/integration/native-sdks/android-sdk
- GitHub: https://github.com/didit-protocol/sdk-android
- Webhooks: https://docs.didit.me/integration/webhooks
- API Reference: https://docs.didit.me/api-reference/overview`}
/>

A lightweight, server-driven Android SDK for identity verification with minimal configuration required.

<Card title="GitHub Repository" icon="github" href="https://github.com/didit-protocol/sdk-android">
  View source code and examples on GitHub
</Card>

<Note>
  ### **Native SDK**: This is the recommended approach for Android apps. Native SDKs provide the best user experience, optimized camera handling, and full NFC support.
</Note>

***

## Requirements

| Requirement     | Minimum Version                                                             |
| --------------- | --------------------------------------------------------------------------- |
| Android API     | 21+ (Android 5.0 Lollipop). ML auto-detection requires API 24+ (see below). |
| Kotlin          | 1.9+                                                                        |
| Jetpack Compose | Included as a transitive dependency                                         |

<Info>
  **Feature availability by API level**: Document and face auto-detection use MediaPipe (API 24+). On API 21–23 devices the SDK falls back to manual capture with a timed shutter button. All other features work across the full API 21+ range.
</Info>

***

## Installation

### Step 1: Add the Repository

Add the Didit Maven repository to the `repositories` block in your `settings.gradle.kts`:

```kotlin theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository") }
    }
}
```

Or if using `settings.gradle` (Groovy):

```groovy theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url "https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository" }
    }
}
```

### Step 2: Add the Dependency

Add the SDK dependency to your app's `build.gradle.kts`:
(!) Regarding the version ensure you check the [GitHub repository](https://github.com/didit-protocol/sdk-android) for the latest version.

```kotlin theme={null}
dependencies {
    implementation("me.didit:didit-sdk:3.5.8")
}
```

Or if using `build.gradle` (Groovy):

```groovy theme={null}
dependencies {
    implementation "me.didit:didit-sdk:3.5.8"
}
```

### Step 3: Add Packaging Exclusion

Add this to your app's `android` block to avoid build conflicts:

```kotlin theme={null}
android {
    packaging {
        resources {
            excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
        }
    }
}
```

That's it! Gradle will automatically resolve all transitive dependencies.

***

## Permissions

The SDK requires the following permissions. These are declared in the SDK's `AndroidManifest.xml` and will be merged automatically into your app's manifest:

| Permission             | Source AAR       | Description                             | Required                                                                         |
| ---------------------- | ---------------- | --------------------------------------- | -------------------------------------------------------------------------------- |
| `INTERNET`             | `didit-sdk-core` | Network access for API communication    | Yes                                                                              |
| `ACCESS_NETWORK_STATE` | `didit-sdk-core` | Detect network availability             | Yes                                                                              |
| `CAMERA`               | `didit-sdk-core` | Document scanning and face verification | Yes                                                                              |
| `NFC`                  | `didit-sdk-nfc`  | Read NFC chips in passports/ID cards    | Auto-merged from `didit-sdk-nfc` (transitive dependency of `me.didit:didit-sdk`) |

### Camera and NFC Features

The SDK declares `android.hardware.camera` and `android.hardware.nfc` as optional features (`android:required="false"`). This ensures your app can be installed on devices without a camera or NFC hardware — the SDK will gracefully handle missing hardware at runtime.

***

## Quick Start

### Step 1: Initialize the SDK

Initialize the SDK in your `Application.onCreate()`:

```kotlin theme={null}
import me.didit.sdk.DiditSdk

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        DiditSdk.initialize(this)
    }
}
```

### Step 2: Start Verification and Handle Results

```kotlin theme={null}
import me.didit.sdk.DiditSdk
import me.didit.sdk.DiditSdkState
import me.didit.sdk.VerificationResult

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Observe SDK state to launch UI when ready
        lifecycleScope.launch {
            DiditSdk.state.collect { state ->
                when (state) {
                    is DiditSdkState.Ready -> DiditSdk.launchVerificationUI(this@MainActivity)
                    is DiditSdkState.Error -> Log.e("Didit", "Error: ${state.message}")
                    else -> { /* Loading, Idle, CreatingSession */ }
                }
            }
        }
    }

    private fun startVerification() {
        // Method 1: UniLink (no backend required)
        DiditSdk.startVerification(
            workflowId = "your-workflow-id",
            vendorData = "user-123"
        ) { result ->
            handleResult(result)
        }

        // Method 2: Backend Session (recommended for production)
        // DiditSdk.startVerification(
        //     token = "your-session-token"
        // ) { result ->
        //     handleResult(result)
        // }
    }

    private fun handleResult(result: VerificationResult) {
        when (result) {
            is VerificationResult.Completed -> {
                Log.d("Didit", "Session: ${result.session.sessionId}")
                Log.d("Didit", "Status: ${result.session.status}")
            }
            is VerificationResult.Cancelled -> {
                Log.d("Didit", "User cancelled")
            }
            is VerificationResult.Failed -> {
                Log.e("Didit", "Failed: ${result.error.message}")
            }
        }
    }
}
```

***

## Integration Methods

The SDK supports two integration methods:

### Method 1: UniLink (Simplest)

No backend required. The SDK creates the session directly using your workflow ID from the Didit Console. Limited to `vendorData` only.

```kotlin theme={null}
DiditSdk.startVerification(
    workflowId = "your-workflow-id",
    vendorData = "user-123"
) { result ->
    handleResult(result)
}
```

### Method 2: Backend Session (Recommended for Production)

Your backend creates the session via the [Create Verification Session API](/sessions-api/create-session) (`POST /v3/session/`) with full parameter support (`contact_details`, `expected_details`, `metadata`, `callback`, etc.), then passes the `session_token` to the SDK.

```kotlin theme={null}
// Your backend creates a session and returns the token
val sessionToken = yourBackend.createVerificationSession(userId = currentUser.id)

// Pass the token to the SDK
DiditSdk.startVerification(
    token = sessionToken
) { result ->
    handleResult(result)
}
```

This approach gives you full control over:

* Associating sessions with your users (`vendor_data`)
* Setting custom metadata
* Configuring callbacks per session
* Providing contact details and expected details for cross-validation

***

## Configuration

Customize the SDK behavior:

```kotlin theme={null}
import me.didit.sdk.Configuration
import me.didit.sdk.core.localization.SupportedLanguage

val configuration = Configuration(
    languageLocale = SupportedLanguage.SPANISH,  // Force Spanish language
    fontFamily = "my_custom_font",                // Custom font (must be in res/font/)
    loggingEnabled = true                         // Enable debug logging
)

DiditSdk.startVerification(
    token = "your-session-token",
    configuration = configuration
) { result ->
    handleResult(result)
}
```

### Configuration Options

| Property               | Type                 | Default       | Description                                                                             |
| ---------------------- | -------------------- | ------------- | --------------------------------------------------------------------------------------- |
| `languageLocale`       | `SupportedLanguage?` | Device locale | Force a specific language                                                               |
| `fontFamily`           | `String?`            | System font   | Custom font resource name (from `res/font/`)                                            |
| `loggingEnabled`       | `Boolean`            | `false`       | Enable SDK debug logging                                                                |
| `showCloseButton`      | `Boolean`            | `true`        | Show close (X) button on verification step screens                                      |
| `showExitConfirmation` | `Boolean`            | `true`        | Show confirmation dialog when user attempts to exit                                     |
| `closeOnComplete`      | `Boolean`            | `false`       | Auto-dismiss verification UI when complete (Web SDK equivalent: `closeModalOnComplete`) |

<Info>
  Options `showCloseButton`, `showExitConfirmation`, and `closeOnComplete` match the Web SDK's `DiditSdkConfiguration`. Mobile-specific options `languageLocale` and `fontFamily` exist because the mobile SDK renders the full verification UI natively (unlike the Web SDK which delegates to the hosted frontend inside an iframe).
</Info>

<Info>
  **Theming & Colors**: Colors, backgrounds, and intro screen settings are configured through your [White Label settings](https://business.didit.me) in the Didit Console, not in the SDK configuration. This ensures consistent branding across all platforms.
</Info>

***

## Language Support

The SDK supports **53 languages**. If no language is specified, the SDK uses the device locale with English as fallback.

```kotlin theme={null}
// Use device locale (default)
val config = Configuration()

// Force specific language
val config = Configuration(languageLocale = SupportedLanguage.FRENCH)
```

**[View All Supported Languages →](/integration/supported-languages)**

***

## Advanced Options

For advanced session parameters (`contact_details`, `expected_details`, `metadata`, `callback`), use the **Backend Session** method. Your backend calls the [Create Verification Session API](/sessions-api/create-session) with full parameters, then passes the `session_token` to the SDK.

***

## Handling Results

The `VerificationResult` sealed class provides the outcome of the verification:

### Result Cases

| Case                     | Description                                                     |
| ------------------------ | --------------------------------------------------------------- |
| `Completed(session)`     | Verification flow completed (check `session.status` for result) |
| `Cancelled(session)`     | User cancelled the verification flow                            |
| `Failed(error, session)` | An error occurred during verification                           |

### SessionData Properties

| Property    | Type                 | Description                          |
| ----------- | -------------------- | ------------------------------------ |
| `sessionId` | `String`             | Unique session identifier            |
| `status`    | `VerificationStatus` | `APPROVED`, `PENDING`, or `DECLINED` |

### Error Types

All errors are sealed subclasses of `me.didit.sdk.VerificationError`:

| Error                | Description                                                     |
| -------------------- | --------------------------------------------------------------- |
| `SessionExpired`     | The session has expired                                         |
| `NetworkError`       | Network connectivity issue                                      |
| `CameraAccessDenied` | Camera permission not granted                                   |
| `NotInitialized`     | SDK not initialized — call `DiditSdk.initialize(context)` first |
| `ApiError`           | Backend returned an error response                              |
| `RetryBlocked`       | Verification cannot be retried (e.g., max attempts reached)     |
| `Unknown(message)`   | Other error with message                                        |

### Complete Result Handling Example

```kotlin theme={null}
DiditSdk.startVerification(token = "your-token") { result ->
    when (result) {
        is VerificationResult.Completed -> {
            when (result.session.status) {
                VerificationStatus.APPROVED -> {
                    Log.d("Didit", "Approved! Session: ${result.session.sessionId}")
                    // User is verified - grant access
                }
                VerificationStatus.PENDING -> {
                    Log.d("Didit", "Under review. Session: ${result.session.sessionId}")
                    // Show "verification in progress" UI
                }
                VerificationStatus.DECLINED -> {
                    Log.d("Didit", "Declined. Session: ${result.session.sessionId}")
                    // Handle declined verification
                }
            }
        }
        is VerificationResult.Cancelled -> {
            Log.d("Didit", "Cancelled: ${result.session?.sessionId ?: "unknown"}")
            // User chose to cancel - maybe show retry option
        }
        is VerificationResult.Failed -> {
            Log.e("Didit", "Error: ${result.error.message}")
            // Handle error - show retry or contact support
        }
    }
}
```

***

## Observing SDK State

You can observe the SDK state for custom loading UI:

```kotlin theme={null}
lifecycleScope.launch {
    DiditSdk.state.collect { state ->
        when (state) {
            is DiditSdkState.Idle -> {
                // Ready to start verification
            }
            is DiditSdkState.CreatingSession -> {
                // Show "Creating session..." progress
            }
            is DiditSdkState.Loading -> {
                // Show loading indicator
            }
            is DiditSdkState.Ready -> {
                // Verification UI is ready - launch it
                DiditSdk.launchVerificationUI(this@MainActivity)
            }
            is DiditSdkState.Error -> {
                // Show error message
                Log.e("Didit", "Error: ${state.message}")
            }
        }
    }
}
```

***

## ProGuard / R8

The SDK includes its own consumer ProGuard rules. No additional configuration is needed.

If you use R8 full mode, you may need to add this to your `gradle.properties`:

```properties theme={null}
android.enableR8.fullMode=false
```

***

## End-to-End Example (Backend Session → Android SDK → Result)

This pattern is the production-ready integration. Your backend creates the session, your Android app receives the `session_token`, and the SDK runs the flow.

### 1. Backend — create the session

```ts theme={null}
// Node.js / Express example. Run on your server. NEVER ship DIDIT_API_KEY to the device.
import express from "express";

const app = express();
app.use(express.json());

app.post("/api/verification/start", async (req, res) => {
  const response = await fetch("https://verification.didit.me/v3/session/", {
    method: "POST",
    headers: {
      "x-api-key": process.env.DIDIT_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      workflow_id: process.env.DIDIT_WORKFLOW_ID,
      vendor_data: req.body.userId, // your stable user id
    }),
  });

  if (!response.ok) {
    return res.status(500).json({ error: `Didit ${response.status}` });
  }

  const { session_id, session_token } = await response.json();
  // Persist session_id <-> userId so you can match the webhook later.
  res.json({ session_id, session_token });
});
```

### 2. Android — exchange and start the SDK

```kotlin theme={null}
import android.app.Activity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.didit.sdk.DiditSdk
import me.didit.sdk.VerificationResult
import me.didit.sdk.VerificationStatus
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.MediaType.Companion.toMediaType
import org.json.JSONObject

class VerificationFlow(private val activity: ComponentActivity) {
    private val http = OkHttpClient()
    private val json = "application/json".toMediaType()

    fun start(userId: String) {
        activity.lifecycleScope.launch {
            val token = withContext(Dispatchers.IO) {
                val body = JSONObject().put("userId", userId).toString().toRequestBody(json)
                val req = Request.Builder()
                    .url("https://your-backend.example.com/api/verification/start")
                    .post(body)
                    .build()
                http.newCall(req).execute().use { resp ->
                    JSONObject(resp.body!!.string()).getString("session_token")
                }
            }

            DiditSdk.startVerification(token = token) { result ->
                when (result) {
                    is VerificationResult.Completed -> when (result.session.status) {
                        VerificationStatus.APPROVED -> { /* optimistic UI; rely on webhook for source of truth */ }
                        VerificationStatus.PENDING  -> { /* show "under review" */ }
                        VerificationStatus.DECLINED -> { /* show retry/contact support */ }
                    }
                    is VerificationResult.Cancelled -> { /* user cancelled */ }
                    is VerificationResult.Failed    -> { /* show error: result.error.message */ }
                }
            }
        }
    }
}
```

### 3. Backend — receive the final decision via webhook

The SDK result is convenient for UI feedback, but the authoritative outcome arrives via webhook. See the [Webhooks guide](/integration/webhooks) for HMAC verification.

```ts theme={null}
app.post("/api/webhooks/didit", express.raw({ type: "application/json" }), (req, res) => {
  // 1. Verify the X-Signature header (see Webhooks docs)
  // 2. Parse the body
  const event = JSON.parse(req.body.toString());
  if (event.webhook_type === "status.updated") {
    // event.session_id, event.status ("Approved" | "Declined" | "In Review" | ...)
    // Look up the user by session_id and update their verification state.
  }
  res.sendStatus(200);
});
```

***

## Complete Example

```kotlin theme={null}
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import me.didit.sdk.Configuration
import me.didit.sdk.DiditSdk
import me.didit.sdk.DiditSdkState
import me.didit.sdk.VerificationResult
import me.didit.sdk.VerificationStatus
import me.didit.sdk.core.localization.SupportedLanguage

class MainActivity : ComponentActivity() {

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

        // Observe SDK state
        lifecycleScope.launch {
            DiditSdk.state.collect { state ->
                when (state) {
                    is DiditSdkState.Ready -> DiditSdk.launchVerificationUI(this@MainActivity)
                    is DiditSdkState.Error -> Log.e("Didit", "Error: ${state.message}")
                    else -> { /* Idle, Loading, CreatingSession */ }
                }
            }
        }
    }

    fun startVerification() {
        val config = Configuration(
            languageLocale = SupportedLanguage.ENGLISH,
            loggingEnabled = true
        )

        // Method 1: UniLink (no backend required)
        DiditSdk.startVerification(
            workflowId = "your-workflow-id",
            vendorData = "user-123",
            configuration = config
        ) { result ->
            handleResult(result)
        }

        // Method 2: Backend Session (recommended for production)
        // DiditSdk.startVerification(
        //     token = "your-session-token",
        //     configuration = config
        // ) { result ->
        //     handleResult(result)
        // }
    }

    private fun handleResult(result: VerificationResult) {
        when (result) {
            is VerificationResult.Completed -> {
                when (result.session.status) {
                    VerificationStatus.APPROVED -> {
                        Log.d("Didit", "Approved! Session: ${result.session.sessionId}")
                    }
                    VerificationStatus.PENDING -> {
                        Log.d("Didit", "Under review")
                    }
                    VerificationStatus.DECLINED -> {
                        Log.d("Didit", "Declined")
                    }
                }
            }
            is VerificationResult.Cancelled -> {
                Log.d("Didit", "Cancelled: ${result.session?.sessionId ?: "unknown"}")
            }
            is VerificationResult.Failed -> {
                Log.e("Didit", "Error: ${result.error.message}")
            }
        }
    }
}
```

***
