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

# Android

> Install the Legal Talent SDK from GitHub Packages and present the KYC flow

## Requirements

* `minSdk` 26 (Android 8.0)
* JDK 17
* Jetpack Compose in the host app
* A physical device for capture steps

## 1. Get access to the packages

Artifacts are published to GitHub Packages. Ask your Legal Talent contact to add your GitHub users to the partner team, then create a **classic** personal access token with `read:packages` and `repo` (read).

Store the credentials in `~/.gradle/gradle.properties`, never in the project:

```properties theme={null}
gpr.user=YOUR_GITHUB_USERNAME
gpr.token=ghp_...
```

<Note>
  GitHub Packages requires authentication even for public packages. On CI, inject `gpr.user` / `gpr.token` as Gradle properties from your secrets store.
</Note>

## 2. Add the dependency

```kotlin settings.gradle.kts theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri("https://maven.pkg.github.com/legal-talent/legaltalent-android")
            credentials {
                username = providers.gradleProperty("gpr.user").get()
                password = providers.gradleProperty("gpr.token").get()
            }
        }
    }
}
```

```kotlin app/build.gradle.kts theme={null}
dependencies {
    implementation("ai.legaltalent.sdk:legaltalent-ui:0.1.0")
}
```

`legaltalent-ui` brings in core, forensics and liveness. Use `legaltalent-core` alone for a headless integration.

## 3. Permissions and network

The SDK's manifest already declares `CAMERA` (and `NFC` in the NFC module); the SDK requests the runtime permission when a capture step opens. You don't need to add anything.

Keep HTTPS only. Recommended `res/xml/network_security_config.xml`:

```xml theme={null}
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>
```

## 4. Create a session on your backend

Your backend creates the session with its API key and returns only the `access_token` to the app:

```bash theme={null}
curl -X POST https://kyc.legaltalent.ai/kyc/sessions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "YOUR_WORKFLOW_ID",
    "client_id": "your-internal-user-id"
  }'
```

Return `data.access_token` to the app. See [Create Session](/api-reference/sessions#create-session) for every parameter.

<Warning>
  Never call `POST /kyc/sessions` from the app, and never embed the API key in the APK.
</Warning>

## 5. Present the flow

```kotlin theme={null}
import ai.legaltalent.sdk.core.KYCEnvironment
import ai.legaltalent.sdk.ui.LegalTalentFlowView

@Composable
fun OnboardingScreen(accessToken: String, onDone: () -> Unit) {
    LegalTalentFlowView(
        accessToken = accessToken,
        environment = KYCEnvironment.PRODUCTION,
        onComplete = { session ->
            // The applicant finished. The decision arrives on your backend.
            onDone()
        },
    )
}
```

<Note>
  `environment` defaults to `KYCEnvironment.DEV`. Always pass it explicitly: `STAGING` while you integrate, `PRODUCTION` when you go live. The token must come from the same environment.
</Note>

The flow state lives in a `ViewModel` keyed by the access token, so it survives configuration changes such as rotation.

## 6. Handle the result

`onComplete` fires once, after the last step is submitted. Treat it as a UX signal:

1. Navigate away from the flow and show a "verification in progress" screen.
2. Wait for your backend to receive [`kyc.session.processed`](/api-reference/webhooks/sessions) (or the manual `approved` / `rejected` events), or poll [`GET /kyc/sessions/{id}`](/api-reference/sessions#get-session-details) from your backend.
3. Update the app from your backend's state.

<Info>
  Android does not have an `onExit` callback yet. The applicant leaves the flow with the system back gesture, handled by your navigation. The session stays open until it expires, so presenting the flow again with the same token resumes where they left off.
</Info>

## Headless

```kotlin theme={null}
import ai.legaltalent.sdk.core.KYCEnvironment
import ai.legaltalent.sdk.core.LegalTalentClient

val client = LegalTalentClient(accessToken = token, environment = KYCEnvironment.PRODUCTION)
val session = client.getSession()
val workflow = client.getWorkflow()
```

Errors are thrown as `LegalTalentError`; see [Reference](/mobile-sdk/reference#errors).
