Skip to main content

Android SDK

The Kora IDV Android SDK provides a complete verification UI — document capture, selfie, and liveness detection — built with Jetpack Compose.

Requirements

  • Android API 24+ (Android 7.0)
  • Kotlin 2.0.0+
  • Jetpack Compose BOM 2024.02.00+

Installation

Gradle (Kotlin DSL)

Add the JitPack repository and dependency:

// settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven { url = uri("https://jitpack.io") }
}
}

// build.gradle.kts (app module)
dependencies {
implementation("com.github.badedokun:koraidv-koraidv-android:v1.5.0")
}

Gradle Version Catalog

# libs.versions.toml
[versions]
koraidv = "v1.5.0"

[libraries]
koraidv = { module = "com.github.badedokun:koraidv-koraidv-android", version.ref = "koraidv" }
// build.gradle.kts
dependencies {
implementation(libs.koraidv)
}

Quick start

1. Configure the SDK

import com.koraidv.sdk.KoraIDV
import com.koraidv.sdk.Configuration
import com.koraidv.sdk.Environment

// In your Application class or Activity
KoraIDV.configure(
Configuration(
apiKey = "kora_sandbox_xxxxx",
tenantId = "your-tenant-uuid",
environment = Environment.SANDBOX
)
)

2. Register for verification results

import com.koraidv.sdk.VerificationContract
import com.koraidv.sdk.VerificationRequest
import com.koraidv.sdk.VerificationResult

class VerifyActivity : ComponentActivity() {

private val verificationLauncher = registerForActivityResult(
VerificationContract()
) { result: VerificationResult ->
when (result) {
is VerificationResult.Success -> {
val status = result.verification.status
val riskScore = result.verification.riskScore // Int? 0–100
val imagePersisted = result.verification.imagePersisted
// Handle success
}
is VerificationResult.Failure -> {
val error = result.error
// Handle error
}
is VerificationResult.Cancelled -> {
// User cancelled
}
}
}
}

3. Launch verification

The SDK creates the verification on your behalf — pass an externalId (your own user identifier) and a tier:

import com.koraidv.sdk.VerificationRequest
import com.koraidv.sdk.VerificationTier

verificationLauncher.launch(
VerificationRequest(
externalId = "user-${userId}",
tier = VerificationTier.STANDARD
)
)

VerificationTier accepts: BASIC, STANDARD, ENHANCED. (See tier table for what each includes.)

Verification tiers

TierIncludes
BASICDocument OCR + basic authenticity
STANDARD+ Face match + active liveness
ENHANCED+ Anti-spoof + risk signals + compliance screening (sanctions / PEP / adverse media)

Resume an existing verification

If the user closed the app mid-flow and you have the verificationId from the success or webhook payload, resume rather than start fresh:

private val resumeLauncher = registerForActivityResult(
KoraIDV.ResumeVerificationContract()
) { result ->
// Handle result the same way as a fresh start
}

resumeLauncher.launch(existingVerificationId)

Configuration options

ParameterTypeDefaultDescription
apiKeyStringRequiredYour API key (kora_sandbox_… for sandbox, kora_live_… for production)
tenantIdStringRequiredYour tenant UUID
environmentEnvironmentSANDBOXSANDBOX or PRODUCTION (auto-detected from API key prefix; explicit setting overrides)
baseUrlString?nullOverride base URL (for on-premise deployments)
themeKoraTheme?DefaultsCustom theme colors and styling
timeoutLong120000Network request timeout in milliseconds
debugLoggingBooleanfalseVerbose logs in debug builds

Theme customization

import com.koraidv.sdk.KoraTheme
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

KoraIDV.configure(
KoraIDVConfig(
apiKey = "test_your_api_key",
tenantId = "your-tenant-uuid",
theme = KoraTheme(
primaryColor = Color(0xFF2563EB),
backgroundColor = Color.White,
textColor = Color(0xFF1F2937),
errorColor = Color(0xFFDC2626),
cornerRadius = 12.dp,
buttonHeight = 48.dp
)
)
)

Error handling

The SDK provides typed errors with recovery suggestions:

is VerificationResult.Failure -> {
when (result.error) {
is KoraException.NetworkError -> {
// Check internet connection
showRetryDialog(result.error.recoverySuggestion)
}
is KoraException.CameraAccessDenied -> {
// Request camera permission
requestCameraPermission()
}
is KoraException.SessionExpired -> {
// Create a new verification on your server
createNewVerification()
}
is KoraException.UserCancelled -> {
// User backed out
}
}
}
ErrorDescriptionRecovery
NetworkErrorNetwork request failedCheck connection, retry
CameraAccessDeniedCamera permission deniedRequest permission again
SessionExpiredVerification session timed outCreate a new verification
UserCancelledUser dismissed the verificationPrompt to try again

Permissions

Add to your AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera" android:required="true" />

The SDK requests camera permission at runtime if not already granted.

ProGuard rules

The SDK ships a consumer-rules.pro that's applied automatically — you don't need to add anything to your own proguard-rules.pro for the SDK itself. (It already covers the SDK's models, API interfaces, public types, and the optional OpenCV imports.)

OpenCV (optional dependency for document dewarping)

The SDK includes a DocumentDewarper that detects the document quadrilateral in a captured photo and warps it to a frame-filling crop. This is an optional enhancement — OpenCV is NOT bundled in the SDK because it adds ~50 MB per ABI and most consumers don't need it.

Behaviour without OpenCV:

  • The SDK builds cleanly (the bundled consumer-rules.pro silences R8 warnings on org.opencv.*).
  • At runtime, DocumentDewarper.dewarp() calls OpenCVLoader.initLocal() inside a try/catch. If OpenCV isn't on the classpath, the call returns null and the SDK falls back to the original capture. No crash.

If you want dewarping enabled, add OpenCV to your app's build.gradle.kts:

dependencies {
implementation("org.opencv:opencv:4.10.0")
}

That's it — the SDK detects OpenCV's presence at runtime and starts dewarping automatically.

Flutter bridge

If your Android host is part of a Flutter app:

// In your FlutterActivity
class MainActivity : FlutterActivity() {
private val CHANNEL = "com.yourapp/koraidv"

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
.setMethodCallHandler { call, result ->
when (call.method) {
"startVerification" -> {
val verificationId = call.argument<String>("verificationId")!!
verificationLauncher.launch(
VerificationRequest(verificationId = verificationId)
)
result.success(null)
}
else -> result.notImplemented()
}
}
}
}