# Approval

The Approval module finalizes an onboarding flow by deciding whether to approve the user, then registers approved users in the Incode database. By default, it runs with no UI and approves silently, but you can toggle the UI, silent face match, and forced approval.

In Dashboard, Approval isn't a module. It's a flow setting you enable when building the flow. The SDK receives no callback when Approval executes at flow end. If you need that notification, [integration Pattern 3](https://developer.incode.com/docs/android-common-implementation-patterns#pattern-3-run-flows-configured-in-dashboard) won't work. Use [Pattern 1](https://developer.incode.com/docs/android-common-implementation-patterns#pattern-1-configure-flows-locally-and-run-end-to-end) or [2](https://developer.incode.com/docs/android-common-implementation-patterns#pattern-2-configure-flows-locally-and-run-step-by-step) instead, adding the module to a `FlowConfig` in code as shown on this page.

Approval is not available in [Capture-Only mode](https://developer.incode.com/docs/android-capture-only-sdk); adding it there throws `ModuleNotAvailableException`.

## Add Approval

1. Add Approval after the capture and verification modules it depends on, such as [Selfie Scan](https://developer.incode.com/docs/android-selfie-scan), [ID Scan](https://developer.incode.com/docs/android-id-scan) (or [QR Scan](https://developer.incode.com/docs/android-qr-scan)), and [Face Match](https://developer.incode.com/docs/android-face-match). Because the decision reflects the user's overall score across those steps, Approval should be one of the last modules in the flow.
2. Add the module with one of the `addApproval` overloads:

   ```kotlin
   // Default configuration: no UI, no silent face match, scores enforced
   flowConfigBuilder.addApproval()

   // Toggle UI and silent face match
   flowConfigBuilder.addApproval(showUi, silentFaceMatch)

   // Also control whether approval is forced regardless of score
   flowConfigBuilder.addApproval(showUi, silentFaceMatch, forceApproval)
   ```
   ```java
   // Default configuration: no UI, no silent face match, scores enforced
   flowConfigBuilder.addApproval();

   // Toggle UI and silent face match
   flowConfigBuilder.addApproval(showUi, silentFaceMatch);

   // Also control whether approval is forced regardless of score
   flowConfigBuilder.addApproval(showUi, silentFaceMatch, forceApproval);
   ```

### Example

The example below adds the capture and verification steps Approval depends on, then adds Approval in its default configuration and listens for the result through `onApproveCompleted()`.

```kotlin
val flowConfig = FlowConfig.Builder()
    .addID()
    .addSelfieScan()
    .addFaceMatch()
    .addApproval()
    .build()

val onboardingListener = object : IncodeWelcome.OnboardingListener() {
    override fun onApproveCompleted(approveResult: ApproveResult) {
        // User approval completed
    }

    override fun onError(error: Throwable) {
        // Onboarding flow was aborted due to error
    }
}

IncodeWelcome.getInstance().startOnboarding(
    activityContext,
    sessionConfig,
    flowConfig,
    onboardingListener
)
```
```java
FlowConfig flowConfig = new FlowConfig.Builder()
    .addID()
    .addSelfieScan()
    .addFaceMatch()
    .addApproval()
    .build();

IncodeWelcome.OnboardingListener onboardingListener = new IncodeWelcome.OnboardingListener() {
    @Override
    public void onApproveCompleted(@NonNull ApproveResult approveResult) {
        // User approval completed
    }

    @Override
    public void onError(@NonNull Throwable error) {
        // Onboarding flow was aborted due to error
    }
};

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

## Configuration Options

Approval has no `Builder`. Configure it through the parameters of the `addApproval` overloads.

| Setting           | Description                                                                                                                          |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `showUi`          | Shows the Approval module UI. Defaults to `false`, so approval runs silently.                                                        |
| `silentFaceMatch` | Performs face processing inside the Approval module. Do not use this together with the Face Match module, or an exception is thrown. |
| `forceApproval`   | If `true`, the user is approved with any score. If `false`, only users with an overall score above the threshold are approved.       |

The approval decision and the score thresholds this module enforces also depend on your Flow or Workflow configuration, not just these parameters.

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

## Result

Approval delivers an `ApproveResult` to the `onApproveCompleted(approveResult)` callback on `OnboardingListener`. Key fields include:

- `isSuccess`: `true` if the approval was successful; otherwise, `false`.
- `uuid`: The Session UUID associated with this approval; `null` when unavailable.
- `token`: The Session token associated with this approval; `null` when unavailable.
- 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.

If the approval step fails, the error surfaces through `OnboardingListener.onError(Throwable)` and the onboarding flow is aborted. Approval does not define its own exception subtype.

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