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. |
| 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 theIncodeWelcomesingleton. 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.