---
Source: https://docs.microblink.com/blinkid/next/migration-v8000
Title: Migrate to v8000
Description: How to migrate the BlinkID SDK from v7 to v8000
---
# Migrate to v8000
This guide describes how to upgrade the BlinkID SDK from v7 to v8000.
:::note
BlinkID v8000 brings new capabilities beyond those listed in this migration guide.
The migration guide is focused on getting you to successfully migrate to the new version, so it doesn't cover new features.
Read the [release notes](/blinkid/release-notes) to find out what else is new.
:::
## Versioning change
Starting with v8000, BlinkID adopts the [epoch versioning scheme](https://antfu.me/posts/epoch-semver#epoch-semantic-versioning).
> `{EPOCH * 1000 + MAJOR}.MINOR.PATCH`
>
> EPOCH: Increment when you make significant or groundbreaking changes.
>
> MAJOR: Increment when you make minor incompatible API changes.
>
> MINOR: Increment when you add functionality in a backwards-compatible manner.
>
> PATCH: Increment when you make backwards-compatible bug fixes.
So, instead of going from v7.x.x to v8.x.x, **BlinkID goes from v7.x.x to v8000.x.x**.
Subsequent versions will follow the same scheme.
## Architecture changes
### Modularity
The most significant change in v8000 is the introduction of **recognition modules**, and their replacement of (fallback) recognition modes.
Four distinct modules now define how information is extracted from a document:
- document capture
- barcode
- machine readable zone (MRZ)
- visual inspection zone (VIZ)
You can now enable only those modules that you want to use.
This is reflected in how the settings object has been restructured:
**v7** (flat object):
```typescript
const settings: ScanningSettings = {
blurDetectionLevel: "low",
skipImagesWithBlur: false,
croppedImageSettings: {
returnFaceImage: true,
dotsPerInch: 300,
},
// ...
};
```
**v8000** (modularized):
```typescript
const settings: ScanningSettings = {
documentCaptureModule: {
blurSensitivityLevel: "low",
imageWithBlurRejected: false,
faceImageExtractionEnabled: true,
dotsPerInch: 300,
},
vizModule: {},
barcodeModule: {},
mrzModule: {},
// ...
};
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
**v7** (flat object):
```kotlin
val settings = ScanningSettings(
blurDetectionLevel = DetectionLevel.Low,
skipImagesWithBlur = false,
croppedImageSettings = CroppedImageSettings(
returnFaceImage = true,
dotsPerInch = 300,
),
// ...
)
```
**v8000** (modularized):
```kotlin
val settings = ScanningSettings(
documentCaptureModule = DocumentCaptureModuleSettings(
blurSensitivityLevel = SensitivityLevel.Low,
imageWithBlurRejected = false,
faceImageExtractionEnabled = true,
dotsPerInch = 300,
),
barcodeModule = BarcodeModuleSettings(),
mrzModule = MrzModuleSettings(),
vizModule = VizModuleSettings(),
)
```
*/}
**v7** (flat object):
```swift
let settings = ScanningSettings(
blurDetectionLevel: .low,
skipImagesWithBlur: false,
croppedImageSettings: CroppedImageSettings(
returnFaceImage: true,
dotsPerInch: 300
),
// ...
)
```
**v8000** (modularized):
```swift
let settings = ScanningSettings(
documentCaptureModule: DocumentCaptureModuleSettings(
blurSensitivityLevel: .low,
imageWithBlurRejected: false,
faceImageExtractionEnabled: true,
dotsPerInch: 300
),
vizModule: VizModuleSettings(),
barcodeModule: BarcodeModuleSettings(),
mrzModule: MrzModuleSettings()
)
```
In addition to settings being modularized, you'll also find that they're [validated](/blinkid/settings-validation), meaning that the SDK will block settings where the resulting configuration is nonsensical or cannot work properly.
### Non-blocking flow
Scanning now always completes.
Instead of failing in cases where it's difficult to read a specific field, the SDK will wait for a set amount of time, during which it will attempt to extract everything.
After the expiration of this time, the SDK will expose a **result completeness** object where you'll be able to use extracted information, even if the overall extraction wasn't a success.
In v7, result completeness was a flat set of boolean flags:
```typescript
// v7
blinkIdUxManager.addOnFrameProcessCallback((frameResult) => {
const completeness = frameResult.resultCompleteness;
if (completeness.mrzExtracted) {
// MRZ data is available
}
if (!completeness.faceImageExtracted) {
// face image wasn't captured
}
});
```
```kotlin
// v7
val completeness = processResult.resultCompleteness
if (completeness.mrzExtracted) {
// MRZ data is available
}
if (!completeness.faceImageExtracted) {
// face image wasn't captured
}
```
```swift
// v7
let completeness = processResult.resultCompleteness
if completeness.mrzExtracted {
// MRZ data is available
}
if !completeness.faceImageExtracted {
// face image wasn't captured
}
```
In v8000, the result completeness object provides detailed per-module status, including why extraction failed:
```typescript
// v8000
blinkIdUxManager.addOnFrameProcessCallback((frameResult) => {
const completeness = frameResult.resultCompleteness;
if (completeness.mrz?.status === "extracted") {
// MRZ data is available
}
if (completeness.faceImage?.failureReason === "detection") {
// face was not detected on the document
}
});
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
// v8000
BlinkIdCameraScanningScreen(
onFrameProcessResult = { handle ->
val completeness = handle.processResult.resultCompleteness
if (completeness.mrz?.status == ExtractionStatus.Extracted) {
// MRZ data is available
}
if (completeness.faceImage?.failureReason == ExtractionFailureReason.Detection) {
// face was not detected on the document
}
}
)
```
*/}
```swift
// v8000
BlinkIDUXView(...)
.onFrameProcessResult { handle in
guard let completeness = handle.processResult?.resultCompleteness else { return }
if completeness.mrz?.status == .extracted {
// MRZ data is available
}
if completeness.faceImage?.failureReason == .detection {
// face was not detected on the document
}
}
```
### Removal of custom document rules
With the introduction of a result completeness object, custom document rules are no longer used and have been removed.
Instead, each processed frame now exposes information about what has been extracted from a document, and you can create custom logic to indicate whether scanning should continue or stop.
Instead of specifying in advance which fields you expect to scan (for example, specifying in advance that you only want passports from a specific country), you now allow the SDK to perform all possible extraction, and for each frame, you check if your desired fields have been extracted or not.
If they have, you can then proceed or finish the scan.
**v7:**
```typescript
// Specify mandatory fields per document class in advance
const settings: ScanningSettings = {
customDocumentRules: [
{
documentFilter: { country: "croatia", type: "id" },
fields: [
{ fieldType: "firstName", alphabetType: "latin" },
{ fieldType: "lastName", alphabetType: "latin" },
],
},
],
// ...
};
```
**v8000:**
```typescript
// Check per-frame whether the fields you need have been extracted
blinkIdUxManager.addOnFrameProcessCallback(async (frameResult, advanceToNextStep) => {
const analysis = frameResult.inputImageAnalysisResult;
if (
analysis.documentClassInfo.country === "croatia" &&
analysis.documentClassInfo.type === "id" &&
analysis.extractedFields.includes("firstName") &&
analysis.extractedFields.includes("lastName")
) {
await advanceToNextStep();
}
});
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
**v7:**
```kotlin
// Specify mandatory fields per document class in advance
val settings = ScanningSettings(
customDocumentRules = listOf(
DocumentRules(
documentFilter = DocumentFilter(
country = Country.Croatia,
type = Type.Id
),
fields = listOf(
DetailedFieldType(FieldType.FirstName, AlphabetType.Latin),
DetailedFieldType(FieldType.LastName, AlphabetType.Latin)
)
)
)
)
```
**v8000:**
```kotlin
// Check per-frame whether the fields you need have been extracted
val processResult = session.process(image).getOrNull() ?: return
val analysis = processResult.inputImageAnalysisResult
if (analysis.documentClassInfo.country == Country.Croatia &&
analysis.documentClassInfo.type == Type.Id &&
analysis.extractedFields.contains(FieldType.FirstName) &&
analysis.extractedFields.contains(FieldType.LastName)
) {
session.resolveCurrentStep()
}
```
*/}
**v7:**
```swift
// Specify mandatory fields per document class in advance
var settings = ScanningSettings()
settings.customDocumentRules = [
DocumentRules(
documentFilter: DocumentFilter(country: .croatia, documentType: .id),
fields: [
DetailedFieldType(fieldType: .firstName, alphabetType: .latin),
DetailedFieldType(fieldType: .lastName, alphabetType: .latin),
]
)
]
```
**v8000:**
```swift
// Check per-frame whether the fields you need have been extracted
BlinkIDUXView(...)
.onFrameProcessResult { handle in
guard let analysis = handle.processResult?.inputImageAnalysisResult else { return }
if analysis.documentClassInfo.country == .croatia,
analysis.documentClassInfo.documentType == .id,
analysis.extractedFields.contains(.firstName),
analysis.extractedFields.contains(.lastName) {
await handle.advanceToNextStep()
}
}
```
### Changes in anonymization
Similarly to how custom document rules have been removed, so has the option to do custom anonymization using settings.
Instead of using document filters to specify in advance which fields in which document types should be anonymized, you now perform anonymization after you receive a result object.
This feature has also been renamed from anonymization to **redaction**, and the corresponding types and fields use `Redaction` instead of `Anonymization` in their names.
**v7:**
```typescript
// Per-document anonymization configured in scanning settings
const settings: ScanningSettings = {
anonymizationMode: "full-result",
customDocumentAnonymizationSettings: [
{
documentFilter: { country: "croatia", type: "id" },
fields: ["documentNumber", "sex", "dateOfBirth"],
documentNumberAnonymizationSettings: {
prefixDigitsVisible: 0,
suffixDigitsVisible: 2,
},
},
],
};
```
**v8000:**
```typescript
const blinkId = await createBlinkId({
licenseKey: "...",
redactionSettingsResolver: (classInfo) => {
if (classInfo.country === "croatia" && classInfo.type === "id") {
return {
mode: "full-result",
fields: ["sex", "dateOfBirth"],
documentNumberRedactionSettings: {
prefixDigitsVisible: 0,
suffixDigitsVisible: 2,
},
};
}
return null; // use SDK defaults for other documents
},
});
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
**v7:**
```kotlin
// Per-document anonymization configured in scanning settings
val settings = ScanningSettings(
anonymizationMode = AnonymizationMode.FullResult,
customDocumentAnonymizationSettings = listOf(
DocumentAnonymizationSettings(
documentFilter = DocumentFilter(
country = Country.Croatia,
type = Type.Id
),
fields = listOf(FieldType.DocumentNumber, FieldType.Sex, FieldType.DateOfBirth),
documentNumberAnonymizationSettings = DocumentNumberAnonymizationSettings(
prefixDigitsVisible = 0U,
suffixDigitsVisible = 2U
)
)
)
)
```
**v8000:**
```kotlin
// Anonymization applied when retrieving the result
val result = session.getResult(
documentAnonymizationSettings = DocumentAnonymizationSettings(
anonymizationMode = AnonymizationMode.FullResult,
fields = listOf(FieldType.Sex, FieldType.DateOfBirth),
documentNumberAnonymizationSettings = DocumentNumberAnonymizationSettings(
prefixDigitsVisible = 0U,
suffixDigitsVisible = 2U
)
)
).getOrNull()
```
*/}
**v7:**
```swift
// Per-document anonymization configured in scanning settings
var settings = ScanningSettings()
settings.customDocumentAnonymizationSettings = [
DocumentAnonymizationSettings(
documentFilter: DocumentFilter(country: .croatia, documentType: .id),
fields: [.documentNumber, .sex, .dateOfBirth],
documentNumberAnonymizationSettings: DocumentNumberAnonymizationSettings(
prefixDigitsVisible: 0,
suffixDigitsVisible: 2
)
)
]
```
**v8000:**
```swift
// Redaction configured via resolver when creating the analyzer
struct MyRedactionResolver: RedactionSettingsResolver {
func resolveRedactionSettings(classInfo: DocumentClassInfo) -> RedactionSettings? {
if classInfo.country == .croatia, classInfo.documentType == .id {
return RedactionSettings(
mode: .fullResult,
fields: [.sex, .dateOfBirth],
documentNumberRedactionSettings: DocumentNumberRedactionSettings(
prefixDigitsVisible: 0,
suffixDigitsVisible: 2
)
)
}
return nil // use SDK defaults for other documents
}
}
let analyzer = try await BlinkIDAnalyzer(
sdk: sdk,
redactionSettingsResolver: MyRedactionResolver()
)
```
#### Partial redaction
In v8000, the `fields` array takes precedence over `documentNumberRedactionSettings`.
In practice, this means that if you put `documentNumber` in the array of fields that are to be anonymized, and then specify the prefix/suffix, **the whole document number will be anonymized**.
If you want to show a document number prefix or suffix, don't explicitly list `documentNumber` in the `fields` array.
Other fields are not affected by this change.
For example, you can partially redact a document number, and fully redact another field.
See also the article on [redaction](/blinkid/redaction).
### Scan progression has changed
The result completeness object now contains much more detail.
In addition to saying if extraction failed for any given section of a document, the result completeness object now also provides information *why* something hasn't been extracted.
The structure of the object has also changed accordingly.
See the [result completeness examples](#non-blocking-flow) above.
In addition to more information in the result completeness object, v8000 introduces a per-frame API that is available across all platforms.
In v7, each scanning step would have a timeout.
If a timeout fired without the SDK reaching a "complete" state for that step, all collected intermediate data would be discarded.
You could also not trigger a transition to the next step based on your own criteria.
And, most importantly, you could not have collected raw camera frames regardless of extraction success.
In v8000, for each processed frame, you can optionally:
- inspect the result completeness object
```typescript
blinkIdUxManager.addOnFrameProcessCallback((frameResult) => {
const completeness = frameResult.resultCompleteness;
if (completeness.mrz?.status === "extracted") {
// MRZ extraction succeeded
}
if (completeness.faceImage?.failureReason === "detection") {
// Face was not detected on the document
}
});
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
BlinkIdCameraScanningScreen(
onFrameProcessResult = { handle ->
val completeness = handle.processResult.resultCompleteness
if (completeness.mrz?.status == ExtractionStatus.Extracted) {
// MRZ extraction succeeded
}
if (completeness.faceImage?.failureReason == ExtractionFailureReason.Detection) {
// Face was not detected on the document
}
}
)
```
*/}
```swift
BlinkIDUXView(...)
.onFrameProcessResult { handle in
guard let completeness = handle.processResult?.resultCompleteness else { return }
if completeness.mrz?.status == .extracted {
// MRZ extraction succeeded
}
if completeness.faceImage?.failureReason == .detection {
// Face was not detected on the document
}
}
```
- advance to the next step
```typescript
blinkIdUxManager.addOnFrameProcessCallback(async (frameResult, advanceToNextStep) => {
// Explicitly advance the session to the next step when your criteria are met
await advanceToNextStep();
});
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
BlinkIdCameraScanningScreen(
onFrameProcessResult = { handle ->
// Explicitly advance the session to the next step when your criteria are met
handle.advanceToNextStep()
}
)
```
*/}
```swift
BlinkIDUXView(...)
.onFrameProcessResult { handle in
// Explicitly advance the session to the next step
await handle.advanceToNextStep()
}
```
- retrieve the raw frames
```typescript
blinkIdUxManager.addOnFrameProcessCallback((frameResult, advanceToNextStep, triggerTimeout, getLastFrame) => {
const rawFrame: ArrayBuffer = getLastFrame();
});
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
BlinkIdCameraScanningScreen(
onFrameProcessResult = { handle ->
val rawFrame: Bitmap? = handle.getLastFrame()
}
)
```
*/}
```swift
BlinkIDUXView(...)
.onFrameProcessResult { handle in
// Retrieve the last processed camera frame
if let lastFrame = handle.getLastFrame() {
let image: UIImage? = lastFrame.image
let orientation = lastFrame.orientation
}
}
```
## License considerations
Old v7 licenses are **compatible** with v8000.
You don't need to issue new licenses.
## Installation and dependencies
Android now uses Kotlin v2.2.21.
Web and iOS SDK have no new dependencies.
Upgrade by incrementing your SDK version in your build system:
```
npm install @microblink/blinkid@8000.0.0
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
implementation("com.microblink:blinkid-ux:8000.0.0")
```
*/}
In your `Package.swift`, update the version constraint:
```swift
.package(url: "https://github.com/BlinkID/blinkid-ios.git", .upToNextMajor(from: "8000.0.0"))
```
## Session initialization
SDK initialization (`BlinkIDSdk.createBlinkIDSdk` on iOS, `BlinkIdSdk.initializeSdk` on Android, `createBlinkId` on web) is unchanged in v8000.
The `BlinkIdSessionSettings` wrapper structure is also unchanged: it still takes `inputImageSource`, `scanningMode`, and `scanningSettings`.
The `ScanningSettings` within it has been restructured into four sub-modules—see [Changes in scanning settings](#changes-in-scanning-settings) for the full mapping.
### Android: `createScanningSession()` now returns `Result`
`createScanningSession()` previously returned `BlinkIdScanningSession` directly.
In v8000, it returns `Result`.
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
// v7
val session = sdk.createScanningSession(sessionSettings)
// v8000
val session = sdk.createScanningSession(sessionSettings).getOrThrow()
```
*/}
### New inactivity timeout
All platforms now automatically stop scanning after 10 seconds of inactivity—defined as no change in the stabilized UI state (reticle type and on-screen messages).
This is a new behavior: in v7, scanning ran indefinitely unless a per-step timeout fired.
No code changes are required to get this behavior.
If you need to disable the inactivity timeout or adjust the duration:
```typescript
const blinkId = await createBlinkId({
licenseKey: "...",
uxManagerOptions: {
timeoutConfiguration: {
inactivityTimeoutMs: null, // null disables it; or pass a duration in milliseconds
},
},
});
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
BlinkIdCameraScanningScreen(
blinkIdSdk = blinkIdSdk,
uxSettings = BlinkIdUxSettings(
stateBasedTimeoutDuration = Duration.ZERO, // ZERO disables it; or pass a custom Duration
),
// ...
)
```
*/}
```swift
let sessionSettings = BlinkIDSessionSettings(
inactivityTimeoutDuration: 0 // any value ≤ 0 disables it; or pass a custom TimeInterval
)
let analyzer = try await BlinkIDAnalyzer(
sdk: sdk,
blinkIdSessionSettings: sessionSettings
)
```
## Changes in scanning settings
### Structure changes
`ScanningSettings` was a flat object in v7.
In v8000 it is a structured object with four sub-modules.
Some settings in sub-modules have also changed their name.
**v7:**
```typescript
const settings: ScanningSettings = {
blurDetectionLevel: "low",
skipImagesWithBlur: false,
glareDetectionLevel: "low",
skipImagesWithGlare: false,
enableCharacterValidation: false,
scanPassportDataPageOnly: false,
croppedImageSettings: {
returnDocumentImage: true,
returnFaceImage: true,
returnSignatureImage: true,
},
};
```
**v8000:**
```typescript
const settings: ScanningSettings = {
documentCaptureModule: {
blurSensitivityLevel: "low",
imageWithBlurRejected: false,
glareSensitivityLevel: "low",
imageWithGlareRejected: false,
documentImageReturnEnabled: true,
faceImageExtractionEnabled: true,
passportDataPageScanOnly: false,
},
vizModule: {
signatureImageExtractionEnabled: true,
characterValidationEnabled: false,
},
barcodeModule: {},
mrzModule: {},
};
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
**v7:**
```kotlin
val settings = ScanningSettings(
blurDetectionLevel = DetectionLevel.Low,
skipImagesWithBlur = false,
glareDetectionLevel = DetectionLevel.Low,
skipImagesWithGlare = false,
enableCharacterValidation = false,
scanPassportDataPageOnly = false,
croppedImageSettings = CroppedImageSettings(
returnDocumentImage = true,
returnFaceImage = true,
returnSignatureImage = true
)
)
```
**v8000:**
```kotlin
val settings = ScanningSettings(
documentCaptureModule = DocumentCaptureModuleSettings(
blurSensitivityLevel = SensitivityLevel.Low,
imageWithBlurRejected = false,
glareSensitivityLevel = SensitivityLevel.Low,
imageWithGlareRejected = false,
documentImageReturnEnabled = true,
faceImageExtractionEnabled = true,
passportDataPageScanOnly = false,
),
vizModule = VizModuleSettings(
signatureImageExtractionEnabled = true,
characterValidationEnabled = false,
),
barcodeModule = BarcodeModuleSettings(),
mrzModule = MrzModuleSettings()
)
```
*/}
**v7:**
```swift
let settings = ScanningSettings(
blurDetectionLevel: .low,
skipImagesWithBlur: false,
glareDetectionLevel: .low,
skipImagesWithGlare: false,
enableCharacterValidation: false,
scanPassportDataPageOnly: false,
croppedImageSettings: CroppedImageSettings(
returnDocumentImage: true,
returnFaceImage: true,
returnSignatureImage: true
)
)
```
**v8000:**
```swift
let settings = ScanningSettings(
documentCaptureModule: DocumentCaptureModuleSettings(
blurSensitivityLevel: .low,
imageWithBlurRejected: false,
glareSensitivityLevel: .low,
imageWithGlareRejected: false,
documentImageReturnEnabled: true,
faceImageExtractionEnabled: true,
passportDataPageScanOnly: false
),
vizModule: VizModuleSettings(
signatureImageExtractionEnabled: true,
characterValidationEnabled: false
),
barcodeModule: BarcodeModuleSettings(),
mrzModule: MrzModuleSettings()
)
```
### Renamed settings
#### `DetectionLevel` renamed to `SensitivityLevel`
The type used for detection sensitivity thresholds has been renamed from `DetectionLevel` to `SensitivityLevel`.
The values are unchanged: `"off"`, `"low"`, `"mid"`, `"high"`.
These fields have also moved to the `documentCaptureModule` subfield.
- `blurDetectionLevel` is now `documentCaptureModule.blurSensitivityLevel`
- `glareDetectionLevel` is now `documentCaptureModule.glareSensitivityLevel`
- `tiltDetectionLevel` is now `documentCaptureModule.tiltSensitivityLevel`
---
#### `skipImagesWith*` renamed to `imageWith*Rejected`
These fields have also moved to the `documentCaptureModule` subfield.
- `skipImagesWithBlur` is now `documentCaptureModule.imageWithBlurRejected`
- `skipImagesWithGlare` is now `documentCaptureModule.imageWithGlareRejected`
- `skipImagesWithInadequateLightingConditions` is now `documentCaptureModule.imageWithPoorLightingRejected`
- `skipImagesOccludedByHand` is now `documentCaptureModule.imageWithHandOcclusionRejected`
---
#### `croppedImageSettings` have moved to `documentCaptureModule`
- `croppedImageSettings.dotsPerInch` is now `documentCaptureModule.dotsPerInch`
- `croppedImageSettings.extensionFactor` is now `documentCaptureModule.extensionFactor`
And these have additionally been **renamed** as well:
- `croppedImageSettings.returnDocumentImage` is now `documentCaptureModule.documentImageReturnEnabled`
- `croppedImageSettings.returnFaceImage` is now `documentCaptureModule.faceImageExtractionEnabled`
- `croppedImageSettings.returnSignatureImage` is now `vizModule.signatureImageExtractionEnabled`
---
#### Other renaming
- `combineResultsFromMultipleInputImages` is now `vizModule.resultAggregationEnabled`
- `returnInputImages` is now `documentCaptureModule.inputImageReturnEnabled`
- `scanCroppedDocumentImage` is now `documentCaptureModule.inputImageCropped`
- `inputImageMargin` is now `documentCaptureModule.inputImageMargin`
- `allowUncertainFrontSideScan` is now `documentCaptureModule.unsupportedDocumentsAllowed`
- `scanUnsupportedBack` is now `documentCaptureModule.secondSideWithNoExtractableDataSkipped`
- `scanPassportDataPageOnly` is now `documentCaptureModule.passportDataPageScanOnly`
- `enableCharacterValidation` is now `vizModule.characterValidationEnabled`
---
### Removed settings
- `CroppedImageSettings` type and `croppedImageSettings` property: image return and quality settings are now part of `documentCaptureModule` and `vizModule` (see renamed settings above)
- `RecognitionModeFilter` type and `recognitionModeFilter` property: use the per-module disable mechanism instead (see [New settings](#new-settings))
- `enableBarcodeScanOnly`: replaced by the per-module disable mechanism; to scan barcodes only, disable `mrzModule` and `vizModule` (see [New settings](#new-settings) for how to disable a module per platform)
- `customDocumentRules`: replaced by per-frame result completeness checks (see [Removal of custom document rules](#removal-of-custom-document-rules))
- `anonymizationMode` and `customDocumentAnonymizationSettings`: moved to the `getResult()` call (see [Changes in anonymization](#changes-in-anonymization))
### New settings
New fields in `documentCaptureModule`:
- `faceImagePresenceMandatory`: requires a face image to be detected for a result to be considered complete
New fields in `barcodeModule`:
- `presenceMandatory`: requires a barcode to be present for a result to be considered complete
- `barcodeImageReturnEnabled`: returns the input image frame that contained the successfully scanned barcode
- Individual symbology toggles: `pdf417ScanningEnabled`, `qrScanningEnabled`, `upceScanningEnabled`, `upcaScanningEnabled`, `code128ScanningEnabled`, `code39ScanningEnabled`, `ean8ScanningEnabled`, `ean13ScanningEnabled`, `itfScanningEnabled`, `dataMatrixScanningEnabled`
New fields in `mrzModule`:
- `presenceMandatory`: requires an MRZ to be present for a result to be considered complete
New fields in `vizModule`:
- `presenceMandatory`: requires VIZ data to be present for a result to be considered complete
## Changes in the result
### Renamed fields
In `SingleSideScanningResult`, `barcodeInputImage` has changed to `barcodeImage`.
**v7:**
```typescript
const barcodeImg = result.subResults[0].barcodeInputImage;
```
**v8000:**
```typescript
const barcodeImg = result.subResults[0].barcodeImage;
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
**v7:**
```kotlin
val barcodeImg = result.subResults[0].barcodeInputImage
```
**v8000:**
```kotlin
val barcodeImg = result.subResults[0].barcodeImage
```
*/}
**v7:**
```swift
let barcodeImg = result.subResults[0].barcodeInputImage
```
**v8000:**
```swift
let barcodeImg = result.subResults[0].barcodeImage
```
### Removed fields
The recognition mode is no longer exposed in the result: `mode` (web, Android), `recognitionMode` (iOS).
### New processing status values
Three new values have been added in `ProcessingStatus`:
- `"mrz-detection-failed"` / `MrzDetectionFailed` / `.mrzDetectionFailed`: the MRZ was not detected on the image
- `"input-image-not-focused"` / `InputImageNotFocused` / `.inputImageNotFocused`: the input image was not focused
- `"canceled"` / `Canceled` / `.canceled`: scanning was canceled
## Migrating from BlinkID Capture
If you were using BlinkID Capture, switch to BlinkID v8000 and enable only the `documentCaptureModule`.
Disable the other modules by setting them to `null` (web, Android) or `nil` (iOS).
```typescript
const settings: ScanningSettings = {
documentCaptureModule: {},
mrzModule: null,
vizModule: null,
barcodeModule: null,
};
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
val settings = ScanningSettings(
documentCaptureModule = DocumentCaptureModuleSettings(),
mrzModule = null,
vizModule = null,
barcodeModule = null,
)
```
*/}
```swift
let settings = ScanningSettings(
documentCaptureModule: DocumentCaptureModuleSettings(),
mrzModule: nil,
barcodeModule: nil,
vizModule: nil
)
```
## Migrating from PDF417
If you were using BlinkID PDF417, switch to BlinkID v8000 and enable only the `barcodeModule` with PDF417 scanning enabled.
Disable the other modules by setting them to `null` (web, Android) or `nil` (iOS).
```typescript
const settings: ScanningSettings = {
documentCaptureModule: null,
mrzModule: null,
vizModule: null,
barcodeModule: {
pdf417ScanningEnabled: true,
},
};
```
:::note
Android v8000 is not yet released.
This sample will be added when it becomes available.
:::
{/*
```kotlin
val settings = ScanningSettings(
documentCaptureModule = null,
mrzModule = null,
vizModule = null,
barcodeModule = BarcodeModuleSettings(
pdf417ScanningEnabled = true,
)
)
```
*/}
```swift
let settings = ScanningSettings(
documentCaptureModule: nil,
mrzModule: nil,
barcodeModule: BarcodeModuleSettings(
pdf417ScanningEnabled: true
),
vizModule: nil
)
```
Last updated on May 27, 2026