# Configure Flows Locally and Run End to End

Use `startOnboarding()` when you want to configure the flow in your app code and run all modules end to end in a single call. This is the simplest pattern: configure the session, configure the flow, and start onboarding. The SDK handles every module in sequence and returns control to your app when the flow completes.

## When to use this pattern

Use this pattern when:

- You want to define your flow's modules in code rather than in Dashboard.
- You want all modules to run consecutively without intermediate control returned to your app.
- You don't need to interleave Incode SDK steps with your app's own screens.

For section-by-section execution with control returned between sections, see [Configure Flows Locally and Run Step by Step](./flutter-configure-flows-locally-and-run-step-by-step). For flows configured in Dashboard, see [Run Flows Configured Online](./flutter-run-flows-configured-online).

## Prerequisites

- The SDK is initialized. See [Installation](./flutter-installation).

## 1. Configure the onboarding session

Create an instance of `OnboardingSessionConfiguration`:

```dart
OnboardingSessionConfiguration sessionConfig = OnboardingSessionConfiguration();
```

### Optional session parameters

You can pass any of the following parameters to the `OnboardingSessionConfiguration` constructor:

- `region`: Defaults to `ALL`.
- `onboardingValidationModules`: List of `OnboardingValidationModule` items. Determines which modules are used for verification and onboarding score calculation. If `null`, the defaults are used: id, faceRecognition, and liveness.
- `queue`: Name of the video conference queue. Defaults to `null`, which uses the default queue.
- `customFields`: Custom fields sent to the server.
- `externalId`: User identifier outside of the Incode Omni database. If a session with the same `externalId` already exists, it is resumed; otherwise, a new session is created.
- `externalCustomerId`: Identifier linking the onboarding session to an entity in an external system. Typically used to represent a prospect ID or customer ID from your own database.
- `interviewId`: Unique identifier of an existing session. Resumes that session.
- `token`: Token of an existing session. Resumes that session. See [Token-Based Setup](./flutter-token-based-setup).
- `configurationId`: Flow `configurationId` from the Incode Dashboard. On this pattern, the locally configured flow still executes; the `configurationId` does not take precedence. To run a Dashboard-configured Flow, see [Run Flows Configured Online](./flutter-run-flows-configured-online).
- `e2eEncryptionEnabled`: Enables End-to-End Encryption for the session. See [End-to-End Encryption (E2EE)](./flutter-e2ee).

## 2. Configure the onboarding flow

Create an instance of `OnboardingFlowConfiguration` and add the modules you need. Modules execute in the order you add them.

```dart
OnboardingFlowConfiguration flowConfig = OnboardingFlowConfiguration();
flowConfig.addIdScan();
flowConfig.addSelfieScan();
flowConfig.addFaceMatch();
```

For the full list of available modules, their configuration parameters, and their interdependencies, see [Modules](./flutter-modules).

## 3. Start onboarding

Call `startOnboarding` with the session and flow configurations. Add optional listener callbacks to receive results from individual modules as they complete.

```dart
IncodeOnboardingSdk.startOnboarding(
  sessionConfig: sessionConfig,
  flowConfig: flowConfig,
  onSuccess: () {
    print('Incode Onboarding completed!');
  },
  onError: (String error) {
    print('Incode onboarding error: $error');
    IncodeSdkFlowError? e = error.toIncodeSdkFlowError();
    switch (e) {
      case IncodeSdkFlowError.permissionsDenied:
        print('User denied permissions');
        break;
      case IncodeSdkFlowError.jailbreakDetected:
        print('Jailbreak detected');
        break;
      case IncodeSdkFlowError.faceAuthenticationFailed:
        print('Face authentication failed');
        break;
      case IncodeSdkFlowError.unknown:
        print('Unknown error');
        break;
      default:
        print('Other error: $error');
        break;
    }
  },
  onUserCancelled: () {
    print('User cancelled onboarding');
  },
  onSelfieScanCompleted: (SelfieScanResult result) {
    print('Selfie completed result: $result');
  },
  onIdFrontCompleted: (IdScanResult result) {
    print('onIdFrontCompleted result: $result');
  },
  onIdBackCompleted: (IdScanResult result) {
    print('onIdBackCompleted result: $result');
  },
  onIdProcessed: (String ocrData) {
    print('onIdProcessed result: $ocrData');
  },
);
```

### Flow callbacks

- `onSuccess`: Called when all modules complete successfully.
- `onError`: Called when an error stops the flow. Receives an `error` String; possible values are listed in the `IncodeSdkFlowError` enum.
- `onUserCancelled`: Called when the user cancels the flow.
- Per-module completion callbacks (`onSelfieScanCompleted`, `onIdFrontCompleted`, `onIdBackCompleted`, `onIdProcessed`, and others): Optional. Add the callbacks for modules whose results you want to receive as they complete. See [Results](./flutter-results) for the full list of available listeners and their payloads.

### IncodeSdkFlowError enum values

- `permissionsDenied`: The user denied a required permission.
- `badEnvDetected` **(deprecated)**: No longer reported. The native SDK terminates the process when a compromised device environment is detected, so this case is never delivered.
- `jailbreakDetected`: The device is jailbroken or rooted.
- `faceAuthenticationFailed`: Face authentication did not succeed.
- `sslPinningFailed`: SSL pinning failed.
- `unknown`: An error that does not match any other enum case.

## Record the capture session (optional)

To store ID and Selfie capture session recordings, pass an `OnboardingRecordSessionConfiguration` to `startOnboarding` via the `recordSessionConfig` parameter.

```dart
OnboardingRecordSessionConfiguration recordSessionConfig = OnboardingRecordSessionConfiguration(
  recordSession: true,
  forcePermission: false,
);

IncodeOnboardingSdk.startOnboarding(
  sessionConfig: sessionConfig,
  flowConfig: flowConfig,
  recordSessionConfig: recordSessionConfig,
  onSuccess: () { /* ... */ },
  onError: (String error) { /* ... */ },
  // Add per-module listeners as needed
);
```

### Record session parameters

- `recordSession`: bool. Set to `true` to record ID and Selfie capture sessions.
- `forcePermission`: bool. If `true`, the user must accept recording permissions or the onboarding session is aborted. If `false`, the session continues without recording when permission is denied.

Recorded sessions are automatically uploaded to Incode's servers. You can access them in Dashboard in the single session view for each individual session.

<br />
