# ID Scan

The ID Scan 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](https://developer.incode.com/docs/android-common-implementation-patterns#integration-patterns). In Patterns 1 and 2, you add the module to a `FlowConfig` in code as shown on this page. In Pattern 3, you define your modules and configuration in Dashboard as a Flow or Workflow and reference it by ID with `startFlow()` or `startWorkflow()` as shown on [Run Flows Configured in Dashboard](https://developer.incode.com/docs/android-run-flows-configured-online).

## Add ID Scan

1. If you plan to enable frame streaming with `setStreamFramesEnabled`, ensure you've [declared](https://developer.incode.com/docs/android-installation#declare-dependencies) the `com.incode.sdk:video-streaming` dependency in your `[module]/build.gradle`. If you plan to do front/back orientation checks, ensure you've declared `com.incode.sdk:model-id-face-detection`.
2. Add the module with one of the `addID` overloads:

   ```kotlin
   // Default configuration
   flowConfigBuilder.addID()

   // Custom configuration built with IdScan.Builder
   flowConfigBuilder.addID(idScan)
   ```
   ```java
   // Default configuration
   flowConfigBuilder.addID();

   // Custom configuration built with IdScan.Builder
   flowConfigBuilder.addID(idScan);
   ```
3. Add [Process ID](https://developer.incode.com/docs/android-process-id) after ID Scan. ID Scan captures the document images, and Process ID then runs validation on what was captured.

ID Scan ships both a v1 (legacy View) and a v2 (Jetpack Compose) capture screen; the active one depends on your Incode configuration. Contact your Incode representative to enable v2.

### Example

The example below builds an `IdScan` module with tutorials shown, adds it to the flow followed by Process ID, and listens for the front and back capture results separately.

```kotlin
val idScan = IdScan.Builder()
    .setShowIdTutorials(true)
    .build()

val flowConfig = FlowConfig.Builder()
    .addID(idScan)
    .addProcessId(ProcessId.Builder().build())
    .build()

IncodeWelcome.getInstance().startOnboarding(
    activityContext,
    sessionConfig,
    flowConfig,
    object : OnboardingListener() {
        override fun onIdFrontCompleted(frontIdScanResult: IdScanResult) {
            // Front of the document captured
        }

        override fun onIdBackCompleted(backIdScanResult: IdScanResult) {
            // Back of the document captured
        }

        override fun onError(error: Throwable) {}

        override fun onUserCancelled() {}
    }
)
```
```java
IdScan idScan = new IdScan.Builder()
    .setShowIdTutorials(true)
    .build();

FlowConfig flowConfig = new FlowConfig.Builder()
    .addID(idScan)
    .addProcessId(new ProcessId.Builder().build())
    .build();

IncodeWelcome.getInstance().startOnboarding(
    activityContext,
    sessionConfig,
    flowConfig,
    new IncodeWelcome.OnboardingListener() {
        @Override
        public void onIdFrontCompleted(@NonNull IdScanResult frontIdScanResult) {
            // Front of the document captured
        }

        @Override
        public void onIdBackCompleted(@NonNull IdScanResult backIdScanResult) {
            // Back of the document captured
        }

        @Override
        public void onError(@NonNull Throwable error) {}

        @Override
        public void onUserCancelled() {}
    }
);
```

## Configuration Options

Configure the module with `IdScan.Builder`. The table below lists the most commonly used options.

| Setting                                      | Description                                                                                                                                         |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setShowIdTutorials(Boolean)`                | Shows or hides the tutorial screen that explains how to scan an ID.                                                                                 |
| `setShowIdTypeChooser(Boolean)`              | Shows or hides the document type selector. When hidden, the type from `setIdType` is used.                                                          |
| `setIdType(IdScan.IdType)`                   | Sets the document type when the selector is not shown (`ID`, `PASSPORT`, `DIGITAL_ID`, `GOOGLE_WALLET_ID`).                                         |
| `setScanStep(IdScan.ScanStep)`               | Selects which sides are captured (`FRONT`, `BACK`, or `BOTH`).                                                                                      |
| `setShowRetakeScreenForAutoCapture(Boolean)` | Controls whether the review/retake screen appears after auto capture.                                                                               |
| `setCaptureAttempts(Integer)`                | Sets the number of allowed capture attempts.                                                                                                        |
| `setStreamFramesEnabled(Boolean)`            | Turns on frame streaming and requires the optional `video-streaming` dependency described above. It is ignored on devices with 2 GB of RAM or less. |

When both `setShowIdTypeChooser(true)` and `setIdType(...)` are provided, the chooser takes precedence and the explicitly set type is ignored.

&#x20;For the complete option set, see `IdScan.Builder` in [API Reference](https://developer.incode.com/docs/android-api-reference).

## Result

ID Scan delivers an `IdScanResult` through two separate `OnboardingListener` callbacks, one per captured side: `onIdFrontCompleted(IdScanResult)` and `onIdBackCompleted(IdScanResult)`. Key fields include:

- `idImagePath`: The URI pointing to the captured front and back ID or passport image.
- `idImageBase64`: The Base64-encoded string of the captured front and back ID or passport bitmap.
- `croppedFacePath`: The URI to the face photo cropped from the ID; `null` when no face can be extracted.
- `croppedDocumentPath`: The URI to the cropped document photo; `null` when it can't be extracted. This result is available for SDK versions 5.42.0 and newer.
- `base64Barcode`: The Base64-encoded content of the scanned PDF417 barcode; `null` if no barcode was read. This result is available for SDK versions 5.43.0 and newer.
- `chosenIdType`: The document type the user chose: `ID` or `Passport`.
- `classifiedIdType`: The document type returned by the server.
- `idCategory`: Whether this is the first or second ID captured.
- `actualIdType`: The derived (read-only) resolved type; uses `classifiedIdType` when present, otherwise falls back to `chosenIdType`.
- `issueName`: The legal name on the document.
- `issueYear`: The year the document was issued.
- `countryCode`: The country code of the document's issuing country.
- `scanStatus`: The integer status code for the scan:
  - `0`: OK
  - `-2`: user cancelled
  - `-1`: unknown error
  - Specific failure codes for fake, glare, sharpness, shadow, unreadable, and emulator
  - `10`: back returns `RESULT_SKIPPED` when only the front is scanned.
- `failReason`: The reason the scan failed; `null` when the scan succeeds.
- `isOnlyFront`: `true` if only the front of the ID was scanned.
- `isOnlyBack`: `true` if only the back of the ID was scanned.
- `skipBackIdCapture`: `true` if back-ID scanning should be skipped.
- `allAttemptsExhausted`: `true` if all retry attempts are used up. This reflects the current side, front or back, independently.
- `faceExtractionSkipped`: `true` when the back end intentionally skipped extracting the face image and biometric template from the front ID; `croppedFacePath` is then expected to be `null` and ID-selfie face match is unavailable.
- `metadata`: The proprietary capture metadata required by the SDK. Populated only when `SdkMode` is `CAPTURE_ONLY`. This result is available for SDK versions 5.39.0 and newer.
- `idealCaptureEnvironmentTestResult`: The result of the ideal-capture-environment test. This result was deprecated in SDK version 5.39.0; use `metadata` instead.
- Fields inherited from `BaseResult`:
  - `resultCode`: The `ResultCode` for this result.
  - `error`: When `resultCode` is `ERROR`, the `Throwable` that caused it; otherwise, `null`.
  - `deviceStats`: The `DeviceStats` snapshot of the device state when the result was produced.
  - `motionStatus`: Device motion assessment during capture. One of the following:
    - `UNCLEAR`: Motion could not be determined; the default.
    - `PASS`: Device motion was within acceptable limits.
    - `FAIL`: Excessive device motion was detected.

Errors surface through `OnboardingListener.onError(Throwable)`. There is no ID Scan-specific exception subtype.

For all fields, see `IdScanResult` in [API Reference](https://developer.incode.com/docs/android-api-reference).
