# Document Scan

The Document Scan module captures a supplementary document, such as a proof of address document, medical document, or bank statement. Users can upload a file or take a photo of the document with their device’s camera. For some document types, the server performs [OCR](https://developer.incode.com/docs/glossary#ocr) and returns the extracted data.

For an overview of this module and how it works, see [Document Capture](https://developer.incode.com/docs/document-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 Document Scan

Add the module with `addDocumentScan(documentScan)`. Document Scan ships both a v1 (legacy View) UI and a v2 (Jetpack Compose) UI; the active one depends on your Incode configuration. Contact your Incode representative to enable v2.

```kotlin
flowConfigBuilder.addDocumentScan(documentScan)
```
```java
flowConfigBuilder.addDocumentScan(documentScan);
```

### Example

The example below builds a `DocumentScan` configured for an `ADDRESS_STATEMENT` document type with tutorials enabled, adds it to a `FlowConfig`, and starts onboarding. The `OnboardingListener` receives the result in `onDocumentValidationCompleted`.

```kotlin
val documentScan = DocumentScan.Builder()
    .setDocumentType(DocumentType.ADDRESS_STATEMENT)
    .setShowTutorials(true)
    .build()

val flowConfig = FlowConfig.Builder()
    .addDocumentScan(documentScan)
    .build()

val onboardingListener = object : OnboardingListener() {
    override fun onDocumentValidationCompleted(
        documentType: DocumentType,
        documentValidationResult: DocumentValidationResult
    ) {
        // Document captured. Process the result.
    }
}

IncodeWelcome.getInstance()
    .startOnboarding(activityContext, sessionConfig, flowConfig, onboardingListener)
```
```java
DocumentScan documentScan = new DocumentScan.Builder()
    .setDocumentType(DocumentType.ADDRESS_STATEMENT)
    .setShowTutorials(true)
    .build();

FlowConfig flowConfig = new FlowConfig.Builder()
    .addDocumentScan(documentScan)
    .build();

IncodeWelcome.OnboardingListener onboardingListener = new IncodeWelcome.OnboardingListener() {
    @Override
    public void onDocumentValidationCompleted(
        @NonNull DocumentType documentType,
        @NonNull DocumentValidationResult documentValidationResult
    ) {
        // Document captured. Process the result.
    }
};

IncodeWelcome.getInstance()
    .startOnboarding(activityContext, sessionConfig, flowConfig, onboardingListener);
```

## Configuration Options

Configure the module with `DocumentScan.Builder`. The table below lists the most common options.

| Setting                                   | Description                                                                                                                              |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `setDocumentType(DocumentType)`           | Sets the type of document the module looks for: for example, `ADDRESS_STATEMENT`, `MEDICAL_DOC`, `PAYMENT_PROOF`, or `OTHER_DOCUMENT_1`. |
| `setShowTutorials(Boolean)`               | Shows tutorials on how to capture the document.                                                                                          |
| `setWaitForTutorials(Boolean)`            | Waits for the tutorial to finish before starting capture.                                                                                |
| `setShowDocumentProviderOptions(Boolean)` | Allows the user to choose between using the camera to scan the document and uploading its file.                                          |
| `setAllowSkipDocumentCapture(Boolean)`    | Lets the user skip document capture.                                                                                                     |

The data extracted by OCR depends on the configured `DocumentType`. For example, `getAddressStatementData()` and `addressFields` apply to `DocumentType.ADDRESS_STATEMENT`, and `getMedicalDocData()` applies to `DocumentType.MEDICAL_DOC`.

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

## Result

The module delivers a `DocumentValidationResult` to the `onDocumentValidationCompleted(DocumentType, DocumentValidationResult)` callback on the `OnboardingListener`. Key fields include:

- `documentPath`: A URI pointing to the captured document. Available only when the user chose to scan the document. When the SDK runs in `SdkMode.STANDARD`, this is always `null`.
- `addressFields`: Address fields read from an address statement; `null` if the address couldn't be read or the `DocumentType` is not `ADDRESS_STATEMENT`.
- `mimeType`: The document's MIME type: for example, `image/jpeg`, `image/png`, or `application/pdf`. Empty string when unknown.
- `isDocumentValidationSkipped`: `true` if the user skipped document capture; otherwise, `false`.
- 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.

For address statements, read `addressFields`. `getDocumentImage()` returns the captured document as a `Bitmap`.

If the module fails, the error surfaces through `OnboardingListener.onError(Throwable)`.

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