--- 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