SDK reference · Android SDK / Android Getting Started

Capture-Only Mode

Capture-Only mode runs the Incode capture experience on-device and returns the resulting photos and videos through callbacks, without sending data to Incode for processing. Use it when you want Incode's auto-capturing camera UX but do not want the SDK to upload or process the media. Every API call is fully decoupled and can be made in any order, any number of times. You are responsible for whatever you do with the captured media afterward.


How It Works

The capture APIs perform local checks, auto-capture the photo when conditions are met, and return the captured photo through a callback.

The diagram below shows the recommended data flow when using Capture-Only mode. The SDK captures locally and hands the media to the host app. The host app sends it to the customer server, which calls the Incode API and decides whether to repeat the capture.

Each module follows the same pattern, but the completion callback, the result type, and the fields it carries change. Read the below diagram once to understand the pattern, then view the diagram for module you are integrating: ID Scan, Selfie Scan, or Video Selfie. Each module-specific diagram includes the exact callback signature and every result field your app receives.

sequenceDiagram
    autonumber
    participant App as Host App
    participant SDK as Incode SDK
    participant Server as Customer Server

    App->>SDK: init in CAPTURE_ONLY mode
    Note over App,SDK: Keep a singleton reference so the SDK<br/>is not cleared from memory

    loop For each module in the flow (any order, any number of times)
        App->>SDK: startOnboardingSection(module)
        SDK->>SDK: local checks, auto capture
        SDK-->>App: module completion callback with result
        SDK-->>App: onOnboardingSectionCompleted
        Note over App,SDK: Only start the next section<br/>after onOnboardingSectionCompleted
        App->>Server: upload captured media
        Server->>Server: call Incode API, analyze response
        alt capture not acceptable
            Server-->>App: request re-capture
            App->>SDK: startOnboardingSection(module) again
        end
    end

    App->>SDK: deleteUserLocalData

ID Scan

The diagram below shows the recommended data flow when using Capture-Only mode for the ID Scan​ module.

sequenceDiagram
    autonumber
    participant App as Host App
    participant SDK as Incode SDK
    participant Server as Customer Server

    App->>SDK: startOnboardingSection(IdScan FRONT)
    SDK-->>App: onIdFrontCompleted(IdScanResult)
    Note right of App: idImagePath (file URI)<br/>idImageBase64 (base64)<br/>chosenIdType<br/>metadata
    SDK-->>App: onOnboardingSectionCompleted
    App->>Server: upload front ID photo
    Server-->>App: OK or repeat front scan

    App->>SDK: startOnboardingSection(IdScan BACK)
    SDK-->>App: onIdBackCompleted(IdScanResult)
    Note right of App: idImagePath (file URI)<br/>idImageBase64 (base64)<br/>chosenIdType<br/>metadata
    SDK-->>App: onOnboardingSectionCompleted
    App->>Server: upload back ID photo
    Server-->>App: OK or repeat back scan

Selfie Scan

The diagram below shows the recommended data flow when using Capture-Only mode for the Selfie Scan​ module.

sequenceDiagram
    autonumber
    participant App as Host App
    participant SDK as Incode SDK
    participant Server as Customer Server

    App->>SDK: startOnboardingSection(SelfieScan)
    SDK-->>App: onSelfieScanCompleted(SelfieScanResult)
    Note right of App: croppedSelfieImgPath (file URI)<br/>fullFrameSelfieImgPath (file URI)<br/>selfieBase64 (base64)<br/>fullFrameSelfieBase64 (base64)<br/>metadata
    SDK-->>App: onOnboardingSectionCompleted
    App->>Server: upload selfie
    Server-->>App: OK or repeat selfie scan

Video Selfie

The diagram below shows the recommended data flow when using Capture-Only mode for the Video Selfie module.

sequenceDiagram
    autonumber
    participant App as Host App
    participant SDK as Incode SDK
    participant Server as Customer Server

    App->>SDK: startOnboardingSection(VideoSelfie)
    SDK-->>App: onVideoRecorded(VideoSelfieResult)
    Note right of App: videoFilePath (file URI)<br/>audioFilePath (file URI)<br/>selfieImagePath (file URI)<br/>idFrontImagePath (file URI)<br/>idBackImagePath (file URI)<br/>documentImagePath (file URI)<br/>voiceConsentSelfiePath (file URI)
    SDK-->>App: onOnboardingSectionCompleted
    App->>Server: upload video selfie assets
    Server-->>App: OK or repeat video selfie

Supported Modules

Capture-Only mode supports the following modules:

Module Description
Intro Displays an introduction screen at the start of an onboarding flow.
Name Allows the user to enter their name and sends it to the server.
Phone Allows the user to enter their phone number and sends it to the server.
Email Allows the user to enter their email address and sends it to the server.
ID Scan Captures the front and back of a government-issued ID or passport and uploads the images to the Incode back end for processing. Select the document type via IdScan.Builder.setIdType.
NFC Scan Reads the secure NFC chip embedded in ICAO 9303-compliant travel documents (such as e-passports) and returns the document holder's data.
Document Scan Captures a document image, such as a proof of address or other supporting document, and sends it to the server.
Selfie Scan Captures the user's face with the device camera and runs liveness detection and face recognition.
Geolocation Requests location permission, reads the device's current location, and returns the coordinates along with an address breakdown.
Signature Allows the user to draw a signature by hand and uploads that signature image to the server.
Video Selfie Records a short video of the user during the session and runs liveness and face-match checks.

Set Up Capture-Only Mode

Complete the following steps in order.

Initialize the SDK for Capture-Only

Add the following to the class that extends Application and set the SDK mode to SdkMode.CAPTURE_ONLY. You can only make capture API calls after the SDK has been initialized with build().

override fun onCreate() {
    super.onCreate()
    ...
    IncodeWelcome.Builder(this)
        .setLoggingEnabled(loggingEnabled) // enable/disable logcat logs. logs are enabled by default
        .setSdkMode(SdkMode.CAPTURE_ONLY) // enable CAPTURE_ONLY mode
        .build()
    ...
}
@Override
public void onCreate() {
    super.onCreate();
    ...
    new IncodeWelcome.Builder(this)
        .setLoggingEnabled(loggingEnabled) // enable/disable logcat logs. logs are enabled by default
        .setSdkMode(SdkMode.CAPTURE_ONLY) // enable CAPTURE_ONLY mode
        .build();
    ...
}
  • build() creates the IncodeWelcome singleton. You can only make capture API calls after initialization.
  • setLoggingEnabled() is optional. Logs are enabled by default.

See API Reference for the complete specification of IncodeWelcome.Builder.

Perform Capture SDK Calls

Build the module you want to capture, wrap it in a FlowConfig, and start an onboarding section. Results arrive on the OnboardingListener callbacks. The examples below show an ID scan and a selfie scan.

// IdScan

IncodeWelcome.getInstance().setSdkMode(SdkMode.CAPTURE_ONLY)
try {
    val idScan: IdScan = IdScan.Builder()
        .setShowIdTutorials(true)
        .build()

    val flowConfig: FlowConfig = FlowConfig.Builder()
        .setFlowTag("ID scan section")
        .addID(idScan)
        .build()

    IncodeWelcome.getInstance()
        .startOnboardingSection(activityContext, flowConfig, object : OnboardingListener() {
            override fun onIdProcessed(idProcessResult: IdProcessResult) {
                // Use idProcessResult to read the result photos
            }

            override fun onError(error: Throwable) {}

            override fun onUserCancelled() {}

            override fun onOnboardingSectionCompleted(flowTag: String) {
                // ID scan section complete
            }
        }
    )
} catch (e: ModuleConfigurationException) {
    e.printStackTrace()
}

// SelfieScan
IncodeWelcome.getInstance().setSdkMode(SdkMode.CAPTURE_ONLY)
try {
    val selfieScan = SelfieScan.Builder()
        .setShowTutorials(true)
        .build()

    val flowConfig: FlowConfig = FlowConfig.Builder()
        .setFlowTag("Selfie scan section")
        .addSelfieScan(selfieScan)
        .build()

    IncodeWelcome.getInstance()
        .startOnboardingSection(activityContext, flowConfig, object : OnboardingListener() {
            override fun onSelfieScanCompleted(selfieScanResult: SelfieScanResult) {
                // Use selfieScanResult to read the result photo
            }

            override fun onError(error: Throwable) {}

            override fun onUserCancelled() {}

            override fun onOnboardingSectionCompleted(flowTag: String) {
                // Selfie scan section complete
            }
        }
    )
} catch (e: ModuleConfigurationException) {
    e.printStackTrace()
}
// IdScan

IncodeWelcome.getInstance().setSdkMode(com.incode.welcome_sdk.SdkMode.CAPTURE_ONLY);
try {
    IdScan idScan = new IdScan.Builder()
        .setShowIdTutorials(true)
        .build();

    FlowConfig flowConfig = new FlowConfig.Builder()
        .setFlowTag("ID scan section")
        .addID(idScan)
        .build();

    IncodeWelcome.getInstance()
        .startOnboardingSection(activityContext, flowConfig, new IncodeWelcome.OnboardingListener() {
            @Override
            public void onIdFrontCompleted(@NonNull IdScanResult frontIdScanResult) {}

            @Override
            public void onIdBackCompleted(@NonNull IdScanResult backIdScanResult) {}

            @Override
            public void onError(@NonNull Throwable error) {}

            @Override
            public void onUserCancelled() {}

            @Override
            public void onOnboardingSectionCompleted(@NonNull String flowTag) {
                // ID scan section complete
            }
        }
    );
} catch (ModuleConfigurationException e) {
    e.printStackTrace();
}

// SelfieScan

IncodeWelcome.getInstance().setSdkMode(com.incode.welcome_sdk.SdkMode.CAPTURE_ONLY);
try {
    SelfieScan selfieScan = new SelfieScan.Builder()
        .setShowTutorials(true)
        .build();

    FlowConfig flowConfig = new FlowConfig.Builder()
        .setFlowTag("Selfie scan section")
        .addSelfieScan(selfieScan)
        .build();

    IncodeWelcome.getInstance()
        .startOnboardingSection(activityContext, flowConfig, new IncodeWelcome.OnboardingListener() {
            @Override
            public void onSelfieScanCompleted(@NonNull SelfieScanResult selfieScanResult) {
                // Use selfieScanResult to read the result photo
            }

            @Override
            public void onError(@NonNull Throwable error) {}

            @Override
            public void onUserCancelled() {}

            @Override
            public void onOnboardingSectionCompleted(@NonNull String flowTag) {
                // Selfie scan section complete
            }
        }
    );
} catch (ModuleConfigurationException e) {
    e.printStackTrace();
}

Forward Metadata for Deepsight

If your organization uses Deepsight, forward the metadata field from IdScanResult and SelfieScanResult to the corresponding omni/add/* API request. Deepsight's downstream checks depend on this field. If you omit it, those checks run without the data they need.

Clean Up Local User Data

After the flow exits, call IncodeWelcome.deleteUserLocalData(context) to delete all local user data generated during the flow.

Danger

Always call deleteUserLocalData()

Call deleteUserLocalData() to remove the local user data the flow generated. Call it from your success, error, and cancellation callbacks.

Call deleteUserLocalData() in the following callbacks:

fun onSuccess()
fun onError()
fun onUserCancelled()
public void onSuccess()
public void onError()
public void onUserCancelled()

Supported API Configurations

The builders below show every configuration supported in Capture-Only mode. The ... placeholders stand for the values you supply.

FlowConfig

FlowConfig assembles the modules in order for the section you start.

val flowConfig = FlowConfig.Builder()
    .setFlowTag(...)
    .addIntro(...)
    .addName()
    .addPhone(...)
    .addEmail(...)
    .addID(...)
    .addNfcScan(...)
    .addDocumentScan(...)
    .addSelfieScan(...)
    .addGeolocation()
    .addSignature(...)
    .addVideoSelfie(...)
    .build()
FlowConfig flowConfig = new FlowConfig.Builder()
    .setFlowTag(...)
    .addIntro(...)   
    .addName()
    .addPhone(...)
    .addEmail(...)
    .addID(...)
    .addNfcScan(...)
    .addDocumentScan(...)
    .addSelfieScan(...)
    .addGeolocation()
    .addSignature(...)
    .addVideoSelfie(...)
    .build();

CommonConfig

CommonConfig holds settings shared across modules: thresholds, navigation, localization, and theming.

val commonConfig = CommonConfig.Builder()
    .setIdGlareThreshold(...)
    .setIdBlurThreshold(...)
    .setShowCloseButton(...)
    .setShowExitConfirmation(...)
    .setLocalizationLanguage(...)
    .setThemeConfiguration(...)
    .build()
CommonConfig commonConfig = new CommonConfig.Builder()
    .setIdGlareThreshold(...)
    .setIdBlurThreshold(...)
    .setShowCloseButton(...)
    .setShowExitConfirmation(...)
    .setLocalizationLanguage(...)
    .setThemeConfiguration(...)
    .build();

For the complete Builder options for each capture module, see Document Scan, ID Scan, Selfie Scan, and Video Selfie. The same options apply in Capture-Only mode.


Customizable Strings

Every user-facing string the SDK shows can be overridden, including in Capture-Only flows. For the complete list of string keys and override methods, see Customization.


For help, see API Reference or contact Incode support.

Was this page helpful?