# Approval

The Approval module finalizes an onboarding flow by deciding whether to approve the user, then registers approved users in the Incode database. The approval decision reflects the user's overall score across the capture and verification steps that ran before it. Approval has no UI; it runs silently at the end of the flow and reports its outcome through a delegate callback.

In Dashboard, Approval isn't a module. It's a flow setting you enable when building the flow. You can also add it to a flow configuration in code, as shown below. Either way, the SDK maps it internally to `IncdOnboardingFlowConfiguration.addApproval()` and reports the outcome the same way: iOS fires `onApproveCompleted(_:)` when the step completes, regardless of whether the flow came from Dashboard or from code. See [Integration Approaches](https://developer.incode.com/docs/ios-flow-configuration).

**Availability:** All variants.

## Add Approval

1. Add Approval after the capture and verification modules it depends on, such as [Selfie](https://developer.incode.com/docs/module-selfie), [ID Capture](https://developer.incode.com/docs/module-id-scan), and [Face Match](https://developer.incode.com/docs/module-face-match) (or [Government Validation](https://developer.incode.com/docs/module-government-validation)). 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 `addApproval()`.
   ```swift
   flowConfig.addApproval(forceApproval: nil)   // forceApproval defaults to nil
   ```

Approval cannot be combined with the [Video Conference](https://developer.incode.com/docs/module-conference) module in the same flow. Configuration verification rejects any flow with both.

### Example

The example below adds the capture and verification modules Approval depends on, then adds Approval and listens for the result through `onApproveCompleted(_:)` on the delegate.

```swift
let flow = IncdOnboardingFlowConfiguration()
flow.addIdScan(scanStep: .both)
flow.addSelfieScan()
flow.addFaceMatch(matchType: .idSelfie, idCategory: .primary)
flow.addApproval()

IncdOnboardingManager.shared.startOnboarding(
    sessionConfig: IncdOnboardingSessionConfiguration(token: "<SESSION_TOKEN>"),
    flowConfig: flow,
    delegate: self
)

// In your IncdOnboardingDelegate:
func onApproveCompleted(_ result: ApprovalResult) {
    if result.success {
        // User approved
    }
}
```

## Configuration Options

Approval exposes a single method, `addApproval(forceApproval:)`, configured through its one parameter. Calling `addApproval()` with no arguments doesn't invoke a separate, parameterless overload; it's the same method, with `forceApproval` left at its default value.

| Option          | Type    | Notes                                                                                                                                                                                                                                  |
| --------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `forceApproval` | `Bool?` | If `true`, the user is approved regardless of score. If `false`, only users whose overall score is above the threshold are approved. Defaults to `nil`, which falls back to the persisted `IncdOnboardingManager.forceApproval` value. |

Score thresholds and approval decisions also depend on your Flow or Workflow configuration in Dashboard.

## Result

```swift
func onApproveCompleted(_ result: ApprovalResult)
```

`ApprovalResult` fields:

- `success: Bool`: `true` when the user was approved.
- `uuid: String?`: The session UUID; `nil` when unavailable.
- `customerToken: String?`: The session token; `nil` when unavailable.
- `error: IncdError?`: Set when the step failed.

<br />
