Onfido logo home page
Watch a demo
Get in touch
Arrow back Back to guides

Onfido Studio: Android SDK integration

Start here

This is an introductory guide to integrating Onfido Studio - our drag and drop interface for building, managing, and deploying identity verification journeys - with Onfido’s Android SDK. For more general information regarding Onfido Studio, please see our product guide.

Getting started

All of the interactive tasks of an end-user’s verification journey designed and built using Onfido Studio are managed by our SDKs.

The Onfido Android SDK communicates directly and dynamically with active Studio workflows to display the relevant screens to ensure the correct capture and upload of user information, such as identity documents, selfie photos and videos. As a result, the SDK flow will vary depending on the workflow configuration. You won't need to specify any steps directly in the SDK integration as these will be overridden when the workflow run ID is passed into the SDK initialization.

The Android SDK supports API level 21 and above. Our configuration is currently set to the following:

  • minSdkVersion = 21
  • targetSdkVersion = 31
  • android.useAndroidX=true
  • Kotlin = 1.3+
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8

Create a workflow run

As a first step, you will need to create a Workflow Run by making a call to the Onfido API. At a minimum, you will need to provide a workflow_id from a valid, active workflow, as well as an Applicant ID. More details on creating a workflow run can be found in our API reference.

The server will return a workflow run object, with a workflow run ID contained in the response:

HTTP/1.1 201 Created
Content-Type: application/json

  "id": "<WORKFLOW_RUN_ID>",
  "applicant_id": "<APPLICANT_ID>",
  "workflow_id": "<WORKFLOW_ID>",
  "workflow_version_id": 11,
  "status": "approved",
  "output": {"prop1": "val_1", "prop2": 10},
  "reasons": ["reason_1", "reason_2"],
  "error": null,
  "created_at": "2022-06-28T15:39:42Z",
  "updated_at": "2022-07-28T15:40:42Z",
  "link": {
      "completed_redirect_url": "https://example.onfido.com",
      "expired_redirect_url": "https://example.onfido.com",
      "expires_at": "2022-10-17T14:40:50Z",
      "language": "en_US",
      "url": "https://eu.onfido.app/l/<WORKFLOW_RUN_ID>"

Generate an SDK token

SDK tokens are required to authenticate the SDKs for Studio workflows, generated by making a call to the Onfido API.

$ curl https://api.eu.onfido.com/v3.6/sdk_token \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -F 'applicant_id=<APPLICANT_ID>' \

SDK tokens expire after 90 minutes. You can use the optional tokenExpirationHandler parameter in the SDK token configurator function to generate and pass a new SDK token when it expires. This ensures the SDK continues its flow even after an SDK token has expired. You should inject a new token in 10 seconds after the callback is triggered, otherwise the flow will finish with a TokenExpiredException error.


class ExpirationHandler : TokenExpirationHandler {

    override fun refreshToken(injectNewToken: (String?) -> Unit) {
        TODO("<Your network request logic to retrieve SDK token goes here>")
        injectNewToken("<NEW_SDK_TOKEN>") // if you pass `null` the sdk will exit with token expired error

val config = OnfidoConfig.builder(context)
    .withSDKToken("<YOUR_SDK_TOKEN_HERE>", tokenExpirationHandler = ExpirationHandler()) // ExpirationHandler is optional


class ExpirationHandler implements TokenExpirationHandler {

    public void refreshToken(@NotNull Function1<? super String, Unit> injectNewToken) {
        //Your network request logic to retrieve SDK token goes here
        injectNewToken.invoke("<NEW_SDK_TOKEN>"); // if you pass `null` the sdk will exit with token expired error

OnfidoConfig.Builder config = new OnfidoConfig.Builder(context)
                .withSDKToken("<YOUR_SDK_TOKEN>", new ExpirationHandler()); // ExpirationHandler is optional

More detailed documentation about SDK tokens can be found in our API reference.

Add the SDK dependency

Onfido-capture-sdk is the recommended integration option.

repositories {

dependencies {
    implementation 'com.onfido.sdk:onfido-workflow:x.y.z'

Multi-APK split

C++ code needs to be compiled for each of the CPU architectures (known as "ABIs") present on the Android environment. Currently, the SDK supports the following ABIs:

  • armeabi-v7a: Version 7 or higher of the ARM processor. Most recent Android phones use this
  • arm64-v8a: 64-bit ARM processors. Found on new generation devices
  • x86: Most tablets and emulators
  • x86_64: Used by 64-bit tablets

The SDK binary contains a copy of the native .so file for each of these four platforms. You can considerably reduce the size of your .apk by applying APK split by ABI, editing your build.gradle to the following:

android {
  splits {
    abi {
        enable true
        include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a'
        universalApk false

Read the Android documentation for more information.

Initialize the SDK for Studio

Now you can initialize the SDK, using your generated SDK token and workflow run ID.

Build a configuration object

const val REQUEST_CODE = 0x05

private lateinit var onfidoWorkflow: OnfidoWorkflow

fun onCreate(savedInstanceState: Bundle?) {
    val workflowConfig = WorkflowConfig.Builder(
        workflowRunId = "<WORKFLOW_RUN_ID>",
        sdkToken = "<SDK_TOKEN>"

Start the flow

onfidoWorkflow = OnfidoWorkflow.create(this)
startActivityForResult(onfidoWorkflow.createIntent(workflowConfig), REQUEST_CODE)

Handling callbacks

To receive the result from a completed workflow, you should override the method onActivityResult on your Activity/Fragment. The following code is provided as an example:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    onfidoWorkflow.handleActivityResult(resultCode, data, object : OnfidoWorkflow.ResultListener {
        override fun onUserCompleted() {
            // Called when the entire workflow run has reached the terminal node.

        override fun onUserExited(exitCode: ExitCode) {
            // Called when the user has exited the flow prematurely.

        override fun onException(exception: OnfidoWorkflow.WorkflowException) {
            // Called when the flow has ended with an exception

onUserCompleted Callback that fires when all interactive tasks in the workflow have been completed. If you have configured webhooks, a notification will be sent to your backend confirming the workflow run has finished. You do not need to create a check using your backend as this is handled directly by the workflow
onUserExited Callback that fires when the workflow was exited prematurely by the user. The reason can be an exitCode, e.g USER_CONSENT_DENIED
onException In case of an unexpected error, the onException method will be invoked with a relevant error message in the WorkflowException object. Error messages are not in a presentable format to the end user and are not localised

Error handling

The exception object returned as part of onException(exception) is of type WorkflowException.

It's a sealed class with multiple cases, depending on the exception type.

override fun onException(exception: OnfidoWorkflow.WorkflowException) {
    when (exception) {
        is WorkflowInsufficientVersionException ->
            // This happens when you are using an older version of the Android SDK and trying
            // to access a new functionality from workflow. You can fix this by updating the SDK
        is WorkflowInvalidSSLCertificateException ->
            // When network requests fail because SSL certificate is invalid
        is WorkflowTokenExpiredException ->
            // When SDK token is expired and needs to be refreshed
        is WorkflowUnknownCameraException ->
            // When some unknown camera exception happens.
        is WorkflowUnknownResultException ->
            // When an corrupted intent result is passed to the SDK
        is WorkflowUnsupportedTaskException ->
            // This happens when you are using an older version of the Android SDK.
            // You can fix this by updating the SDK
        is WorkflowHttpException ->
            // This happens when the SDK receives an error from an API call
            // see https://documentation.onfido.com/#errors for more information
        is WorkflowUnknownException ->
            // This happens when an unexpected error occurs.
            // Please contact android-sdk@onfido.com when this happens
        else ->
            // Necessary because of Kotlin

Customizing the SDK

The Android SDK has multiple customizable features that provide flexibility, while also being easy to integrate. For more detailed documentation, read our SDK customization guide.

UI Customization

The Android SDK supports the customization of colors and fonts used in the SDK flow. For information regarding the available options, please see our SDK customization guide.

Language localization

The SDK supports and maintains multiple languages. Please refer to the Android SDK language localization documentation for more details.

Note: For localisation, you need to use withLocale(locale: Locale) method of the WorkflowConfig.Builder to set the preferred locale.


Our solutions

Onfido uses 256-bit SSL encryption 100% of the time on every device.


Onfido has been certified by BSI to ISO 27001 under certificate number IS 660122.

© Onfido™, 2022. All rights reserved.
Company Registration Number: 07479524.