> For the complete documentation index, see [llms.txt](https://docs.voveid.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.voveid.com/docs/sdks/flutter.md).

# Flutter SDK

Integrate VOVE ID in Flutter with typed statuses, locales, and step-by-step control.

Use the plugin version your team has tested and approved.

## Install

```yaml
dependencies:
  vove_id_flutter: ^1.6.0
```

Run:

```bash
flutter pub get
cd ios && pod install
```

Add a camera usage description on iOS and camera permission on Android, then request authorization at runtime.

## Initialize

```dart
import 'package:flutter/widgets.dart';
import 'package:vove_id_flutter/vove_id_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Vove.initialize(
    environment: VoveEnvironment.sandbox,
    publicKey: 'public_sandbox_replace_me',
  );

  runApp(const MyApp());
}
```

The public key may ship in the application. Create the session token on your backend; never embed the private API key in the app.

## Start

```dart
final result = await Vove.start(
  sessionToken: tokenFromYourBackend,
  configuration: VoveStartConfiguration(
    showUI: true,
    exitAfterEachStep: false,
    onMaxAttemptsReached: showSupportOptions,
  ),
  locale: VoveLocale.en,
  enableVocalGuidance: false,
);

switch (result.status) {
  case VoveVerificationStatus.success:
    showAwaitingServerConfirmation();
    break;
  case VoveVerificationStatus.pending:
    showPendingReview();
    break;
  case VoveVerificationStatus.canceled:
    showVerificationCanceled();
    break;
  case VoveVerificationStatus.maxAttempts:
    showSupportOptions();
    break;
  default:
    reportIntegrationError();
    break;
}
```

Treat the result as a journey signal. Your backend should verify the webhook and retrieve the current KYC resource before making a final decision.

## Configuration

| Field                  | Type            | Default | Description                                    |
| ---------------------- | --------------- | ------- | ---------------------------------------------- |
| `showUI`               | `bool`          | `true`  | Show the built-in welcome and summary screens. |
| `exitAfterEachStep`    | `bool`          | `false` | Return control after each configured step.     |
| `onMaxAttemptsReached` | `VoidCallback?` | `null`  | Present an approved recovery or support path.  |
| `locale`               | `VoveLocale?`   | `en`    | `en`, `fr`, `ar`, `de`, or `arMA`.             |
| `enableVocalGuidance`  | `bool?`         | `false` | Enable supported spoken guidance.              |

Documented status values are `success`, `pending`, `canceled`, and `maxAttempts`. Treat any other value as a safe pending/error state—never as success.

## Step-by-step journey

```dart
final result = await Vove.start(
  sessionToken: tokenFromYourBackend,
  configuration: VoveStartConfiguration(
    showUI: false,
    exitAfterEachStep: true,
  ),
);

handleNextStep(result.nextStep);
```

Next-step values map to liveness, ID document, driving license, address proof, car registration document, done, or unknown. They depend on the configured flow.

## Production checklist

* Pin and regression-test the package version.
* Confirm iOS and Android permission denial/recovery paths.
* Test physical devices across supported OS versions.
* Match `sandbox`/`production` to the public key and session token.
* Test backgrounding, process recreation, network loss, and max attempts.
* Reconcile final state on the backend.

## Troubleshooting

| Symptom                                  | Check                                                                              |
| ---------------------------------------- | ---------------------------------------------------------------------------------- |
| iOS cannot find `VoveStartConfiguration` | Update CocoaPods metadata, run `pod install`, and rebuild.                         |
| Native plugin is missing                 | Stop the app and perform a full native rebuild; hot reload cannot install plugins. |
| Session token is rejected                | Fetch a fresh token from the matching environment.                                 |
| Camera is blank or denied                | Check platform declarations, runtime authorization, and physical-device behavior.  |
| Unrecognized result or next step         | Keep the user pending, capture non-sensitive diagnostics, and escalate.            |

See [SDK compatibility](/docs/sdks/compatibility.md), [session creation](/docs/kyc-api/verification-session.md), and [production readiness](/docs/production-readiness.md).
