Trulioo KYC Documents Capture SDK — Android

The KYC Documents Capture SDK gives your organization full control over the document and selfie capture experience on Android. You own the UI, the branding, and the flow — Trulioo powers the underlying image capture and verification technology.

This means you can build capture experiences that are fully aligned with your brand guidelines, with custom overlays, animations, and messaging, while relying on Trulioo's built-in verification intelligence for accuracy and security.

Looking for a ready-made solution?

If you prefer a complete Trulioo-designed UI out of the box, see the KYC Documents Android SDK instead. It delivers the same trusted capture and verification technology with minimal setup.


Quick Start

  1. Add the com.trulioo:kyc-documents-capture dependency to your project.
  2. Get a shortcode from your backend for the active transaction.
  3. Call TruliooCapture.initializeCapture(shortCode) and wait for it to resolve.
  4. Create a document or selfie camera with TruliooCapture.createCaptureCamera(config).
  5. Render the camera into your Compose UI.
  6. Use startFeedback() for auto capture or captureLatestFrame() for manual capture.
  7. Call verifyImage() then acceptImage() on the capture result.
  8. Call TruliooCapture.submitCapture() when all required images have been accepted.
  9. Call TruliooCapture.clearSession() when the flow is complete.

What This SDK Covers

This guide is for integrations where your application owns the screen and embeds the SDK camera into your own Compose UI. The SDK handles:

  • Camera provider setup and teardown
  • Frame analysis for auto capture
  • Post-capture image verification
  • Accepted-image association with the active transaction

Your application handles:

  • Camera permission prompts and surrounding UI
  • Which capture step is currently active (document or selfie)
  • Whether to use auto capture or manual capture
  • Whether to accept or retake a verified image
  • When to submit or clear the session

Package and Compatibility

PropertyValue
Maven artifactcom.trulioo:kyc-documents-capture:<version>
Kotlin packagecom.trulioo.docv.sdk.capture
Minimum Android SDK24
UI contractJetpack Compose

The Android artifact is a single fused AAR. You do not need to add separate Capture contract modules.


Installation

dependencies {
    implementation("com.trulioo:kyc-documents-capture:<version>")
}

End-to-End Example

import com.trulioo.docv.sdk.capture.TruliooCapture
import com.trulioo.docv.sdk.capture.contract.DetectionType
import com.trulioo.docv.sdk.capture.contract.TruliooCameraConfig
import com.trulioo.docv.sdk.capture.contract.TruliooCameraProps

suspend fun startCaptureFlow(shortCode: String) {
    val transactionId = TruliooCapture.initializeCapture(shortCode).getOrThrow()
    println("Initialized transaction: $transactionId")

    val camera = TruliooCapture.createCaptureCamera(
        TruliooCameraConfig(detectionType = DetectionType.DOCUMENT),
    )

    // render() returns a Compose lambda — invoke it from your Compose UI tree
    val renderCamera = camera.render(
        TruliooCameraProps(backgroundColor = "#00000050"),
    )

    val captured = camera.startFeedback().getOrThrow()
    val verify = captured.verifyImage().getOrThrow()

    val accepted = verify.verifyResponses.any { value ->
        value == "SUCCESS" || value == "SUCCESS_REQUIRES_BACK"
    }

    if (accepted) {
        captured.acceptImage().getOrThrow()
    }

    TruliooCapture.submitCapture().getOrThrow()
    TruliooCapture.clearSession()
}

Initialization

Call TruliooCapture.initializeCapture(shortCode) before creating cameras or submitting the transaction. It resolves the active Capture session, authorizes the transaction, fetches configuration, and returns the transaction ID.

val transactionId = TruliooCapture.initializeCapture(shortCode).getOrThrow()
println("Active transaction: $transactionId")

Always initialize with a shortcode created for the active transaction. Do not reuse a stale shortcode across sessions. After calling clearSession(), a new initializeCapture() call is required before reusing the SDK.


Creating and Rendering a Camera

Use TruliooCapture.createCaptureCamera(config) to create a camera. Document capture is the default detection type.

import com.trulioo.docv.sdk.capture.contract.DetectionType
import com.trulioo.docv.sdk.capture.contract.TruliooCameraConfig

// Document camera (default)
val documentCamera = TruliooCapture.createCaptureCamera()

// Selfie camera
val selfieCamera = TruliooCapture.createCaptureCamera(
    TruliooCameraConfig(detectionType = DetectionType.BIOMETRIC_SELFIE),
)

render() returns a Compose lambda. Invoke it from your Compose UI tree — do not call it outside of a Compose context.

val renderCamera = camera.render(
    TruliooCameraProps(backgroundColor = "#00000050"),
)

// In your Compose UI:
// renderCamera()

Observe feedback and capture region during an active session:

camera.onFeedbackState().collect { state ->
    println("Feedback state: $state")
}

camera.onCaptureRegion().collect { region ->
    println("Capture region: $region")
}

Inspect the active stream resolution after startup:

val resolution = camera.getResolution().getOrThrow()
println("Resolution: ${resolution.width} x ${resolution.height}")

To tear down and resume the camera:

camera.remove()
camera.resume()

To clear in-camera capture state without clearing the root SDK session:

camera.resetCaptureSession()

Capturing an Image

Auto Capture (Recommended)

Call startFeedback() to let the SDK process frames until it captures an acceptable image:

val captured = camera.startFeedback().getOrThrow()
println("Captured image: ${captured.imageId}")
println("Detection type: ${captured.detectionType}")
println("Feedback: ${captured.imageFeedbacks}")

To stop an active auto-capture session:

camera.stopFeedback()

If stopFeedback() is called during an in-progress startFeedback(), the result will reflect a stopped-feedback state. Handle this as an expected case, not a fatal error.

To apply your own acceptance rule while still using SDK frame analysis:

val captured = camera.startFeedback { feedback ->
    feedback.imageFeedbacks.contains("SUCCESS")
}.getOrThrow()
println("Captured filtered image: ${captured.imageId}")

Manual Capture

Use captureLatestFrame() to trigger a manual capture instead of waiting for auto capture:

val captured = camera.captureLatestFrame().getOrThrow()
println("Manually captured image: ${captured.imageId}")

Verifying and Accepting an Image

After capturing, call verifyImage() to get post-capture feedback. Then call acceptImage() to mark the image as accepted for the transaction.

verifyImage() does not finalize the transaction — it gives your application the information to decide whether to keep or retake the image.

val verify = captured.verifyImage().getOrThrow()

if (!verify.isVerifyAttemptAvailable) {
    println("No further verify attempts available.")
}

println("Verify responses: ${verify.verifyResponses}")

val accepted = verify.verifyResponses.any { value ->
    value == "SUCCESS" || value == "SUCCESS_REQUIRES_BACK"
}

if (accepted) {
    captured.acceptImage().getOrThrow()
    println("Image accepted.")
}

Verify attempts are limited. Check isVerifyAttemptAvailable before calling verifyImage() again. Avoid repeated verify calls once this value is false.

Recommended acceptance rule: treat SUCCESS and SUCCESS_REQUIRES_BACK as accepted outcomes for image upload.


Submitting and Clearing the Session

Call TruliooCapture.submitCapture() after all required images have been accepted:

TruliooCapture.submitCapture().getOrThrow()

Then call TruliooCapture.clearSession() to clear local runtime state:

TruliooCapture.clearSession()

submitCapture() does not clear local runtime state by itself. Always call clearSession() when the flow is done or abandoned.


Result Reference

MethodReturnsKey fields
startFeedback()TruliooCaptureResponseimageId, detectionType, imageFeedbacks
startFeedback(filter)TruliooCaptureResponseimageId, detectionType, imageFeedbacks
captureLatestFrame()TruliooManualCaptureResponseimageId, detectionType
verifyImage()ITruliooVerifyFeedbackisVerifyAttemptAvailable, verifyResponses

Public API Reference

Session and submission:

TruliooCapture.initializeCapture(shortCode) · TruliooCapture.submitCapture() · TruliooCapture.clearSession()

Camera creation:

TruliooCapture.createCaptureCamera() · TruliooCapture.createCaptureCamera(config) · DetectionType · TruliooCameraConfig · TruliooCameraProps

Camera operations:

render(cameraProps) · startFeedback() · startFeedback(filter) · captureLatestFrame() · stopFeedback() · onFeedbackState() · onCaptureRegion() · getResolution() · resume() · remove() · resetCaptureSession()

Capture result operations:

verifyImage() · acceptImage()


Common Mistakes

Calling createCaptureCamera() before initializeCapture() completes. Initialization must succeed before creating or rendering a camera.

Not invoking the Compose lambda returned by render(). render() returns a composable lambda — you must call it from within your Compose UI tree. Storing the lambda without invoking it is a common setup mistake.

Calling submitCapture() before all required images are accepted. Verify and accept each required image before submitting.

Assuming submitCapture() also clears local state. Always call clearSession() after submitting or abandoning a flow.

Treating a stopped feedback session as a fatal error. Calling stopFeedback() during auto capture produces an expected stopped state — handle it intentionally, not as an unexpected failure.


Troubleshooting

Initialization fails: Confirm the shortcode is valid and belongs to the expected environment.

Camera UI does not appear: Confirm the render() lambda is being invoked from an active Compose tree and that camera permission has been granted.

Auto capture never completes: Confirm camera permission is granted and use onFeedbackState() to inspect whether the SDK is repeatedly requesting a retake condition. This usually indicates a lighting or framing issue.

Verify or accept fails: Confirm the image came from the current active session and was not invalidated by a prior resetCaptureSession() or clearSession() call.


Diagnostic Checklist

When filing a support issue, include:

  • Capture SDK version.
  • Device model and Android version.
  • Host Compose version, if relevant.
  • Whether the flow was document or selfie capture.
  • Whether the issue occurred during auto capture or manual capture.
  • The shortcode environment used.
  • The transaction ID, if available.
  • The latest feedback state or verify responses.
  • Which stage the failure occurred at: initialize, render, capture, verify, accept, or submit.