# Document Capture Module Guide

This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation [here](https://developer.incode.com/docs/web-sdk-reference). 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 Document Capture module captures generic documents (utility bills, lease agreements, tax documents, address proofs, vehicle logbooks, etc.) — anything that isn't an identity document but needs to be uploaded as part of verification. Supports both camera-based capture and file-picker upload, with optional multi-page support.

Follows the [camera-capture pattern](https://developer.incode.com/docs/web-sdk-2-module-patterns#2-camera-capture-modules), but extends it with file-upload alternatives and multi-page state. See the patterns page for the shared lifecycle.

## Tag

`<incode-document-capture>` is a standard Web Component. Importing the UI subpath registers the custom element; importing the CSS applies the module's styles.

```ts
import '@incodetech/web/document-capture';
import '@incodetech/web/document-capture/styles.css';
```

## Properties

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `DocumentCaptureConfig` | ❌ | Configuration options |
| `onFinish` | `() => void` | ❌ | Called when capture completes |
| `onError` | `(error: string | undefined) => void` | ❌ | Called when an error occurs |

## Configuration

```typescript
type DocumentCaptureConfig = {
  processingType?: DocumentType; // Backend routing key (default 'addressStatement')
  captureMode?: 'file' | 'camera'; // 'camera' = capture only (hides upload); 'file' = upload only (hides camera); absent = capture + upload
  allowSkipDocumentCapture?: boolean; // Default false
  disableSkipPoa?: boolean; // Backend ADDRESS field; inverse of allowSkipDocumentCapture
  title?: string; // Tutorial screen title override
  text?: string; // Tutorial screen text override
  step2Title?: string; // Multi-page tutorial second-page title
  step2Text?: string; // Multi-page tutorial second-page text
  captureAttempts?: number; // Default 3
  sendBase64?: boolean; // Default false (sends raw bytes)
  maxFileSize?: number; // Default 10 MB
};
```

`processingType` accepts: `addressStatement`, `otherDocument1`, `otherDocument2`, `otherDocument3`, `v5cMultiPageLogbook`, `circulationCard`, `financeSettlement`, `carInvoice`, plus `process*` variants for OCR-driven processing. The multi-page types (`v5cMultiPageLogbook`, `circulationCard`, `financeSettlement`) trigger the `nextPage` flow described below.

## State machine

`DocumentCaptureState` is a discriminated union over `status`. The 11 states extend the camera-capture pattern with file-upload and multi-page handling:

| Status | Description |
| --- | --- |
| `tutorial` | Initial guidance screen. |
| `initializingCamera` | Camera starting up (when camera capture is offered and the user picks camera). |
| `capturing` | Live camera preview, ready to capture. |
| `preview` | After capture or file pick, user reviews the image before accept/retake. |
| `uploading` | Uploading the (accepted) image to the backend. |
| `success` | Upload accepted; transitioning out. |
| `nextPage` | Multi-page document; backend asked for an additional page. User can capture or skip. |
| `finalizing` | Server-side finalization after all pages uploaded. |
| `failure` | Upload or finalization failed; user can retry. |
| `finished` | Terminal — module complete. |
| `closed` | User dismissed. |

## API methods

| Method | Purpose |
| --- | --- |
| `capture()` | Trigger camera capture (when `capturing`). |
| `setFile(file, imageBase64)` | Provide a file from the picker (when `capturing` or `nextPage`). |
| `accept()` | Accept the previewed image and start uploading. |
| `retake()` | Reject the preview and return to capturing. |
| `retry()` | Retry from `failure` state. |
| `continue()` | Continue from `nextPage` after all pages captured. |
| `skip()` | Skip this step (only when `allowSkipDocumentCapture` is `true`). |
| `close()` | Dismiss the module (transitions to `closed`). |
| `captureNextPageFromCamera()` | In `nextPage` state, switch back to camera for the next page. |
| `captureNextPageFromFile()` | In `nextPage` state, open file picker for the next page. |
| `finishPageCapture()` | Mark all pages captured; transitions to `finalizing`. |

Plus the universal lifecycle: `subscribe`, `getState`, `reset`, `stop`.

## WASM requirement

Camera-mode capture uses WASM for image quality checks. Preload via `setup({ wasm: { pipelines: ['idCapture'] } })` if you'll be running this module in camera mode. Upload-only mode (`captureMode: 'file'`) does not require WASM.
