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

# Android SDK

> Integrate SmartComply identity verification and liveness detection into your Android app.

# SmartComply Android SDK

The SmartComply Android SDK delivers a fully self-contained identity verification flow for Android apps. Launch one Activity and the SDK handles session management, country and ID-type selection, document capture, identity verification, and liveness detection automatically.

## Features

* **Single-Activity launch** — start verification with one Intent and receive a typed result back
* **Two verification modes** — document photo capture or ID number data entry, configured from your Dashboard
* **Guide-box document capture** — frames the ID card precisely so images are always clean and correctly cropped
* **Liveness detection** — camera-based face challenge system (blink, turn head) runs automatically after identity verification
* **Dynamic ID types** — channels and fields are fetched live from your Dashboard configuration
* **Multi-country support** — renders a country picker automatically when more than one country is configured
* **Dark and light mode** — theme adapts to the system setting; override via the launch intent

***

## Requirements

* **Android API 24** (Android 7.0) or later
* **Kotlin 1.9** or later
* **Jetpack Compose** enabled in your module

***

## Installation

### 1 — Add Maven Central

In `settings.gradle.kts` (already present in most projects):

```kotlin theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
}
```

### 2 — Add the dependency

In your app or feature module `build.gradle.kts`:

```kotlin theme={null}
dependencies {
    implementation("io.github.386konsult:android-sdk:1.0.0")
}
```

### 3 — Enable Compose

```kotlin theme={null}
android {
    buildFeatures {
        compose = true
    }
}
```

***

## Permissions

The SDK declares these permissions automatically via manifest merge. You do not need to add them manually unless your project uses a custom manifest merge strategy:

```xml theme={null}
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
```

The SDK requests the `CAMERA` permission at runtime before the camera is used. Your app does not need to request it separately.

***

## Quick Start

### 1 — Register the result launcher

In your `Activity` or `Fragment`:

```kotlin theme={null}
import androidx.activity.result.contract.ActivityResultContracts
import com.smartcomply.sdk.ui.SmartComplyActivity
import com.smartcomply.sdk.types.FlowResult

val verificationLauncher = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { result ->
    val data = result.data ?: return@registerForActivityResult
    when (data.getStringExtra(SmartComplyActivity.RESULT_TYPE)) {
        SmartComplyActivity.TYPE_SUCCESS -> {
            val entryId      = data.getIntExtra(SmartComplyActivity.RESULT_ENTRY_ID, -1)
            val status       = data.getStringExtra(SmartComplyActivity.RESULT_STATUS)
            val verifiedName = data.getStringExtra(SmartComplyActivity.RESULT_VERIFIED_NAME)
            val idTypeName   = data.getStringExtra(SmartComplyActivity.RESULT_ID_TYPE_NAME)
            // handle success
        }
        SmartComplyActivity.TYPE_FAILURE -> {
            val errorMsg = data.getStringExtra(SmartComplyActivity.RESULT_ERROR_MSG)
            // handle error
        }
        SmartComplyActivity.TYPE_CANCELLED -> {
            // user pressed back
        }
    }
}
```

### 2 — Launch verification

```kotlin theme={null}
import com.smartcomply.sdk.client.Environment
import java.util.UUID

val intent = SmartComplyActivity.buildIntent(
    from        = this,
    apiKey      = "pk_live_xxxxxxxxxxxx",   // your SmartComply API key
    clientId    = UUID.randomUUID().toString(), // unique per verification attempt
    environment = Environment.PRODUCTION
)
verificationLauncher.launch(intent)
```

### Jetpack Compose

If you are launching from a composable, use `rememberLauncherForActivityResult`:

```kotlin theme={null}
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.rememberCoroutineScope
import com.smartcomply.sdk.ui.SmartComplyActivity
import com.smartcomply.sdk.client.Environment
import java.util.UUID

@Composable
fun StartVerificationButton() {
    val context = LocalContext.current

    val launcher = rememberLauncherForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        val data = result.data ?: return@rememberLauncherForActivityResult
        when (data.getStringExtra(SmartComplyActivity.RESULT_TYPE)) {
            SmartComplyActivity.TYPE_SUCCESS   -> { /* handle success */ }
            SmartComplyActivity.TYPE_FAILURE   -> { /* handle error */ }
            SmartComplyActivity.TYPE_CANCELLED -> { /* user cancelled */ }
        }
    }

    Button(onClick = {
        val intent = SmartComplyActivity.buildIntent(
            from        = context,
            apiKey      = "pk_live_xxxxxxxxxxxx",
            clientId    = UUID.randomUUID().toString(),
            environment = Environment.PRODUCTION
        )
        launcher.launch(intent)
    }) {
        Text("Verify Identity")
    }
}
```

***

## buildIntent Parameters

```kotlin theme={null}
fun buildIntent(
    from:        Context,
    apiKey:      String,
    clientId:    String,
    darkTheme:   Boolean? = null,                    // null = follow system
    environment: Environment = Environment.PRODUCTION
): Intent
```

| Parameter     | Default      | Description                                                                      |
| ------------- | ------------ | -------------------------------------------------------------------------------- |
| `from`        | —            | The calling `Context`                                                            |
| `apiKey`      | —            | Your SmartComply API key — find it in the Dashboard                              |
| `clientId`    | —            | A unique ID per verification attempt — use `UUID.randomUUID().toString()`        |
| `darkTheme`   | `null`       | `true` forces dark mode, `false` forces light, `null` follows the device setting |
| `environment` | `PRODUCTION` | `PRODUCTION` for live verification, `SANDBOX` for testing                        |

***

## Result Extras

Read from the `Intent` returned to your activity result callback.

| Constant               | Type     | Present when                                                        |
| ---------------------- | -------- | ------------------------------------------------------------------- |
| `RESULT_TYPE`          | `String` | Always — `"success"`, `"failure"`, or `"cancelled"`                 |
| `RESULT_ENTRY_ID`      | `Int`    | `TYPE_SUCCESS`                                                      |
| `RESULT_STATUS`        | `String` | `TYPE_SUCCESS` — e.g. `"submitted"`, `"verified"`                   |
| `RESULT_SUBMITTED_AT`  | `String` | `TYPE_SUCCESS` — ISO 8601 timestamp                                 |
| `RESULT_VERIFIED_NAME` | `String` | `TYPE_SUCCESS` — full name from the identity provider, if available |
| `RESULT_ID_TYPE_NAME`  | `String` | `TYPE_SUCCESS` — e.g. `"National ID"`, `"BVN"`                      |
| `RESULT_ERROR_MSG`     | `String` | `TYPE_FAILURE`                                                      |

***

## Verification Flow

The SDK steps through these states automatically.

| Step              | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| Loading           | Session creation and brand config fetch                              |
| Welcome           | Brand splash, country picker, and ID type selection                  |
| Camera Permission | Requests camera permission at runtime before any camera is opened    |
| Document Capture  | Camera view for the front (and back, if required) of the ID document |
| ID Input          | Form fields for data-mode verification (BVN, NIN, etc.)              |
| Liveness          | Live camera challenge — blink, turn head                             |
| Processing        | Upload and backend verification in progress                          |
| Success           | Verification complete — shows a summary card, then calls back        |
| Failure           | Unrecoverable error — shows the message and a retry button           |

***

## SDK Configuration

```kotlin theme={null}
data class SDKConfig(
    val apiKey:             String,
    val clientId:           String,
    val environment:        Environment = Environment.PRODUCTION,
    val requestTimeoutMs:   Long        = 30_000L,
    val uploadTimeoutMs:    Long        = 120_000L,
    val maxUploadRetries:   Int         = 3,
    val debug:              Boolean     = false
)
```

| Parameter          | Default      | Description                                               |
| ------------------ | ------------ | --------------------------------------------------------- |
| `apiKey`           | —            | Your SmartComply API key (required)                       |
| `clientId`         | —            | Unique identifier per verification attempt (required)     |
| `environment`      | `PRODUCTION` | `SANDBOX` for testing, `PRODUCTION` for live verification |
| `requestTimeoutMs` | `30000`      | Timeout in milliseconds for standard API calls            |
| `uploadTimeoutMs`  | `120000`     | Timeout in milliseconds for video upload                  |
| `maxUploadRetries` | `3`          | Automatic retry attempts on upload failure                |
| `debug`            | `false`      | Prints verbose network logs to Logcat when `true`         |

***

## Error Handling

`SmartComplyActivity` handles and displays all error states automatically. Common scenarios:

| Scenario                         | Cause                               | Resolution                                                                                      |
| -------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------- |
| `TYPE_FAILURE` with `"401"`      | Invalid or missing API key          | Check your key in the SmartComply Dashboard                                                     |
| `TYPE_FAILURE` — session expired | Session tokens have a 30-minute TTL | Generate a new `clientId` on the next launch                                                    |
| `TYPE_CANCELLED`                 | User pressed back                   | Re-launch when the user is ready to retry                                                       |
| Upload failed                    | Network instability                 | The built-in failure screen offers a retry; if retries are exhausted `TYPE_FAILURE` is returned |

***

## Advanced: Custom Host Activity

If you need to embed the verification flow directly inside your own `ComponentActivity` instead of launching a separate screen, you can use `SmartComplyFlowScreen` as a Compose composable:

```kotlin theme={null}
import com.smartcomply.sdk.SmartComply
import com.smartcomply.sdk.client.SDKConfig
import com.smartcomply.sdk.client.Environment
import com.smartcomply.sdk.ui.SmartComplyFlowScreen
import java.util.UUID

val sdk = SmartComply(
    SDKConfig(
        apiKey      = "pk_live_xxxxxxxxxxxx",
        clientId    = UUID.randomUUID().toString(),
        environment = Environment.PRODUCTION
    )
)

// In your composable:
SmartComplyFlowScreen(
    sdk        = sdk,
    darkTheme  = null,            // null = follow system setting
    onComplete = { result ->
        // result.entryId, result.status, result.verifiedName, etc.
    },
    onError = { message ->
        // unrecoverable error not handled by the built-in failure screen
    }
)
```

<Warning>
  Your host `Activity` must be a `ComponentActivity` and must be in the foreground with an active window. Embedding `SmartComplyFlowScreen` inside a `Dialog` or bottom sheet will cause the camera to fail on some devices.
</Warning>

***

## ProGuard / R8

The SDK ships with its own consumer ProGuard rules. If you see obfuscation-related issues, add to your `proguard-rules.pro`:

```
-keep class com.smartcomply.sdk.** { *; }
-keepattributes *Annotation*
```
