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:

  1. ID_CAPTURE — runs idCaptureMachine for the capture portion only, then advances without calling /process/id. Enabled by setting IdCaptureConfig.skipProcessId = true (the workflow engine sets this automatically on the ID_CAPTURE node's config).
  2. ID — runs the headless id-verification module (@incodetech/core/id-verification, createIdVerificationManager) which invokes /process/id on 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.