---
title: User Journeys
description: Multi-step capture sessions orchestrated by the SDK based on the configured flow, such as selfie, document, and signature in a single session.
canonical: https://developer.unico.io/developers/sdks-and-tools/flutter/capture-flow/user-journeys
locale: en
generated_by: markdown-export
---

- [/](/)
- [SDKs and Tools](/developers/sdks-and-tools/overview)
- [Flutter SDK](/developers/sdks-and-tools/flutter/requirements)
- Capture flow
- User Journeys

# User Journeys

User Journeys are multi-step capture sessions orchestrated by the SDK in conjunction with the configured flow. For example, the `idchecktrustdocssign` flow executes selfie + document + signature in a single session.

ProductsThe available journeys depend on the flow configured for your integration. Refer to [Products](/products) for the full mapping of product → flow → capability.

How it works
The plugin delegates to the underlying native SDKs:

1. The plugin opens the camera (Android or iOS) with the SmartFrame overlay.
2. The native SDK orchestrates the sequence of captures required for the flow (selfie, document, signature).
3. The SDK internally forwards the results to Unico — the client never receives or manages image data directly.
4. Returns a `SuccessResult` object with a `processId` via the platform channel.

The orchestration is handled entirely by the SDK — you do not need to implement the step sequence in your Dart code.

Camera mode (smart capture)
The SDK has **intelligent framing** and **automatic capture** enabled by default. Configure the camera mode in your builder as follows:

```
UnicoCheckCameraOpener _opener = new UnicoCheck(this)**    .setAutoCapture(autoCapture: true)    .setSmartFrame(smartFrame: true)    .build();
```

Starting a User Journey
**Step 1** — Implement `UnicoListener``UnicoListener` handles the SDK lifecycle callbacks. Implement the four mandatory methods:MethodWhen it's called`onErrorUnico(error)`An error occurred during SDK operation`onUserClosedCameraManually()`The user manually closed the camera`onSystemClosedCameraTimeoutSession()`The 40-second session limit was reached`onSystemChangedTypeCameraTimeoutFaceInference()`No face detected for 13 seconds — switches to manual capture```
class _MyHomePageState extends State<MyHomePage> implements UnicoListener {  late UnicoCheckBuilder _unicoCheck;  @override  void onErrorUnico(UnicoError error) {}  @override  void onUserClosedCameraManually() {}  @override  void onSystemClosedCameraTimeoutSession() {}  @override  void onSystemChangedTypeCameraTimeoutFaceInference() {}}
```

Mandatory listener methodsAll four listener methods above must be created in your project (even without any logic). Otherwise, the project will not compile successfully.
**Step 2** — Implement the journey listeners on `UnicoSelfie`Add the journey callbacks to your state class:MethodDescription`onSuccess(SuccessResult result)`Capture succeeded — returns `SuccessResult` with `processId` (Unico processes the image internally)`onErrorSelfie(UnicoError error)`Capture failed — returns a `UnicoError` with code and descriptionNo image dataUnlike the Liveness flow, the User Journey callback does **not** return `base64` or `encrypted`. Unico handles the image processing internally and returns only a `processId`.```
@overridevoid onSuccess(SuccessResult result) {  debugPrint('processId: ${result.processId}');}@overridevoid onErrorSelfie(UnicoError error) { }
```

**Step 3** — Call `openCameraSelfie`The `openCameraSelfie` method opens the camera. For User Journeys, pass the `webAppToken` provided by Unico instead of a JSON credentials file:```
_opener.openCameraSelfie(  listener: this,  webAppToken: token,);
```

Monitoring data collection
The `openCameraSelfie` method provides an overload that accepts metadata via `UnicoCheckPrepareInfo` to assist in identifying the user session and the flow:

`externalUserId` (String, **required**) — User identifier within your system. Automatically hashed using SHA-256 before transmission.
`useCase` (String, optional) — Identifier for the context or flow currently running. Transmitted in plain text.

```
_opener.openCameraSelfie(  listener: this,  webAppToken: token,  prepareInfo: UnicoCheckPrepareInfo(    externalUserId: 'external_user_id',    useCase: 'use_case', // optional  ),);
```

For the full result handling, see [Receiving the result](/developers/sdks-and-tools/flutter/capture-flow/receiving-the-result).Last updated on Oct 8, 2026**