# ID Capture

The ID Capture module captures the front and back of a government-issued ID, with auto-capture and quality checks, and produces clean images for processing. It is the entry point for most identity-capture flows.

For an overview of this module and how it works, see [ID Capture](https://developer.incode.com/docs/id-capture).

How you use this module depends on your integration pattern. When the app defines the steps in code, you add the module to an `IncdOnboardingFlowConfiguration` as shown below; when the flow is defined in Dashboard, you reference it by session token and let the back end drive the steps. See [Integration Approaches](https://developer.incode.com/docs/ios-flow-configuration).

**Availability:** All variants.

## Add ID Capture

1. Add the module with `addIdScan()`.
   ```swift
   flowConfig.addIdScan(
       idType: nil,                              // .id or .passport; nil shows the chooser
       scanStep: .both,                          // .front / .back / .both
       idCategory: .primary,                     // .primary or .secondary
       showTutorials: true,
       showRetakeScreenForManualCapture: nil,
       showRetakeScreenForAutoCapture: nil,
       autocaptureUxMode: nil,                   // .countdown or .holdStill(duration:)
       showIDOverlay: nil,
       streamFrames: nil,
       initialOrientation: nil,
       enableAudioStream: nil,
       showIdTypeChooser: nil,
       digitalIdsUpload: false,
       motion: false                             // collect motion data + run local motion-behavior calc
   )
   ```
2. Add [ID OCR/Process](https://developer.incode.com/docs/module-id-info) after ID Capture. ID Capture captures the document images, and processing then runs validation and OCR on what was captured. When `scanStep == .both`, processing runs automatically afterward.

## Configuration Options

Configure the module with `addIdScan()`.

| Option                             | Type                 | Description                                                                                                                                              |
| ---------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `idType`                           | `IdType?`            | Sets the type of document: `.id` or `.passport`. `nil` lets the user select.                                                                             |
| `scanStep`                         | `ScanStep`           | Selects which sides are captured: `.front`, `.back`, or `.both`. Default: `.both`.                                                                       |
| `idCategory`                       | `IDCategory`         | `.primary` or `.secondary`.                                                                                                                              |
| `showTutorials`                    | `Bool?`              | Shows the tutorial screen that explains how to scan an ID.                                                                                               |
| `showIdTypeChooser`                | `Bool?`              | Shows or hides the document type selector.                                                                                                               |
| `showRetakeScreenForAutoCapture`   | `Bool?`              | Controls whether the review/retake screen appears after auto-capture.                                                                                    |
| `showRetakeScreenForManualCapture` | `Bool?`              | Controls whether the review/retake screen appears after manual capture.                                                                                  |
| `autocaptureUxMode`                | `AutocaptureUxMode?` | Specifies auto-capture behavior: `.countdown` or `.holdStill(duration:)`.                                                                                |
| `showIDOverlay`                    | `Bool?`              | Shows a visual overlay/frame guide on the camera preview to help the user align the ID within the capture area. Does not impact UI v2. Default: `false`. |
| `streamFrames`                     | `Bool?`              | Turns on frame streaming during capture. Only applies for the Video Conference (`-vc`) variant.                                                          |
| `initialOrientation`               | `IDOrientation?`     | Sets the orientation of the on-screen ID template: `.vertical` or `.horizontal`. Does not impact device rotation.                                        |
| `enableAudioStream`                | `Bool?`              | Enables audio capture alongside the video/image stream during scanning. Only applies if `streamFrames` is `true`.                                        |
| `digitalIdsUpload`                 | `Bool?`              | Allows uploading an existing digital ID (PDF).                                                                                                           |
| `motion`                           | `Bool`               | Enables motion data collection and local motion-behavior calculation for the capture. Default: `false`.                                                  |

ID Capture ships both a v1 (legacy) and a v2 (smart-capture) screen. The one that runs is not controlled by an `addIdScan` parameter; the SDK selects it automatically based on a remote UX experiment and, for the v2 US smart-capture back-scan path, the active flow's Workflow configuration in Dashboard. Neither condition is directly settable by the integrating app.

There is also a non-UI variant for headless capture: `addIdScanNonUI(scanStep:idCategory:streamFrames:enableAudioStream:)`.

The overload taking `showRetakeScreen`, `showAutoCaptureRetakeScreen`, and `enableRotationOnRetakeScreen` is deprecated. Use the renamed parameters shown above for `showRetakeScreen` (`showRetakeScreenForManualCapture`) and `showAutoCaptureRetakeScreen` (`showRetakeScreenForAutoCapture`). `enableRotationOnRetakeScreen` has no replacement; it was removed instead of renamed, and is retained in the deprecated overload only as an unused parameter.

## Result

ID Capture reports through the `IncdOnboardingDelegate` callbacks, with one pair per captured side plus the lifecycle and per-attempt variants:

```swift
func onIdFrontStarted(_ controller: any IDCaptureController)
func onIdFrontCompleted(_ result: IdScanResult)
func onIdFrontAttemptCompleted(_ result: IdScanResult)
func onIdBackStarted(_ controller: any IDCaptureController)
func onIdBackCompleted(_ result: IdScanResult)
func onIdBackAttemptCompleted(_ result: IdScanResult)
```

`onIdFrontCompleted(_:)` and `onIdBackCompleted(_:)` each deliver an `IdScanResult` for that side. Check `error` first: a non-`nil` value indicates a fatal, pre-upload failure (for example, the scan never reached the server) and takes precedence over the other fields. Otherwise, treat `scanStatus` as the authoritative validation outcome for the capture. `failReason` provides supplementary detail and is not derived from `scanStatus`. Both are independently reported from the same upload response.

`IdScanResult` fields:

- `image`: The captured ID or passport image.
- `base64Image`: The Base64-encoded string of the captured image.
- `encryptedBase64Image`: The encrypted Base64-encoded image, when encryption is enabled.
- `croppedFace`: The face photo cropped from the ID; `nil` when no face can be extracted.
- `chosenIdType`: The document type the user chose (`IdType`).
- `classifiedIdType`: The document type returned by the server.
- `idCategory`: Whether the document is a primary or secondary identification document (`IDCategory`: `.primary` or `.secondary`).
- `scanStatus`: The scan outcome; an `IncdIdScanStatus`: `unknown`, `ok`, `errorClassification`, `errorGlare`, `errorSharpness`, `errorReadability`, `errorInCapture`, `errorUnacceptableID`, or `wrongSide`.
- `failReason`: The reason the scan failed; `nil` when the scan succeeds.
- `issueName`: The legal name on the document.
- `issueYear`: The year the document was issued.
- `countryCode`: The country code of the document's issuing country.
- `allAttemptsExhausted`: `true` if all retry attempts are used up. This reflects the current side, front or back, independently.
- `metadata`: The proprietary capture metadata required by the SDK; populated only in [Capture-Only mode](https://developer.incode.com/docs/ios-capture-only-sdk).
- `idealCaptureEnvironmentTestResult`: The result of the ideal-capture-environment test.
- `deviceStats`: A `DeviceStats` snapshot of the device state when the result was produced. Its `motionStatus` (`MotionStatus`) reports device motion during capture. `MotionStatus` is a `CustomStringConvertible` enum (not a string-backed/`RawRepresentable` enum) with three cases; its `description`, and the value serialized to the wire, is the uppercase string shown in parentheses:
  - `.unclear` → `"UNCLEAR"`: Motion could not be determined; this is the fallback used when no motion result is available.
  - `.pass` → `"PASS"`: Device motion was within acceptable limits.
  - `.fail` → `"FAIL"`: Excessive device motion was detected.
- `error`: An `IncdIdScanError` when the capture failed; otherwise, `nil`.

Errors also surface through `IncdOnboardingDelegate.onError(_:)`. There is no ID-Capture-specific delegate error callback beyond the per-result `error` field.

## Errors

`IncdIdScanError` cases:

- `error`
- `cameraSetupFailed`
- `permissionsDenied`
- `fakePermissionsDenied`
- `skipped`
- `streamAudioPermissionsDenied`

<br />
