# Results

A Flutter SDK flow returns results in two ways: through per-API success, error, and cancellation behavior (delivered to the callbacks you pass to a `start` method), and through per-module result objects (delivered to optional listener callbacks as individual modules complete).

This page documents both. For how to register listeners and wire callbacks into a flow, see [Common Implementation Patterns](./flutter-common-implementation-patterns). For module configuration parameters, see [Modules](./flutter-modules).

## API results

This section lists the success results and errors returned by each top-level SDK API method. Per-module step results (delivered through callbacks such as `onSelfieScanCompleted`) are listed separately under [Module result objects](./flutter-results#module-result-objects).

### Error enums

Errors are delivered as a `String` to the `onError` callback. The `String` can be converted to one of the following enums.

`IncodeSdkInitError` (via `error.toIncodeSdkInitError()`) is returned by `init`:

- `simulatorDetected`
- `testModeEnabled`
- `unknown`

`IncodeSdkFlowError` (via `error.toIncodeSdkFlowError()`) is returned by flow APIs such as `startOnboarding`:

- `permissionsDenied`
- `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`
- `faceAuthenticationFailed`
- `sslPinningFailed`
- `unknown`

### init

- **Success:** `onSuccess` is called with no result object. Safe to start onboarding.
- **Error:** `onError(String error)`. Convert with `error.toIncodeSdkInitError()` to an `IncodeSdkInitError`.

### startOnboarding

- **Success:** `onSuccess` is called with no result object once all steps are completed.
- **Error:** `onError(String error)`. Convert with `error.toIncodeSdkFlowError()` to an `IncodeSdkFlowError`.
- **Cancellation:** `onUserCancelled` is called if the user cancels the flow.
- Per-step results are delivered through the optional module callbacks. See [Module result objects](./flutter-results#module-result-objects).

### setupOnboardingSession

- **Success:** `onSuccess(OnboardingSessionResult result)` is called once the onboarding session is created.
- **Error:** `onError(String error)`.

### startNewOnboardingSection

- **Section completed:** `onOnboardingSectionCompleted(String flowTag)` is called with the `flowTag` identifier of the completed section.
- **Error:** `onError(String error)`.
- Per-step results are delivered through the optional module callbacks. See [Module result objects](./flutter-results#module-result-objects).

### finishFlow

- Returns no result and reports no errors.

### startFlow

- **Success:** `onSuccess` is called with no result object once the flow completes.
- **Error:** `onError(String error)`.
- **Cancellation:** `onUserCancelled` is called if the user cancels the flow.

### startFlowFromDeepLink

- **Success:** `onSuccess` is called with no result object once the flow completes.
- **Error:** `onError(String error)`.
- **Cancellation:** `onUserCancelled` is called if the user cancels the flow.

### faceMatch

- **Success:** `onSuccess` is called with no result object.
- **Result:** `onFaceMatchCompleted(FaceMatchResult result)` delivers the match result. See [FaceMatch](./flutter-results#facematch-1) under Module result objects.
- **Error:** `onError(String error)`.
- **Cancellation:** `onUserCancelled` is called if the user cancels.

### startFaceLogin

- **Success:** `onSuccess(FaceLoginResult result)`.
- **Error:** `onError(String error)`.

`FaceLoginResult` contains:

- `image`: Selfie image captured during login.
- `spoofAttempt`: bool. `true` indicates the user tried to spoof the system.
- `base64Images`: Base64 representations of the selfie image.
- `faceMatched`: bool. `true` if the faces matched, `false` otherwise.
- `customerUUID`: String?. Unique user identifier if authentication succeeded. `null` if `faceMatched` is `false`.
- `interviewId`: String. Session ID in which the user was approved.
- `interviewToken`: String. Session token in which the user was approved.
- `token`: String. Token that can be used for further API calls.
- `transactionId`: String. Unique identifier of the Face Login attempt.
- `hasLenses`: bool. Indicator if the login attempt failed because the user was wearing lenses.
- `hasFaceMask`: bool. Indicator if the login attempt failed because the user was wearing a face mask.

### idProcess

- **Success:** `onSuccess(IdProcessResult result)`.
- **Error:** `onError(String error)`.

`IdProcessResult` contains:

- `ocrData`: String?. Raw JSON containing full OCR data (for example, `exteriorNumber`, `interiorNumber`, `typeOfId`, `documentFrontSubtype`).

### addFace

- **Success:** `onSuccess(bool result)`.
- **Error:** `onError(String error)`.

### removeFace

- **Success:** `onSuccess(bool result)`.
- **Error:** `onError(String error)`.

### getFaces

- **Success:** `onSuccess(List<FaceInfo> faceInfos)`.
- **Error:** `onError(String error)`.

### setFaces

- **Success:** `onSuccess(bool result)`.
- **Error:** `onError(String error)`.

### deleteLocalUserData

- Returns a `Future` that completes once locally stored user data is deleted. No result object or error is reported.

### getUserScore

- **Success:** `onSuccess(UserScoreResult result)`.
- **Error:** `onError(String error)`.

`UserScoreResult` has an `extendedUserScoreJsonData` String field containing the full user data in JSON format. See [UserScore](./flutter-results#userscore) under Module result objects for the full structure.

### addNOM151Archive

- **Success:** `onSuccess(AddNom151Result addNom151Result)`.
- **Error:** `onError(String error)`.

`AddNom151Result` contains:

- `signature`: String?.
- `archiveUrl`: String?.

### getUserOCRData

- **Success:** `onSuccess(GetUserOCRDataResult result)`.
- **Error:** `onError(String error)`.

`GetUserOCRDataResult` contains:

- `ocrData`: String. Full OCR data in JSON format.

### isInitialized

- Returns a `Future<bool>` that resolves to `true` when the SDK is ready to be used, and `false` otherwise. The method never throws; any platform error is handled internally and reported as `false`.

### onEvents

When onboarding has been started, the optional `onEvents` callback delivers `OnEventsResult` for every tracked user step:

- `event`: String. Unique identifier of the event.
- `data`: String?. JSON string with additional event details.

### Methods without a result

The following methods return no result object and report no errors: `setSdkMode`, `setTheme`, `setString`, `setLocalizationLanguage`, and `showCloseButton`.

## Module result objects

This section lists the result objects returned by individual modules. Alphabetized for direct lookup.

### Aes

Specify `onAesCompleted` to one of the `start` methods to receive `AesResult`:

- `success`: bool. `true` if Aes completed successfully, `false` otherwise.
- `error`: `AesError`. Possible values: `noDocuments`, `failedToSign`.

### Antifraud

Specify `onAntifraudCompleted` to one of the `start` methods to receive `AntifraudResult`:

- `success`: bool. `true` if the antifraud check passed successfully, `false` otherwise.

### Approve

Specify `onApproveCompleted` to one of the `start` methods to receive `ApprovalResult`:

- `success`: bool. `true` if the approval was successful, `false` otherwise.
- `uuid`: String?. Customer ID of the newly created customer if approval was successful; `null` otherwise.
- `customerToken`: String?. Customer token for the newly created customer if approval was successful; `null` otherwise.

### Captcha

Specify `onCaptchaCompleted` to one of the `start` methods to receive `CaptchaResult`:

- `captcha`: String?. The CAPTCHA value entered by the user.

### CombinedConsent

Specify `onCombinedConsentCompleted` to one of the `start` methods to receive `CombinedConsentResult`:

- `success`: bool. `true` if the user gave data sharing consent, `false` otherwise.

### CURP

Specify `onCurpValidationCompleted` to one of the `start` methods to receive `CurpValidationResult`:

- `curp`: String?. The user's CURP.
- `valid`: bool?. `true` if the user's CURP is valid. `null` indicates no result (the user skipped the step).
- `data`: Map\<String, dynamic>?. The user's CURP data.

### CustomWatchlist

Specify `onCustomWatchlistCompleted` to one of the `start` methods to receive `CustomWatchlistResult`:

- `success`: bool. `true` if the CustomWatchlist check completed successfully, `false` otherwise.

### Document

Specify `onDocumentScanCompleted` to one of the `start` methods to receive `DocumentScanResult`:

- `image`: Uint8List?. Document scan image.
- `documentType`: `DocumentType`. The type of scanned document.
- `address`: Map\<String, dynamic>?. Address fetched from the document. Available only for `DocumentType.addressStatement`.
- `ocrData`: Raw JSON containing full OCR data.

### EKYB

Specify `onEKYBCompleted` to one of the `start` methods to receive `EKYBResult`:

- `success`: bool. `true` if the eKYB scan completed successfully, `false` otherwise.

### EKYC

Specify `onEKYCCompleted` to one of the `start` methods to receive `EKYCResult`:

- `success`: bool. `true` if the eKYC scan completed successfully, `false` otherwise.

### Email

Specify `onAddEmailCompleted` to one of the `start` methods to receive `AddEmailResult`:

- `email`: String. The email the user entered.

### FaceAuthentication

Specify `onFaceAuthenticationCompleted` to one of the `start` methods to receive `FaceAuthenticationResult`:

- `status`: bool. `true` if face authentication succeeded, `false` otherwise.
- `customerUUID`: String?. Unique customer identifier if face authentication succeeded. `null` if `status` is `false`.
- `selfieBase64`: String?. Base64 representation of the selfie image captured during face authentication.
- `selfieEncryptedBase64`: String?. Encrypted base64 representation of the selfie image.
- `error`: String?. Description of the error if face authentication did not succeed.

### FaceMatch

Specify `onFaceMatchCompleted` to one of the `start` methods to receive `FaceMatchResult`:

- `confidence`: double?. Recognition confidence between selfie and ID photo.
  If it is higher than 0.6f, the person's selfie successfully matched with the front ID. If it is -1, the front ID image wasn't uploaded, so the face match service didn't have data to compare with the selfie. Valid range is `0.0` to `1.0`.
- `existingInterviewId`: String?. If the user is an existing user, the existing interview ID.
- `idCategory`: `IdCategory`. Category of the ID used for face match.
- `isExistingUser`: bool. Indicates whether the user is new or existing.
- `isFaceMatched`: bool. `true` if the user's selfie matched the front ID successfully. `false` if it did not match. `null` if the front ID image was not uploaded, so the face match service had no data to compare with.
- `isNameMatched`: bool?._&#x20;_`true` if the name of the already existing user matches the name of the current user. `false` otherwise.
- `nfcVsIdConfidence`: double?. Recognition confidence between ID and NFC photo.<br />If it is higher than 0.6f, the person's front ID photo successfully matched with the image in the NFC chip. If it is -1, either no front ID or NFC image was uploaded, so the face match service didn't have data to compare. Valid range is `0.0` to `1.0`.
- `nfcVsSelfieConfidence`: double?. Recognition confidence between selfie and NFC photo.<br />If it is higher than 0.6f, the person's selfie successfully matched with the image in the NFC chip. If it is -1, no NFC image was uploaded, so the face match service didn't have data to compare with the selfie. Valid range is `0.0` to `1.0`.
- `secondIdConfidence`: double?. Recognition confidence between the selfie and the secondary ID. Valid range is `0.0` to `1.0`.

Older documentation may refer to `isFaceMatched` as `faceMatched` and `isExistingUser` as `existingUser`; the current names are `isFaceMatched` and `isExistingUser`.

### FullName

Specify `onAddFullNameCompleted` to one of the `start` methods to receive `AddFullNameResult`:

- `name`: String. The name the user entered.

### Geolocation

Specify `onGeolocationCompleted` to one of the `start` methods to receive `GeoLocationResult`:

- `city`: String?.
- `colony`: String?.
- `postalCode`: String?.
- `state`: String?.
- `street`: String?.

### GlobalWatchlist

Specify `onGlobalWatchlistCompleted` to one of the `start` methods to receive `GlobalWatchlistResult`:

- `success`: bool. `true` if the GlobalWatchlist check completed successfully, `false` otherwise.

### GovernmentValidation

Specify `onGovernmentValidationCompleted` to one of the `start` methods to receive `GovernmentValidationResult`:

- `success`: bool. `true` if government validation succeeded, `false` otherwise.

### IdScan

IdScan delivers results through two listener types.

#### Per-side capture

Specify `onIdFrontCompleted`, `onIdBackCompleted`, `onIdFrontAttemptCompleted`, and/or `onIdBackAttemptCompleted` to one of the `start` methods to receive `IdScanResult`:

- `image`: Captured ID image.
- `base64Image`: String?. Captured front ID image in base64 format.
- `croppedFace`: Cropped face from the captured ID image.
- `chosenIdType`: User-chosen type on the ID selection screen (`id` or `passport`).
- `classifiedIdType`: Type of the captured ID.
- `idCategory`: `IdCategory`. Category of the scanned ID.
- `failReason`: String?. Reason the ID scan failed.
- `issueName`: String?. Detailed type of the ID.
- `issueYear`: int?. Year the ID was issued.
- `countryCode`: String?. Country code where the ID was issued.
- `scanStatus`: `IdValidationStatus`. If the value is anything other than `ok`, the ID scan or validation did not complete successfully. Possible values: `ok`, `errorClassification`, `noFacesFound`, `errorCropQuality`, `errorGlare`, `errorSharpness`, `errorTypeMismatch`, `userCancelled`, `unknownError`, `errorAddress`, `errorPassportClassification`, `errorUnacceptableID`.
- `allAttemptsExhausted`: bool. Indicates whether all retry attempts have been exhausted. Reflects the outcome of the current side (front or back) independently.

_&#x20;_`onIdFrontCompleted` and `onIdBackCompleted` are called only on a successful scan, while `onIdFrontAttemptCompleted` and `onIdBackAttemptCompleted` are called on every scan, successful or not.

#### OCR data

Specify `onIdProcessed` to one of the `start` methods to receive a `String` OCR result:

- `ocrData`: String?. Raw JSON containing the full OCR data (for example, `exteriorNumber`, `interiorNumber`, `typeOfId`, `documentFrontSubtype`).

### MLConsent

Specify `onMLConsentCompleted` to one of the `start` methods to receive `MLConsentResult`:

- `success`: bool. `true` if the user gave machine learning consent, `false` otherwise.

### NFCScan

Specify `onNFCScanCompleted` to one of the `start` methods to receive `NFCScanResult`:

- `success`: bool?. `true` if the NFC scan was successful.
- `birthDate`: String?. Date of birth of the document owner, in `yyMMdd` format.
- `compositeCheckDigit`: String?. Digit used to check the integrity of all data in the MRZ of the document.
- `dateOfBirthCheckDigit`: String?. Digit used to check the integrity of the `birthDate` field.
- `documentCode`: String?. Type of ICAO 9303-compliant document. For example, a passport booklet is `TD3`. Possible values: `TD1`, `TD2`, `TD3`, `MRVA`, `MVRB`.
- `documentNumber`: String?. The 9 most significant digits of the passport number, CIC, or equivalent.
- `documentNumberCheckDigit`: String?. Digit used to check the integrity of the `documentNumber` field.
- `expirationDateCheckDigit`: String?. Digit used to check the integrity of the `expireAt` field.
- `expireAt`: String?. Document expiration date, in `yyMMdd` format.
- `gender`: String?. Gender of the document owner. Possible values: `M`, `F`, `UNKNOWN`, `UNSPECIFIED`.
- `issuingStateOrOrganization`: String?. Three-letter code of the authority that issued the document. For example, US passports use `USA`.
- `nationality`: String?. Three-letter code of the document owner's nationality. For example, UK passports use `GBR`.
- `optionalData1`: String?. Contents of the first optional data field, for TD-1 and TD-3 style MRZs.
- `optionalData2`: String?. Contents of the second optional data field, for TD-1 style MRZs only.
- `personalNumber`: String?. Personal number of the document owner, if encoded in `optionalData1`.
- `personalNumberCheckDigit`: String?. Digit used to check the integrity of the `personalNumber` field. Populated only when `documentCode` is `TD3`.
- `primaryIdentifier`: String?. Primary means of identifying the document. Typically the document owner's last name.
- `secondaryIdentifier`: String?. Secondary means of identifying the document. Typically the document owner's other names.

### OCREdit

Specify `onOCREditCompleted` to one of the `start` methods to receive `OCREditResult`:

- `success`: bool. `true` if OCR edit completed successfully, `false` otherwise.

### Phone

Specify `onAddPhoneNumberCompleted` to one of the `start` methods to receive `PhoneNumberResult`:

- `phone`: String. The phone number the user entered.

### QRScan

Specify `onQRScanCompleted` to one of the `start` methods to receive `QRScanResult`:

- `success`: bool. `true` if the QR scan completed successfully, `false` otherwise.

### SelfieScan

Specify `onSelfieScanCompleted` and/or `onSelfieScanAttemptCompleted` to one of the `start` methods to receive `SelfieScanResult`:

- `image`: Uint8List?. Captured selfie image.
- `spoofAttempt`: bool. `false` indicates a real person. `true` indicates a spoof attempt (the user tried to deceive the system using paper, a digital photo, or other method). `null` indicates an unexpected error so spoof detection could not run.
- `base64Images`: `SelfieScanBase64Images`. Selfie image in different formats.
  - `selfieBase64`: String?. Captured selfie as a base64 image.
  - `selfieEncryptedBase64`: String?. Captured selfie as an encrypted base64 image.
- `allAttemptsExhausted`: bool. Indicates whether all retry attempts have been exhausted.

`onSelfieScanCompleted` is called only on a successful scan, while `onSelfieScanAttemptCompleted` is called on every scan, successful or not.

### Signature

Specify `onSignatureCollected` to one of the `start` methods to receive `SignatureResult`:

- `signature`: Uint8List?. The collected signature image.

### UserConsent

Specify `onUserConsentCompleted` to one of the `start` methods to receive `UserConsentResult`:

- `success`: bool. `true` if the user gave consent, `false` otherwise.

### UserScore

Specify `onUserScoreFetched` to one of the `start` methods to receive `UserScoreResult`:

- `extendedUserScoreJsonData`: String?.
- `overall`: `_UserScore?`. Contains value and status of the overall user score.
  - `value`: String?.
  - `status`: `UserScoreStatus?`.
- `faceRecognition`: `_UserScore?`. Contains value and status of the face recognition user score.
  - `value`: String?.
  - `status`: `UserScoreStatus?`.
- `liveness`: `_UserScore?`. Contains value and status of the liveness user score.
  - `value`: String?.
  - `status`: `UserScoreStatus?`.
- `idValidation`: `_UserScore?`. Contains value and status of the ID validation user score.
  - `value`: String?.
  - `status`: `UserScoreStatus?`.

The `status` field can have one of the following values: `warn`, `unknown`, `manual`, `fail`, `ok`.

Example `UserScoreResult` for module completion:

```dart
{
  overall: {
    value: '0.0/100',
    status: 'ok',
  },
  faceRecognition: {
    value: '0.0/100',
    status: 'warn',
  },
  liveness: {
    value: '95.2/100',
    status: 'manual',
  },
  idValidation: {
    value: '79.0/100',
    status: 'fail',
  },
}
```

### VideoSelfie

Specify `onVideoSelfieCompleted` to one of the `start` methods to receive `VideoSelfieResult`:

- `success`: bool. `true` if the video selfie completed successfully, `false` otherwise.

<br />
