KYC Docs Get credentials
Docs › Blink SDK › Android

Android

Drop-in identity verification for Android: Kotlin, coroutines and CameraX capture screens. Your backend creates the session; the SDK runs the document and liveness steps.

package com.blink.kyc:blink-kyc-android:1.4.0 minSdk 24 host ComponentActivity

Prepare the environment

Add the Blink Maven repository and the dependency:

settings.gradle.ktskotlin
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven("https://blink-pay.net/maven/releases")   // Blink SDK repository
    }
}
app/build.gradle.ktskotlin
android {
    defaultConfig { minSdk = 24 }
}

dependencies {
    implementation("com.blink.kyc:blink-kyc-android:1.4.0")
}

The SDK declares the camera permission and its capture screens; they are merged into your manifest and the drop-in screens request the runtime permission themselves.

Verification flow

Get a session token from your backend (Session API), then run the capture from a coroutine:

VerifyActivity.ktkotlin
import com.blink.kyc.BlinkError
import com.blink.kyc.BlinkKyc
import com.blink.kyc.BlinkStepError
import com.blink.kyc.DocumentType

lifecycleScope.launch {
    try {
        val outcome = BlinkKyc(baseUrl = "https://kyc-api.blink-pay.net", sessionToken = sessionToken)
            .document(DocumentType.PASSPORT)   // PASSPORT | NATIONAL_ID | ID_CARD | DRIVING_LICENCE
            .face()                            // liveness + face match
            .present(this@VerifyActivity)      // the SDK owns the camera UI
            .onProgress { p -> Log.d("kyc", p.step) }
            .run()

        // outcome.result: VERIFIED | REJECTED | REVIEW — a device copy.
        // Ask your backend for the authoritative result before acting.
    } catch (e: BlinkStepError) {
        Log.w("kyc", "${e.step}: ${e.code}")        // e.g. DOCUMENT_UNREADABLE
    } catch (e: BlinkError) {
        Log.e("kyc", "${e.code} (${e.httpStatus})") // switch on e.code
    }
}
CallEffect
BlinkKyc(baseUrl, sessionToken, timeoutMs, theme, strings)Create the client. Only the first two are required.
.document(type, side)Enable the document step. Both are optional.
.face()Enable liveness and face match.
.present(activity)Use the built-in capture screens.
.capture(hooks)Supply the media yourself (headless).
.onProgress { }Progress events.
.status()Suspend: read-only session progress from Blink.
.run()Suspend: run the journey, returns SessionResult(result, detail).

If you enable neither step, run() performs the full capture. The session's purpose decides which steps Blink accepts.

Headless capture

Bring your own camera: return the document image and the liveness frames, and the SDK handles challenges, uploads and the verdict.

HeadlessCapture.ktkotlin
BlinkKyc(baseUrl, sessionToken)
    .document(DocumentType.NATIONAL_ID)
    .face()
    .capture(object : CaptureHooks {
        override suspend fun document(): ByteArray = grabDocumentJpeg()
        override suspend fun liveness(actions: List<String>): List<ByteArray> = recordFrames(actions)
    })
    .run()

UI customisation

VerifyActivity.ktkotlin
BlinkKyc(
    baseUrl = "https://kyc-api.blink-pay.net",
    sessionToken = sessionToken,
    theme = BlinkTheme(
        accent = 0xFF15803D.toInt(),
        background = 0xFF0E1E4D.toInt(),
        text = 0xFFFFFFFF.toInt(),
        onAccent = 0xFFFFFFFF.toInt(),
    ),
)

More in Customisation.

Next

Handle the device outcome and errors (SDK result), then read the authoritative decision on your backend (Result API).