---
icon: device-mobile
label: Android SDK
---

# Android SDK

## Overview

The VerifEye Android SDK (`ai.realeyes.verifeye`) is a Jetpack Compose library for embedding the VerifEye verification flow directly into your Android application. Its single entry point is the [`VerifyVerifier`](#verifyverifier) composable, which renders the full client-side experience — camera access, consent, liveness, and image capture — against a verification session you create server-side.

The SDK handles the on-device capture and the calls to the VerifEye Service. It does **not** create sessions or expose results on its own:

- **Your backend** creates a verification session (using your API key) and returns its `sessionId` and `accessToken` to the app.
- **The `VerifyVerifier` composable** runs the verification using those credentials and invokes `onVerificationCompleted` when the flow finishes.
- **Your backend** fetches the outcome from the [VerifEye Service API](/cloud-apis-web-sdks/verifeye-service-api/#get-session-result) once the flow completes.

!!!tip
Session creation requires your API key and must happen **server-side only**. Never ship your API key inside the app — the SDK only ever receives a short-lived session `accessToken`.
!!!

---

## Prerequisites

- **Android 7.0 (API 24)** or higher, and **Jetpack Compose**.
- A **VerifEye account and API key** from the [VerifEye Developer Console](https://verifeye-console.realeyes.ai/).
- A **server-side endpoint** that creates a verification session and returns its `sessionId` and `accessToken` (see [Quick Start](#quick-start)).

The SDK declares the `CAMERA` and `INTERNET` permissions in its own manifest, so your app inherits them automatically — you do not need to add them. The runtime camera-permission prompt is handled by the SDK.

---

## Installation

Add the dependency to your module's `build.gradle.kts`:

```kotlin
dependencies {
    implementation("ai.realeyes:verifeye-sdk:1.0.2")
}
```

The SDK is built on Jetpack Compose; your app must already apply the Compose Gradle plugin and enable `buildFeatures { compose = true }`.

!!!info compileSdk 35
The SDK is built and tested against **`compileSdk 35`**. It constrains its transitive `androidx.browser` dependency to a 35-compatible version, so your app can stay on `compileSdk 35` — you are **not** forced up to `compileSdk 36`.
!!!

!!!warning Core library desugaring
The SDK uses `java.time` APIs, so apps with a `minSdk` below 26 must enable **core library desugaring**:

```kotlin
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
}
```
!!!

---

## Quick Start

### 1. Create a session on your server

Call the VerifEye Service to [create a verification session](/cloud-apis-web-sdks/verifeye-service-api/#create-session), authenticating with your API key. The response contains the session ID and a short-lived session token, which you return to the app.

```kotlin
// Server-side — never expose your API key to the app
val body = """
{
  "verifierConfigs": {
    "liveness": { "type": "Verification", "challengeType": "Balanced" },
    "age": { "type": "CalculationOnly" },
    "gender": { "type": "CalculationOnly" }
  }
}
"""
// POST https://verifeye-service-api-eu.realeyes.ai/v1/verification/create-session
// Header: Authorization: ApiKey <YOUR_API_KEY>
// Response: { "verificationSessionId": "...", "sessionToken": "..." }
// Return verificationSessionId -> sessionId and sessionToken -> accessToken to the app.
```

### 2. Render the composable in your app

Mount `VerifyVerifier` once the session credentials are available, and react to completion.

```kotlin
import ai.realeyes.verifeye.Region
import ai.realeyes.verifeye.VerifyVerifier

@Composable
fun Verification(sessionId: String, accessToken: String) {
    VerifyVerifier(
        sessionId = sessionId,
        accessToken = accessToken,
        region = Region.EU,
        onVerificationCompleted = { completedSessionId ->
            // The flow has finished. Fetch the outcome from your backend, which
            // calls the VerifEye Service "Get Session Result" endpoint.
        },
    )
}
```

!!!tip
`onVerificationCompleted` fires when the flow finishes — it does **not** tell you whether verification passed or failed. Retrieve the result server-side via [Get Session Result](/cloud-apis-web-sdks/verifeye-service-api/#get-session-result) using the `sessionId`.
!!!

### 3. Read the result on your server

When `onVerificationCompleted` fires, have the app notify your backend, then fetch the outcome from the VerifEye Service [Get Session Result](/cloud-apis-web-sdks/verifeye-service-api/#get-session-result) endpoint — again authenticating with your API key, never from the app.

The result stays available for **7 days** after the session was created, and returns **all** captured fields; fields for verifiers you did not enable are `null`. See [Get Session Result](/cloud-apis-web-sdks/verifeye-service-api/#get-session-result) for the full response schema.

---

## API Reference

### `VerifyVerifier`

```kotlin
@Composable
fun VerifyVerifier(
    sessionId: String,
    accessToken: String,
    onVerificationCompleted: (sessionId: String) -> Unit,
    region: Region = Region.EU,
    onServiceError: ((VerifyServiceOperation) -> Unit)? = null,
    consentSkipMode: ConsentSkipMode? = null,
    headless: Boolean = false,
    headlessCallbacks: HeadlessCallbacks? = null,
    showVerificationSessionId: Boolean = false,
    apiBaseUrlOverride: String? = null,
)
```

The main composable. Render it to run a single verification session. Each session is single-use — to run another verification, create a new session and pass the new `sessionId`. The composable keys its internal state on `sessionId`, so supplying a new one automatically starts a fresh verification (no remount or `key(...)` needed).

#### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sessionId` | `String` | Yes | The verification session ID returned by your server-side `create-session` call. |
| `accessToken` | `String` | Yes | The short-lived session token returned alongside the session ID. |
| `onVerificationCompleted` | `(sessionId: String) -> Unit` | Yes | Called when the verification flow finishes (regardless of pass/fail). Receives the `sessionId`; use it to fetch the result server-side. |
| `region` | [`Region`](#region) | No | The VerifEye region the session belongs to. Must match the region your backend created the session in. Defaults to `Region.EU`. |
| `onServiceError` | `((`[`VerifyServiceOperation`](#verifyserviceoperation)`) -> Unit)?` | No | Called when a backend operation fails. Receives the operation that was in progress when the error occurred. |
| `consentSkipMode` | [`ConsentSkipMode`](#consentskipmode)`?` | No | Controls whether the camera-consent screen is skipped. When `null`, the consent screen is always shown. |
| `headless` | `Boolean` | No | When `true`, runs the verification without the built-in full-screen UI. See [Headless verification](#headless-verification). Defaults to `false`. |
| `headlessCallbacks` | [`HeadlessCallbacks`](#headlesscallbacks)`?` | No | Lifecycle hooks for headless mode. Ignored unless `headless` is `true`. |
| `showVerificationSessionId` | `Boolean` | No | When `true`, displays the verification session ID in the UI (useful for debugging and support). Defaults to `false`. |
| `apiBaseUrlOverride` | `String?` | No | Advanced override for the VerifEye Service base URL the SDK targets. Leave `null` in production — the SDK then targets the production VerifEye Service for the selected `region`. See [Targeting an environment](#targeting-an-environment). |

---

### Supporting types

#### `Region`

```kotlin
enum class Region { EU, US }
```

The supported VerifEye regions.

#### `ConsentSkipMode`

Controls whether the camera-consent screen is shown before capture.

| Member | Value | Meaning |
|--------|-------|---------|
| `ConsentSkipMode.SkipIfCameraGranted` | `"1"` | Skip the consent screen only if camera permission has already been granted. |
| `ConsentSkipMode.AlwaysSkip` | `"2"` | Always skip the consent screen. |

When the `consentSkipMode` parameter is `null`, the consent screen is always shown. See [Consent handling](#consent-handling) for details on when it is safe to skip the built-in consent screen.

#### `VerifyServiceOperation`

```kotlin
enum class VerifyServiceOperation { InitSession, CaptureImage, Verify, Unknown }
```

Identifies which backend operation was in progress when `onServiceError` was invoked.

#### `HeadlessCallbacks`

Lifecycle hooks used in [headless mode](#headless-verification). All are optional.

```kotlin
data class HeadlessCallbacks(
    val onVerificationStarting: (() -> Unit)? = null,
    val onBeforeCameraAccess: (() -> Unit)? = null,
    val onAfterCameraAccess: (() -> Unit)? = null,
)
```

| Callback | Description |
|----------|-------------|
| `onVerificationStarting` | Called just before the verification begins. |
| `onBeforeCameraAccess` | Called immediately before the SDK requests camera access. |
| `onAfterCameraAccess` | Called once camera access has been resolved. |

---

The `VerifyVerifier` composable is the integration entry point. Mount it wherever you would render any other composable — full-screen, inside a bottom sheet, or embedded in a larger screen.

---

## Consent handling

The `VerifyVerifier` flow accesses the user's camera and processes facial (biometric) data to perform liveness and identity verification. Captured images are used solely to carry out the verification — the SDK does not store them or expose raw biometric data to your application.

### Obtaining consent is your responsibility

The hosting application is responsible for obtaining valid, informed user consent for camera access and biometric processing before a verification runs, and for meeting the requirements of the privacy and biometric-data regulations that apply to your users (e.g. GDPR, BIPA, CCPA). See the [Realeyes Privacy Policy](https://realeyes.ai/privacy-policy/).

### Built-in consent screen

By default, the SDK shows its own consent screen before it requests camera access. This behaviour is controlled by the [`consentSkipMode`](#consentskipmode) parameter:

| `consentSkipMode` | Behaviour |
|-------------------|-----------|
| `null` (default) | The consent screen is always shown. |
| `SkipIfCameraGranted` | The consent screen is skipped only if camera permission has already been granted. |
| `AlwaysSkip` | The consent screen is never shown. |

!!!warning
Only disable the built-in consent screen (`SkipIfCameraGranted` or `AlwaysSkip`) when your application already obtains equivalent, legally valid consent for camera access and biometric processing before showing `VerifyVerifier`. If your application does not handle consent itself, leave the built-in consent screen enabled.
!!!

---

## Usage examples

### Standard verification

The default, interactive flow — the SDK renders its own full-screen UI and drives the user through consent, liveness, and capture.

```kotlin
VerifyVerifier(
    sessionId = sessionId,
    accessToken = accessToken,
    region = Region.EU,
    onVerificationCompleted = { handleCompleted(it) },
)
```

### Headless verification

Set `headless` to run a verification without the built-in UI — for example, to silently re-verify a user while they keep using your application. Provide `headlessCallbacks` to hook into the lifecycle, and supply a new `sessionId` (from a new session) for each verification cycle — the composable keys its internal state on `sessionId`, so a new one automatically starts a fresh verification.

```kotlin
VerifyVerifier(
    sessionId = sessionId,
    accessToken = accessToken,
    region = Region.EU,
    headless = true,
    headlessCallbacks = HeadlessCallbacks(
        onVerificationStarting = { /* ... */ },
        onBeforeCameraAccess = { /* ... */ },
        onAfterCameraAccess = { /* ... */ },
    ),
    onVerificationCompleted = { handleCompleted(it) },
    onServiceError = { handleError(it) },
)
```

### Handling service errors

Use `onServiceError` to react to backend failures and inspect which operation failed.

```kotlin
VerifyVerifier(
    sessionId = sessionId,
    accessToken = accessToken,
    region = Region.EU,
    onVerificationCompleted = { handleCompleted(it) },
    onServiceError = { operation ->
        // operation: InitSession | CaptureImage | Verify | Unknown
        Log.e("Verify", "Verification failed during: $operation")
    },
)
```

---

## Targeting an environment

In production, leave `apiBaseUrlOverride` unset — the SDK targets the production VerifEye Service for the selected `region` (`https://verifeye-service-eu.realeyes.ai` or `https://verifeye-service-us.realeyes.ai`).

`apiBaseUrlOverride` is an advanced escape hatch for pointing the SDK at a non-production VerifEye environment while integrating; it must not be set for client applications shipping to production.

---

## Next Steps

- [Web SDK](/cloud-apis-web-sdks/web-sdk/) — the equivalent React library for web applications.
- [iOS SDK](/mobile-sdks/ios-sdk/) — the equivalent library for iOS applications.
- [VerifEye Service API](/cloud-apis-web-sdks/verifeye-service-api/) — manage verification configurations and retrieve session results server-side.
- [Authentication](/cloud-apis-web-sdks/authentication/) — API key and bearer token authentication for server-side calls.

---

*Last updated: 2026-08-04*
