The Trulioo Android SDK lets you add identity verification to your Android application. A standard integration collects device intelligence, optionally submits KYC subject data, and returns a terminal result you can act on.
Quick Start
- Add the Trulioo dependency to your project.
- Set up the SDK host context so it has access to your
Application. - Get a shortcode from your backend for the active transaction.
- Call
Trulioo.initialize(...). - Call
Trulioo.sendDeviceInformation(...). - Branch on
acceptedorfailedand log the returned identifiers anddebugTrace.
What This SDK Covers
The base Trulioo Android SDK provides three verification flows:
- Device Intelligence — via
sendDeviceInformation(...),collectDeviceIntelligence(...), andgetDeviceInformation(...) - KYC Data verification — via
verifyData(...) - eID verification — via
prepareEid(...),verifyEid(...), andregisterEidAuthTab(...)
Package and Compatibility
| Property | Value |
|---|---|
| Maven artifact | com.trulioo:trulioo:<version> |
| Kotlin namespace | com.trulioo.sdk.android |
| Minimum Android SDK | 24 |
Some Trulioo Android releases require an additional runtime dependency. Always follow the dependency instructions published with the specific release you are integrating.
Installation
Add the dependency to your build.gradle.kts:
dependencies {
implementation("com.trulioo:trulioo:<version>")
// Add any additional runtime dependency listed in the release instructions for this version.
}Host Context Setup
The Android SDK requires access to your Application instance for device intelligence. By default, it captures this automatically via AndroidX Startup:
val hostContext = DeviceSdkHostContext.fromRuntime()If your build disables manifest merging or AndroidX Startup, pass an explicit host context instead:
val hostContext = DeviceSdkHostContext(
application = application,
activity = activity,
)Note: The device-intelligence runtime is initialized using Application, not a short-lived UI context. Using an Activity context without a valid Application is one of the most common setup mistakes on Android.
Initialization
Call Trulioo.initialize(...) before any other SDK operation. Initialization resolves the session, authorizes it against Trulioo APIs, and fetches the configuration for your transaction.
Trulioo.initialize(
shortcode = shortcode,
hostContext = DeviceSdkHostContext.fromRuntime(),
options = TruliooInitializationOptions(
allowLocalDevelopment = false,
sdkVersion = BuildConfig.VERSION_NAME,
),
onComplete = { result ->
// Persist result for later use
},
onError = { error ->
// Initialization failed — no product operations can proceed
},
)Initialization options (TruliooInitializationOptions):
| Option | Description |
|---|---|
allowLocalDevelopment | Enables local or emulator shortcode testing. Blocked by default. |
sdkVersion | Your integration's version string. Helps map backend logs and support cases. |
appVersion | Optional override for app version metadata. |
appDomain | Optional override for app package or domain metadata. |
deviceIntelligencePolling | Override default polling settings for debug collection. |
Device Intelligence
Use Device Intelligence to collect device-risk telemetry from the current app session.
Standard Integration (Recommended)
For most integrations, use sendDeviceInformation(...). This submits the device event and returns a terminal result.
val result = Trulioo.sendDeviceInformation(
initialization = initialized,
hostContext = DeviceSdkHostContext.fromRuntime(),
options = DeviceInformationSendOptions(
reference = DeviceSubjectReference(
firstName = "Jane",
lastName = "Doe",
dateOfBirth = "1990-01-01",
),
),
)
when (result) {
is SendDeviceInformationResult.Accepted ->
Log.d("Trulioo", "device accepted ${result.transactionId} ${result.eventId}")
is SendDeviceInformationResult.Failed ->
Log.e("Trulioo", "device failed ${result.error.code} ${result.error.stage} ${result.debugTrace}")
}Debug Integration
Use collectDeviceIntelligence(...) only when you need the resolved device event and normalized seed for diagnostics.
val debugResult = Trulioo.collectDeviceIntelligence(
initialization = initialized,
hostContext = DeviceSdkHostContext.fromRuntime(),
options = DeviceIntelligenceCollectionOptions(
polling = DeviceIntelligencePollingOptions(),
reference = DeviceSubjectReference(firstName = "Jane", lastName = "Doe"),
),
)
Log.d("Trulioo", "deviceEvent=${debugResult.deviceEvent}")
Log.d("Trulioo", "deviceSeed=${debugResult.deviceSeed}")Callback-Only (Normalized Seed)
If you only need the normalized device result in a callback:
Trulioo.getDeviceInformation(
initialization = initialized,
onComplete = { device ->
// device is DeviceSeedResponse?
},
onError = { error ->
// Collection failed
},
)Key behaviors to know:
sendDeviceInformation(...)is the standard production path.collectDeviceIntelligence(...)is a blocking debug path — do not use it in production unless you specifically need the terminal event.referenceis caller-supplied subject data only. The SDK generates device basic information internally — do not attempt to pass those fields yourself.- A failed reference submission is recorded in
debugTracebut does not fail the device event. DeviceSdkHostContextmust resolve to a validApplicationbefore device collection can start.
Note: DeviceInformationSendOptions and DeviceIntelligenceCollectionOptions also accept a userId field. Use this only when your downstream device-intelligence runtime expects a runtime-specific user identifier. It is not a replacement for the Trulioo transaction ID.
Default polling settings:
| Setting | Default |
|---|---|
maxAttempts | 32 |
intervalMs | 1250ms |
To override:
DeviceIntelligenceCollectionOptions(
polling = DeviceIntelligencePollingOptions(
maxAttempts = 10,
intervalMs = 1000,
),
)KYC Data Verification
Use verifyData(...) when your flow has subject data and needs a terminal KYC verification result from the same initialized session.
lifecycleScope.launch {
val stateJob = launch {
Trulioo.observeDataState().collect { state ->
Log.d("Trulioo", "dataState=$state")
}
}
val result = Trulioo.verifyData(
DataVerificationConfig(
countryCode = "CA",
personInfo = PersonInfo(
firstName = "Jane",
lastName = "Doe",
dateOfBirth = "1990-01-01",
),
location = Location(
buildingNumber = "123",
streetName = "Example",
streetType = "Ave",
city = "Exampleville",
stateProvinceCode = "BC",
postalCode = "V0V0V0",
),
communication = Communication(
emailAddress = "[email protected]",
mobileNumber = "+12025550123",
),
),
)
stateJob.cancel()
if (result.outcome == DataOutcome.ACCEPT && result.recordMatch) {
Log.d("Trulioo", "data verified ${result.transactionId}")
} else {
Log.d("Trulioo", "review path $result")
}
}Key behaviors to know:
verifyData(...)reuses the internally stored initialized session — you do not passinitializedto it directly.- The SDK submits PII but does not return PII in
DataVerificationResult. Trulioo.observeDataState()exposes the current module state as aStateFlow.Trulioo.resetData()cancels or clears the current data flow if you need to restart it.
eID Verification
Use the eID entrypoints when your flow needs an interactive, provider-backed identity verification from the same initialized session.
Android eID requires a one-time Auth Tab registration in your ComponentActivity before initialization:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Trulioo.registerEidAuthTab(this)
}
}Then run the eID flow:
lifecycleScope.launch {
val stateJob = launch {
Trulioo.observeEidState().collect { state ->
Log.d("Trulioo", "eidState=$state")
}
}
val config = EidVerificationConfig(
transactionId = initialized.configuration.transactionId,
countryCode = "SE",
)
// Pre-warm when the eID screen becomes visible
Trulioo.prepareEid(config)
// Launch the interactive provider flow
val result = Trulioo.verifyEid(
activity = this@MainActivity,
config = config,
)
stateJob.cancel()
if (result.outcome == EidOutcome.SUCCESS && result.match) {
Log.d("Trulioo", "eID verified ${result.transactionId}")
} else {
Log.d("Trulioo", "eID not verified $result")
}
}Key behaviors to know:
registerEidAuthTab(this)must be called inonCreateof yourComponentActivity— this is required before any eID flow.prepareEid(...)pre-warms the eID screen. Call it when the eID screen becomes visible.verifyEid(...)launches the provider flow and waits for a terminal result.transactionIdmust come frominitialized.configuration.transactionId.providerIdentifieris optional — only pass it when your flow needs to pin a specific provider.callbackSchemeis optional and only needed when your app uses a custom callback scheme.Trulioo.resetEid()clears interrupted eID state before a restart.
Advanced: Authorized Session Client
After initialization, you can access approved Trulioo routes directly using Trulioo.sessionClient(...). Use this for typed authorized requests or binary uploads.
val sessionClient = Trulioo.sessionClient(
initialization = initialized,
allowedAuthorizedPaths = setOf(
"/vendor/device/session",
"/vendor/device/upload",
),
)Available operations:
| Method | Description |
|---|---|
authorizedPost(endpoint, request) | Typed authorized POST |
authorizedGet(endpoint) | Typed authorized GET |
authorizedUpload(endpoint, body, headers, onProgressBytes, timeoutMillis) | Binary upload |
Typed POST example:
@Serializable
data class StatusRequest(val transactionId: String)
@Serializable
data class StatusResponse(val status: String)
val status = sessionClient.authorizedPost(
endpoint = AuthorizedPostEndpoint<StatusRequest, StatusResponse>(
path = "/vendor/device/session",
),
request = StatusRequest(transactionId = "txn-123"),
)Upload example:
@Serializable
data class UploadResponse(val transactionId: String)
val response = sessionClient.authorizedUpload<UploadResponse>(
endpoint = AuthorizedUploadEndpoint(path = "/vendor/device/upload"),
body = imageBytes,
headers = mapOf("Content-Type" to "image/jpeg"),
)Rules:
- Initialize first and reuse the returned session result.
- Register any routes beyond the base SDK defaults explicitly via
allowedAuthorizedPaths. - Use approved relative paths only, beginning with
/. - Prefer the typed endpoint helpers over raw manual HTTP.
- This is an advanced contract. For standard device intelligence, use
sendDeviceInformation(...).
Subject Reference Data
Pass caller-owned subject data using DeviceSubjectReference:
DeviceSubjectReference(
firstName = "Jane",
lastName = "Doe",
dateOfBirth = "1990-01-01",
phoneNumber = "+15551234567",
other = listOf(
DeviceSubjectOtherField(
customKey = "middleName",
value = "Ann",
),
),
)Do not pass device basic-information fields from your application. The SDK generates those internally.
Results
TruliooInitializationResult contains:
| Field | Use |
|---|---|
configuration | Confirm backend enablement flags for the session |
deviceEvent | Source of truth for terminal device status and failure reason |
deviceSeed | Normalized device result for UI and app logic |
debugTrace | Diagnostic timeline for support |
baseUrl | Resolved environment base URL |
accessToken | Session access token (managed by the SDK) |
Error Handling
| Failure type | Behavior |
|---|---|
| Initialization failure | Delivered through the onError callback |
| Send failure | Returns SendDeviceInformationResult.Failed with a stable code, stage, message, and debugTrace |
| Collection failure | Throws DeviceIntelligenceCollectionException — includes a partial initializationResult with debug trace data gathered before failure |
| Reference submission failure | Recorded in debugTrace under device_reference_submit; does not throw |
Environments and Shortcodes
Environment is resolved from the shortcode — you do not set it manually.
| Shortcode pattern | Environment |
|---|---|
| default | Production |
.dv suffix | Development |
.pr suffix | Preview |
.local suffix or local | Local |
.emulator suffix or emulator | Emulator |
local@host:port | Local override |
emulator@host:port | Emulator override |
Supported region prefixes: us, eu, ap / apac, ca
Local and emulator shortcodes are blocked unless allowLocalDevelopment = true is set in initialization options.
Common Mistakes
Using an Activity context without a valid Application. The device-intelligence runtime initializes against Application, not a short-lived UI context. Use DeviceSdkHostContext.fromRuntime() or pass an explicit Application instance.
Assuming initialization also runs device collection. Initialization and collection are separate steps. You must explicitly call sendDeviceInformation(...) after initialization completes.
Passing device basic-information from your app. The SDK generates these fields internally. Supplying them yourself will cause a failure before seed submission.
Treating reference failure as a terminal collection failure. A failed subject reference submission is recorded in debugTrace but does not fail the device event. Check both separately.
Missing the runtime dependency. Some releases require an additional runtime dependency beyond the base artifact. Always check the release notes for your version.
Skipping registerEidAuthTab. Android eID requires this to be called in onCreate of your ComponentActivity. Skipping it will cause the eID flow to fail.
Troubleshooting
Device intelligence is not running:
- Confirm
configuration.deviceIntelligence?.enabled == true. - Confirm the backend returned a non-empty
credentialId. - Confirm the release-specific runtime dependency is on the classpath.
- Confirm
DeviceSdkHostContextcontains a realApplication. - Confirm
sendDeviceInformation(...)was explicitly called after initialization. - Inspect
debugTrace.
Terminal event failed:
- Inspect
deviceEvent.failureReason. - Inspect terminal processor status if present.
- Check whether
device_reference_submitfailed indebugTracewhile the main event still completed — reference failure is not the same as full collection failure.
Diagnostic Checklist
When filing a support issue, include:
- The shortcode environment (production, development, preview, local, or emulator).
- App version, Android version, device manufacturer, and device model.
- Whether
DeviceSdkHostContext.fromRuntime()or an explicit host context was used. - Whether the required runtime dependency was present for your release.
- The terminal
deviceEvent.status,failureReason, and processor details. transactionId,eventId, and relevantdebugTraceentries.- Whether subject reference data was provided and whether
device_reference_submitappears indebugTrace. - Whether a
userIdwas supplied to send or debug collection.
Public API Reference
Main entry points:
Trulioo.initialize(...) · Trulioo.sendDeviceInformation(...) · Trulioo.collectDeviceIntelligence(...) · Trulioo.getDeviceInformation(...) · Trulioo.verifyData(...) · Trulioo.prepareEid(...) · Trulioo.verifyEid(...) · Trulioo.registerEidAuthTab(...) · Trulioo.sessionClient(...)
Key types:
TruliooInitializationOptions · TruliooInitializationResult · DeviceInformationSendOptions · SendDeviceInformationResult · DeviceIntelligenceCollectionOptions · DeviceIntelligencePollingOptions · DeviceSubjectReference · DeviceSubjectOtherField · DeviceSdkHostContext · DeviceIntelligenceCollectionException · DebugTraceEntry · TruliooSessionClient · AuthorizedPostEndpoint · AuthorizedGetEndpoint · AuthorizedUploadEndpoint

