> ## 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 Kotlin SDK für Ausweisverifizierung: KYC

> Didit Android-SDK (Kotlin) für Ausweisverifizierung und NFC. Ab $0.33 pro vollständiger KYC-Prüfung, $10 gratis/Monat, ohne Verträge.



Android-SDK-Integrationsprompt
        Prompt in die Zwischenablage kopieren



      
      

\<pre>

\`Integrate Didit identity verification into my Android app using the native Kotlin SDK.

\## Requirements
\- Android API 23+ (Android 6.0 Marshmallow). 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:4.13.2")
}

\### 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`

\</pre>



      
      

Einfügen in

Ein leichtgewichtiges, serverseitig gesteuertes Android SDK für Identitätsverifizierung mit minimalem Konfigurationsaufwand.> [card] [GitHub-Repository](https://github.com/didit-protocol/sdk-android)
>
> Quellcode und Beispiele auf GitHub ansehen> [!NOTE]
>
> ### **Native SDK**: Dies ist der empfohlene Ansatz für Android-Apps. Native SDKs bieten das beste Nutzererlebnis, eine optimierte Kamerasteuerung und volle NFC-Unterstützung.***## Anforderungen| Anforderung | Mindestversion |
| - | - |
| Android-API | 23+ (Android 6.0 Marshmallow). Die ML-gestützte automatische Erkennung erfordert API 24+ (siehe unten). |
| Kotlin | 1.9+ |
| Jetpack Compose | Als transitive Abhängigkeit enthalten |> [!NOTE]
>
> **Funktionsverfügbarkeit nach API-Level**: Die automatische Erkennung von Dokumenten und Gesichtern erfordert API 24+ (eigene schlanke Detektoren von Didit, enthalten in `didit-sdk-core`). Auf Geräten mit API 23 greift das SDK auf die manuelle Aufnahme mit einer zeitgesteuerten Auslösetaste zurück. Alle anderen Funktionen funktionieren im gesamten Bereich ab API 23+.> [!NOTE]
>
> **Die biometrische Einwilligung erfordert natives SDK 4.10.0 oder neuer.** Für Personen, die den Gesetzen von Illinois, Texas oder Colorado unterliegen, kann Didit vor der ersten Gesichtsaufnahme eine ausdrückliche [biometrische Einwilligung](https://docs.didit.me/de/getting-started/biometric-consent.md) einholen. Das Android SDK ab Version 4.10.0 zeigt diesen Schritt an. Frühere Versionen können ihn nicht anzeigen: Ihre Sitzungen laufen wie bisher weiter, und die Entscheidung meldet die Einwilligung als nicht erfasst (`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`). Aktualisieren Sie das SDK, wenn Sie Personen in diesen Bundesstaaten verifizieren.***## Installation### Schritt 1: Repository hinzufügenFügen Sie das Didit-Maven-Repository dem `repositories`-Block in Ihrer `settings.gradle.kts` hinzu:```kotlin theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository") }
    }
}
```Oder falls Sie `settings.gradle` (Groovy) verwenden:```groovy theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url "https://raw.githubusercontent.com/didit-protocol/sdk-android/main/repository" }
    }
}
```### Schritt 2: Abhängigkeit hinzufügenFügen Sie die SDK-Abhängigkeit in der `build.gradle.kts` Ihrer App hinzu:
(!) Prüfen Sie bei der Version im [GitHub-Repository](https://github.com/didit-protocol/sdk-android) die aktuelle Version.```kotlin theme={null}
dependencies {
    implementation("me.didit:didit-sdk:4.13.2")
}
```Oder falls Sie `build.gradle` (Groovy) verwenden:```groovy theme={null}
dependencies {
    implementation "me.didit:didit-sdk:4.13.2"
}
```#### SDK-VariantenDas Android SDK wird als separate Artefakte bereitgestellt, sodass Ihre App nur die Binärgröße der
Funktionen enthält, die sie tatsächlich nutzt. `me.didit:didit-sdk` oben ist das vollständige Bundle. Wählen Sie die Variante, die zu Ihrer App passt:| Artefakt | Automatische Erkennung (ML) | NFC-Chip-Auslesen | Verwenden, wenn |
| - | :-: | :-: | - |
| `me.didit:didit-sdk-core` | ✓ | – | kleinster Build; automatische Aufnahme mit den eigenen Detektoren von Didit, ohne Auslesen von Pass- oder Ausweischips |
| `me.didit:didit-sdk-autodetection` | ✓ | – | seit 4.11.0 veraltet und leer; hängt nur von `didit-sdk-core` ab, daher stattdessen `didit-sdk-core` verwenden |
| `me.didit:didit-sdk-nfc` | ✓ | ✓ | Chip-Auslesen zusätzlich zu `didit-sdk-core` |
| `me.didit:didit-sdk` | ✓ | ✓ | alle Funktionen (vollständiges Bundle) |Seit `4.6.0` wird die native WalletConnect-Wallet-Signierung als eigenes optionales Add-on ausgeliefert, `me.didit:didit-sdk-wallet`.
Das vollständige Bundle `me.didit:didit-sdk` enthält es bereits, daher ändert sich nichts, wenn Sie das Bundle installieren.
Wenn Sie eine der schlankeren Varianten verwenden und die Bestätigung der Wallet-Inhaberschaft nativ in Ihrer App ausführen lassen möchten, fügen Sie `me.didit:didit-sdk-wallet` daneben hinzu. Ohne dieses Add-on schließt das SDK die Wallet-Inhaberschaft über einen sicheren Browser-Ablauf ab, sodass die Funktion in beiden Fällen weiterhin funktioniert.
Das Auslagern von WalletConnect aus `didit-sdk-core` hat außerdem mehrere Megabyte an Wallet-Abhängigkeiten aus allen Builds entfernt, die diese nicht benötigen.Alle Artefakte werden in derselben Version veröffentlicht. Verwenden Sie daher überall `4.13.2`.#### Download-Größe gering haltenDie Erkennungsmodelle für die automatische Aufnahme werden zur Laufzeit heruntergeladen und zwischengespeichert, sodass sie die Größe Ihrer App nie erhöhen.
Die automatische Aufnahme fügt Ihrer App jedoch die native Bibliothek der ML-Laufzeit hinzu. Diese Kosten richten sich nach der CPU-Architektur: etwa 10 MB für `arm64-v8a`, 7 MB für `armeabi-v7a` und 13 MB für jede der beiden x86-Emulator-Architekturen.Um diese Kosten nur einmal zu tragen:1) **Veröffentlichen Sie ein Android App Bundle (AAB).** Google Play liefert nur die Architektur und Sprachen des jeweiligen Geräts aus. Ein arm64-Smartphone installiert damit etwa 10 MB nativen Code (rund 4 MB als komprimierter Download). Ein universelles APK packt dagegen alle vier Architekturen und ist über 40 MB groß, und das ist die häufigste Ursache für unerwartet große Größenangaben.

2) **Wenn Sie ein einzelnes APK verteilen** und Ihre Zielgruppe ARM-Smartphones und -Tablets nutzt, beschränken Sie die gebündelten Architekturen:

   ```kotlin theme={null}
   android {
       defaultConfig {
           ndk { abiFilters += listOf("arm64-v8a", "armeabi-v7a") }
       }
   }
   ```

   Behalten Sie jede ABI bei, die Ihre Nutzer tatsächlich verwenden: Fügen Sie `x86_64` hinzu, wenn Sie Chromebooks oder andere x86-Geräte ansprechen, oder veröffentlichen Sie ABI-spezifische APK-Splits, damit kein Gerät die Unterstützung verliert.

3) **R8 aktivieren:** `isMinifyEnabled = true` und `isShrinkResources = true` im Release-Build-Typ (`minifyEnabled true` / `shrinkResources true`, wenn Sie das Groovy-`build.gradle` verwenden). Das SDK bringt eigene Consumer-Regeln mit, daher wird nicht verwendeter SDK-Code ohne zusätzliche Konfiguration entfernt.

4) **Gebündelte Sprachen begrenzen** mit `resConfigs(...)`, wenn Sie in einem APK-Build nicht alle 48 SDK-Locales benötigen. AAB-Sprachsplits übernehmen dies bei Google Play automatisch.### Schritt 3: Packaging-Ausschluss hinzufügenFügen Sie dies dem `android`-Block Ihrer App hinzu, um Build-Konflikte zu vermeiden:```kotlin theme={null}
android {
    packaging {
        resources {
            excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
        }
    }
}
```Das war's! Gradle löst alle transitiven Abhängigkeiten automatisch auf.***## BerechtigungenDas SDK benötigt die folgenden Berechtigungen. Sie sind in der `AndroidManifest.xml` des SDK deklariert und werden automatisch in das Manifest Ihrer App übernommen:| Berechtigung | Quelle (AAR) | Beschreibung | Erforderlich |
| - | - | - | - |
| `INTERNET` | `didit-sdk-core` | Netzwerkzugriff für die API-Kommunikation | Ja |
| `ACCESS_NETWORK_STATE` | `didit-sdk-core` | Netzwerkverfügbarkeit erkennen | Ja |
| `CAMERA` | `didit-sdk-core` | Dokumentenscan und Gesichtsverifizierung | Ja |
| `NFC` | `didit-sdk-nfc` | NFC-Chips in Pässen und Ausweisen auslesen | Automatisch aus `didit-sdk-nfc` zusammengeführt (transitive Abhängigkeit von `me.didit:didit-sdk`) |### Kamera- und NFC-FunktionenDas SDK deklariert `android.hardware.camera` und `android.hardware.nfc` als optionale Funktionen (`android:required="false"`). So lässt sich Ihre App auch auf Geräten ohne Kamera oder NFC-Hardware installieren. Das SDK behandelt fehlende Hardware zur Laufzeit ordnungsgemäß.***## Schnellstart### Schritt 1: SDK initialisierenInitialisieren Sie das SDK in Ihrer `Application.onCreate()`:```kotlin theme={null}
import me.didit.sdk.DiditSdk

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        DiditSdk.initialize(this)
    }
}
```### Schritt 2: Verifizierung starten und Ergebnisse verarbeiten```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}")
            }
        }
    }
}
```***## IntegrationsmethodenDas SDK unterstützt zwei Integrationsmethoden:### Methode 1: UniLink (am einfachsten)Kein Backend erforderlich. Das SDK erstellt die Sitzung direkt anhand der Workflow-ID aus der Didit Console. Beschränkt auf `vendorData`.```kotlin theme={null}
DiditSdk.startVerification(
    workflowId = "your-workflow-id",
    vendorData = "user-123"
) { result ->
    handleResult(result)
}
```### Methode 2: Backend-Sitzung (empfohlen für die Produktion)Ihr Backend erstellt die Sitzung über die [API zum Erstellen einer Verifizierungssitzung](https://docs.didit.me/de/sessions-api/create-session.md) (`POST /v3/session/`) mit vollständiger Parameterunterstützung (`contact_details`, `expected_details`, `metadata`, `callback` usw.) und übergibt anschließend den `session_token` an das 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)
}
```Dieser Ansatz gibt Ihnen die volle Kontrolle über:- Die Zuordnung von Sitzungen zu Ihren Benutzern (`vendor_data`)
- Das Festlegen benutzerdefinierter Metadaten
- Die Konfiguration von Callbacks pro Sitzung
- Die Angabe von Kontaktdaten und erwarteten Daten für die Kreuzvalidierung***## KonfigurationPassen Sie das Verhalten des SDK an:```kotlin theme={null}
import me.didit.sdk.Configuration
import me.didit.sdk.core.localization.SupportedLanguage

val configuration = Configuration(
    languageLocale = SupportedLanguage.SPANISH,  // Force Spanish language
    showLanguageSelector = true,                  // Let the user change 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)
}
```### Konfigurationsoptionen| Eigenschaft | Typ | Standard | Beschreibung |
| - | - | - | - |
| `languageLocale` | `SupportedLanguage?` | Locale des Geräts | Eine bestimmte Sprache erzwingen |
| `showLanguageSelector` | `Boolean` | `false` | Den Sprachwähler im Web-Stil auf dem Begrüßungsbildschirm anzeigen |
| `fontFamily` | `String?` | Systemschriftart | Name einer benutzerdefinierten Schriftressource (aus `res/font/`) |
| `loggingEnabled` | `Boolean` | `false` | SDK-Debug-Logging aktivieren |
| `showCloseButton` | `Boolean` | `true` | Schließen-Schaltfläche (X) auf den Bildschirmen der Verifizierungsschritte anzeigen |
| `showExitConfirmation` | `Boolean` | `true` | Bestätigungsdialog anzeigen, wenn der Benutzer versucht, die Verifizierung zu verlassen |
| `closeOnComplete` | `Boolean` | `false` | Verifizierungs-UI nach Abschluss automatisch schließen (Entsprechung im Web SDK: `closeModalOnComplete`) |
| `defaultDocumentCamera` | `CameraLens` | `CameraLens.BACK` | Objektiv, das verwendet wird, wenn der Bildschirm zur Dokumentaufnahme geöffnet wird |
| `defaultLivenessCamera` | `CameraLens` | `CameraLens.FRONT` | Objektiv, das verwendet wird, wenn der Bildschirm zur Gesichtsaufnahme (Liveness-Erkennung) geöffnet wird |
| `showDocumentCameraSwitchButton` | `Boolean` | `true` | Kameraumschalter während der Aufnahme auf dem Bildschirm zur Dokumentaufnahme anzeigen |
| `showLivenessCameraSwitchButton` | `Boolean` | `true` | Kameraumschalter während der Aufnahme auf dem Bildschirm zur Gesichtsaufnahme anzeigen |### KameraoptionenDie Kameraoptionen entsprechen den [Kameraoptionen des Web SDK](https://docs.didit.me/de/integration/web-sdks/javascript-sdk.md#kameraoptionen).
Jedes Objektiv ist `CameraLens.FRONT` oder `CameraLens.BACK`.
Wenn das Gerät das angeforderte Objektiv nicht besitzt, verwendet das SDK die erste verfügbare Kamera.
Der Kameraumschalter wird auch auf Geräten mit nur einer Kamera ausgeblendet.
Setzen Sie eine Umschalter-Option auf `false`, um den Benutzer auf das Standardobjektiv dieses Schritts festzulegen.```kotlin theme={null}
val configuration = Configuration(
    defaultLivenessCamera = CameraLens.BACK,
    showLivenessCameraSwitchButton = false
)
```> [!NOTE]
>
> Die Optionen `showLanguageSelector`, `showCloseButton`, `showExitConfirmation` und `closeOnComplete` entsprechen dem `DiditSdkConfiguration` des Web SDK. Die mobilspezifischen Optionen `languageLocale` und `fontFamily` existieren, weil das mobile SDK die vollständige Verifizierungs-UI nativ rendert (anders als das Web SDK, das die gehostete Frontend-Anwendung innerhalb eines Iframes einbindet).> [!NOTE]
>
> **Theming und Farben**: Farben, Hintergründe und Einstellungen des Einstiegsbildschirms werden über Ihre [White-Label-Einstellungen](https://business.didit.me) in der Didit Console konfiguriert, nicht in der SDK-Konfiguration. So bleibt das Branding auf allen Plattformen einheitlich.***## SprachunterstützungDas SDK unterstützt **54 Sprachen**. Wenn keine Sprache angegeben wird, verwendet das SDK die Locale des Geräts und greift auf Englisch als Ausweichsprache zurück.```kotlin theme={null}
// Use device locale (default)
val config = Configuration()

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

// Let the user change language on the welcome screen
val config = Configuration(showLanguageSelector = true)
```**[Alle unterstützten Sprachen anzeigen →](https://docs.didit.me/de/integration/supported-languages.md)*****## Erweiterte OptionenFür erweiterte Sitzungsparameter (`contact_details`, `expected_details`, `metadata`, `callback`) verwenden Sie die Methode **Backend-Sitzung**. Ihr Backend ruft die [API zum Erstellen einer Verifizierungssitzung](https://docs.didit.me/de/sessions-api/create-session.md) mit allen Parametern auf und übergibt anschließend den `session_token` an das SDK.***## Ergebnisse verarbeitenDie Sealed-Klasse `VerificationResult` liefert das Ergebnis der Verifizierung:### Ergebnisfälle| Fall | Beschreibung |
| - | - |
| `Completed(session)` | Der Verifizierungsablauf wurde abgeschlossen (Ergebnis in `session.status` prüfen) |
| `Cancelled(session)` | Der Benutzer hat den Verifizierungsablauf abgebrochen |
| `Failed(error, session)` | Während der Verifizierung ist ein Fehler aufgetreten |### Eigenschaften von SessionData| Eigenschaft | Typ | Beschreibung |
| - | - | - |
| `sessionId` | `String` | Eindeutige Sitzungskennung |
| `status` | `VerificationStatus` | `APPROVED`, `PENDING` oder `DECLINED` |### FehlertypenAlle Fehler sind Sealed-Unterklassen von `me.didit.sdk.VerificationError`:| Fehler | Beschreibung |
| - | - |
| `SessionExpired` | Die Sitzung ist abgelaufen |
| `NetworkError` | Problem mit der Netzwerkverbindung |
| `CameraAccessDenied` | Kameraberechtigung nicht erteilt |
| `NotInitialized` | SDK nicht initialisiert: Rufen Sie zuerst `DiditSdk.initialize(context)` auf |
| `ApiError` | Das Backend hat eine Fehlerantwort zurückgegeben |
| `RetryBlocked` | Die Verifizierung kann nicht wiederholt werden (z. B. wenn die maximale Anzahl an Wiederholungsversuchen erreicht ist) |
| `Unknown(message)` | Anderer Fehler mit Meldung |### VerbindungsverlustVerliert das Gerät während der Verifizierung die Verbindung, legt das SDK über den Ablauf einen Bildschirm mit „Keine Internetverbindung“, statt einen Schritt weiterhin laden zu lassen.
Im Hintergrund wird die Verbindung weiter geprüft, und sobald Didit wieder erreichbar ist, schließt sich der Bildschirm automatisch. Der Benutzer setzt die Verifizierung bei dem Schritt fort, bei dem er war.
Der Bildschirm bietet **Try Again** und, wenn `showCloseButton` auf `true` gesetzt ist (Standardwert), **Exit Verification**.
Beim Beenden wird die Verifizierung mit `VerificationResult.Failed(error = VerificationError.NetworkError, session = ...)` beendet, sodass Ihre App erkennt, dass der Benutzer die Verifizierung wegen der Verbindungsunterbrechung verlassen hat.### Vollständiges Beispiel zur Ergebnisverarbeitung```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
        }
    }
}
```***## Status des SDK beobachtenDen Status des SDK können Sie für eigene Ladeanzeigen beobachten:```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 / R8Das SDK enthält eigene Consumer-ProGuard-Regeln. Es ist keine zusätzliche Konfiguration nötig.Wenn Sie den R8-Vollmodus verwenden, müssen Sie unter Umständen Folgendes in Ihre `gradle.properties` aufnehmen:```properties theme={null}
android.enableR8.fullMode=false
```***## End-to-End-Beispiel (Backend-Sitzung → Android SDK → Ergebnis)Dieses Muster ist die produktionsreife Integration. Ihr Backend erstellt die Sitzung, Ihre Android-App empfängt den `session_token`, und das SDK führt den Ablauf aus.### 1. Backend: Sitzung erstellen```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: Token austauschen und SDK starten```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: Endgültige Entscheidung per Webhook empfangenDas Ergebnis des SDK eignet sich gut für Rückmeldungen in der Oberfläche, das maßgebliche Ergebnis kommt jedoch per Webhook. Informationen zur HMAC-Prüfung finden Sie im [Webhooks-Leitfaden](https://docs.didit.me/de/integration/webhooks.md).```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);
});
```***## Vollständiges Beispiel```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}")
            }
        }
    }
}
```***


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.