ID Capture Module
📘
This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation here. Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade.
Full rollout to all clients still TBD.
The ID Capture module captures front and back images of identity documents (ID cards, passports) with ML-powered quality checks and validation.
Follows the camera-capture pattern, plus dedicated states for mandatory consent and manual file upload. See the patterns page for the shared lifecycle; the rest of this page covers ID-specific config, capture properties, and methods.
Tag
<incode-id> is a standard Web Component. Importing the UI subpath registers the custom element; importing the CSS applies the module's styles.
import '@incodetech/web/id';
import '@incodetech/web/id/styles.css';
Properties
Set these as JavaScript properties on the element (not as HTML attributes):
| Property | Type | Required | Description |
|---|---|---|---|
config |
IdCaptureConfig |
❌ | Configuration for ID capture behavior |
manager |
IdCaptureManager |
❌ | Optional pre-built manager (advanced use) |
onFinish |
() => void |
❌ | Called when capture completes successfully |
onError |
`(error: string | undefined) => void` | ❌ |
WASM Requirements
The ID Capture module uses WebAssembly for document detection, blur/glare quality checks, and perspective correction. Pre-warm WASM during setup() so models are ready before the user reaches the camera step:
await setup({
apiURL: 'https://demo-api.incodesmile.com',
token: 'your-session-token',
wasm: { pipelines: ['idCapture'] },
});
See WASM Configuration for self-hosted paths and the lower-level warmupWasm() API.
Usage
Vanilla HTML / TypeScript
HTML
<incode-id></incode-id>
<script type="module">
import { setup } from '@incodetech/core';
import '@incodetech/web/id';
import '@incodetech/web/id/styles.css';
await setup({
apiURL: 'https://demo-api.incodesmile.com',
token: 'your-session-token',
wasm: { pipelines: ['idCapture'] },
});
const id = document.querySelector('incode-id');
id.config = {
showTutorial: true,
enableId: true,
enablePassport: false,
autoCaptureTimeout: 5,
captureAttempts: 3,
};
id.onFinish = () => console.log('ID captured!');
id.onError = (err) => console.error('ID error:', err);
</script>
React
import { useEffect, useRef } from 'react';
import { setup } from '@incodetech/core';
import type { IdCaptureConfig } from '@incodetech/core/id';
import '@incodetech/web/id';
import '@incodetech/web/id/styles.css';
type IdElement = HTMLElement & {
config: IdCaptureConfig;
onFinish: () => void;
onError: (error: string | undefined) => void;
};
await setup({
apiURL: 'https://demo-api.incodesmile.com',
token: 'your-session-token',
wasm: { pipelines: ['idCapture'] },
});
export function IdCapture() {
const ref = useRef<IdElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
el.config = {
showTutorial: true,
enableId: true,
enablePassport: false,
autoCaptureTimeout: 5,
captureAttempts: 3,
};
el.onFinish = () => console.log('ID captured!');
el.onError = (err) => console.error('ID error:', err);
}, []);
return <incode-id ref={ref} />;
}
Workflow vs Flow
In a dashboard-driven Flow (<incode-flow> / createOrchestratedFlowManager), ID is a single step that captures the document and runs server-side processing (/process/id). This is what <incode-id> and createIdCaptureManager do by default.
In a server-driven Workflow (<incode-workflow> / createWorkflowManager), the workflow engine emits ID handling as two distinct nodes:
ID_CAPTURE— runsidCaptureMachinefor the capture portion only, then advances without calling/process/id. Enabled by settingIdCaptureConfig.skipProcessId = true(the workflow engine sets this automatically on theID_CAPTUREnode's config).ID— runs the headlessid-verificationmodule (@incodetech/core/id-verification,createIdVerificationManager) which invokes/process/idon its own. The orchestrator renders the corresponding<incode-id-verification>shell while the request is in flight. No UI work needed.
This split lets the workflow inject custom logic (manual review, retries, branching) between capture and verification. For a single-step capture+verify flow, keep using the standard <incode-id> / createIdCaptureManager path — skipProcessId defaults to false, so processing runs inline as before.
API Methods
| Method | Description | When to Use |
|---|---|---|
load() |
Starts the ID capture flow | Always call first |
selectDocument(type) |
Selects 'id' or 'passport' |
When chooser |
capture() |
Manual capture trigger | When detectionStatus === 'manualCapture' |
close() |
Close the flow | Anytime |
getState() |
Returns current state | Anytime |
subscribe(callback) |
Subscribe to state changes | Returns unsubscribe function |
Detection Status Values
| Status | User Instruction |
|---|---|
idle |
"Preparing camera..." |
detecting |
"Hold steady..." |
offline |
"No network connection" |
Error Codes
| Code | Description | User Action |
|---|---|---|
UPLOAD_ERROR |
Upload failed | Retry capture |
CLASSIFICATION_FAILED |
Document not recognized | Use clearer image |
LOW_SHARPNESS |
Image too blurry | Hold device steadier |
NO_TOKEN |
Session token missing | Re-initialize SDK |
Examples
ID Card Only
const config: IdCaptureConfig = {
enableId: true,
enablePassport: false,
showTutorial: true,
autoCaptureTimeout: 5,
};
Passport Only
const config: IdCaptureConfig = {
enableId: false,
enablePassport: true,
showTutorial: false,
};
Capture-only flow
createIdCaptureOnlyManager exposes the same state machine and API surface as createIdCaptureManager, but bypasses the Incode upload pipeline. Instead of submitting the captured frames to Incode and waiting on server-side processing, the manager invokes a customer-supplied onCapture(response) callback with the captured images and reaches finished locally.