---
title: "ID OCR Module"
url: "https://developer.incode.com/sdk-reference/web-sdk-2-module-id-ocr/"
section: "sdk-reference"
group: "Incode Web SDK 2 Reference / Web SDK 2 Individual Modules"
version: "v1.1"
status: "live"
---
# ID OCR Module

:::note
This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation [here](/sdk-reference/web-sdk-reference).  Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade. <br /><br />Full rollout to all clients still TBD.
:::

The ID OCR module extracts structured data (name, address, document number, dates, etc.) from a captured ID image. Typically runs after [ID Capture](/sdk-reference/web-sdk-2-module-id-capture/).

> Follows the [form-based pattern](/sdk-reference/web-sdk-2-module-patterns/#1-form-based-modules), with an additional `readonly` state when `editableOcr` is `false` (display extracted data without letting the user edit). See the patterns page for the shared lifecycle.

## Availability

This module is headless-only — there is no public `<incode-id-ocr>` web component. Drive it with `createIdOcrManager` from `@incodetech/core/id-ocr` and render your own UI (form fields, validation messages, etc.).

## Configuration

```typescript
type IdOcrConfig = {
  editableOcr?: boolean; // Allow user to edit OCR data (default: false)
  cpfOnly?: boolean; // Show and validate only the CPF document number field
  secondId?: boolean; // After first ID OCR step, load second captured ID's OCR (orchestrated flow only)
  flowId?: string; // Session flow ID; when listed in CPFFlowIds, only the CPF field is shown
};
```

| Option        | Type      | Required | Description                                                                                 |
| ------------- | --------- | -------- | ------------------------------------------------------------------------------------------- |
| `editableOcr` | `boolean` | ❌       | When `true`, the user can edit extracted fields before submitting. Default `false`.         |
| `cpfOnly`     | `boolean` | ❌       | When `true`, only the CPF document number field is shown and CPF validation is applied.     |
| `secondId`    | `boolean` | ❌       | Used in orchestrated flows when a second ID was captured. Loads OCR for that document next. |
| `flowId`      | `string`  | ❌       | Set by the orchestrator. CPF flows render only the CPF field; otherwise full OCR fields.    |

When `<incode-flow>` receives `useCPF: true`, it keeps the dashboard's `ID_OCR` step and configuration, then adds `cpfOnly: true`. The module continues to use the standard ID OCR lifecycle: `editableOcr` is respected, edited values are sent to the editable OCR endpoint, and values are not automatically formatted or submitted.

## State machine

`IdOcrState` is a discriminated union over `status`:

| Status       | Description                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------ |
| `idle`       | Initial state.                                                                                   |
| `loading`    | Fetching OCR data from the backend.                                                              |
| `readonly`   | Display extracted data; no edits allowed (`editableOcr === false`). User can confirm to advance. |
| `inputting`  | Editable form rendered. User can edit fields and validate.                                       |
| `submitting` | Sending the (possibly edited) data back to the backend.                                          |
| `success`    | Server accepted the submission.                                                                  |
| `finished`   | Terminal — the module is done.                                                                   |
| `error`      | Fatal error.                                                                                     |

## Field descriptors

The manager exposes the fields it wants rendered as `OcrFieldConfig[]`, so a headless host can build the form without hard-coding a field list:

```typescript
type OcrFieldConfig = {
  key: keyof UpdateOcrDataParams;
  labelKey: string;
  type: 'text' | 'date' | 'radio';
  options?: { label: string; value: string }[];
  validation?: ValidationRule[];
  required: boolean;
};
```

| Property     | Type                                  | Description                                                                              |
| ------------ | ------------------------------------- | ---------------------------------------------------------------------------------------- |
| `key`        | `keyof UpdateOcrDataParams`           | The OCR field this descriptor drives. Pass it to `setField()` and `validateField()`.     |
| `labelKey`   | `string`                              | Translation key for the field's label. Resolve it through your i18n setup rather than displaying it directly. |
| `type`       | `'text' \| 'date' \| 'radio'`         | Which control to render.                                                                 |
| `options`    | `{ label: string; value: string }[]?` | Choices for a `radio` field.                                                             |
| `validation` | `ValidationRule[]?`                   | Rules `validateField()` applies to this field.                                           |
| `required`   | `boolean`                             | Whether the field must have a value before submitting.                                   |

`OcrFieldConfig`, `UpdateOcrDataParams`, and `ValidationRule` are exported from `@incodetech/core/id-ocr`.

## API methods

| Method                   | Purpose                                                                         |
| ------------------------ | ------------------------------------------------------------------------------- |
| `load()`                 | Fetch the OCR data and transition to `readonly` or `inputting`.                 |
| `setField(field, value)` | Update a field while in `inputting`. `field` is a key of `UpdateOcrDataParams`. |
| `validateField(field)`   | Run validation (required, minimum age, CPF format) on a single field.           |
| `continue()`             | Confirm and submit. Transitions to `submitting`.                                |
| `retry()`                | After `error`, restart the OCR fetch.                                           |

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

## Headless example

```typescript
import { createIdOcrManager } from '@incodetech/core/id-ocr';

const manager = createIdOcrManager({
  config: { editableOcr: true },
});

manager.subscribe((state) => {
  switch (state.status) {
    case 'readonly':
      // Render state.formData read-only with a "Confirm" button → manager.continue()
      break;
    case 'inputting':
      // Render editable form. On change: manager.setField('firstName', value)
      // On submit: manager.continue()
      // state.validationErrors lists per-field error keys
      break;
    case 'finished':
      manager.stop();
      break;
  }
});

manager.load();
```

## See also

- [Module: ID Capture](/sdk-reference/web-sdk-2-module-id-capture/): typically runs before this module
- [Module Patterns → form-based](/sdk-reference/web-sdk-2-module-patterns/#1-form-based-modules)
- [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/)