Migrate to v8000
This guide describes how to upgrade the BlinkID SDK from v7 to v8000.
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 to find out what else is new.
Also note that not all platforms expose the same functionality. More on that in How the SDK works.
Versioning change
Starting with v8000, BlinkID adopts the epoch versioning scheme.
{EPOCH * 1000 + MAJOR}.MINOR.PATCHEPOCH: 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:
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
v7 (flat object):
const settings: ScanningSettings = {
blurDetectionLevel: "low",
skipImagesWithBlur: false,
croppedImageSettings: {
returnFaceImage: true,
dotsPerInch: 300,
},
// ...
};
v8000 (modularized):
const settings: ScanningSettings = {
documentCaptureModule: {
blurSensitivityLevel: "low",
imageWithBlurRejected: false,
faceImageExtractionEnabled: true,
dotsPerInch: 300,
},
vizModule: {},
barcodeModule: {},
mrzModule: {},
// ...
};
v7 (flat object):
val settings = ScanningSettings(
blurDetectionLevel = DetectionLevel.Low,
skipImagesWithBlur = false,
croppedImageSettings = CroppedImageSettings(
returnFaceImage = true,
dotsPerInch = 300,
),
// ...
)
v8000 (modularized):
val settings = ScanningSettings(
documentCaptureModule = DocumentCaptureModuleSettings(
blurSensitivityLevel = SensitivityLevel.Low,
imageWithBlurRejected = false,
faceImageExtractionEnabled = true,
dotsPerInch = 300,
),
barcodeModule = BarcodeModuleSettings(),
mrzModule = MrzModuleSettings(),
vizModule = VizModuleSettings(),
)
v7 (flat object):
let settings = ScanningSettings(
blurDetectionLevel: .low,
skipImagesWithBlur: false,
croppedImageSettings: CroppedImageSettings(
returnFaceImage: true,
dotsPerInch: 300
),
// ...
)
v8000 (modularized):
let settings = ScanningSettings(
documentCaptureModule: DocumentCaptureModuleSettings(
blurSensitivityLevel: .low,
imageWithBlurRejected: false,
faceImageExtractionEnabled: true,
dotsPerInch: 300
),
vizModule: VizModuleSettings(),
barcodeModule: BarcodeModuleSettings(),
mrzModule: MrzModuleSettings()
)
v7 (flat object):
const settings = new BlinkIdScanningSettings();
settings.blurDetectionLevel = DetectionLevel.Low;
settings.skipImagesWithBlur = false;
settings.croppedImageSettings.returnFaceImage = true;
settings.croppedImageSettings.dotsPerInch = 300;
// ...
v8000 (modularized):
const settings: BlinkIdScanningSettings = {
documentCaptureModule: {
blurSensitivityLevel: "low",
imageWithBlurRejected: false,
faceImageExtractionEnabled: true,
dotsPerInch: 300,
},
vizModule: {},
barcodeModule: {},
mrzModule: {},
// ...
};
v7 (flat object):
final settings = BlinkIdScanningSettings();
settings.blurDetectionLevel = DetectionLevel.low;
settings.skipImagesWithBlur = false;
settings.croppedImageSettings.returnFaceImage = true;
settings.croppedImageSettings.dotsPerInch = 300;
// ...
v8000 (modularized):
final settings = BlinkIdScanningSettings(
documentCaptureModule: DocumentCaptureModuleSettings(
blurSensitivityLevel: SensitivityLevel.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, 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.
Inspecting result completeness in v7
The scanning session exposed a per-frame process method that returned a result completeness object for each frame you feed it.
In v7, that object was a flat set of boolean flags:
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
// v7
const session = await blinkIdCore.createScanningSession();
const frameResult = await session.process(image);
const completeness = frameResult.resultCompleteness;
if (completeness.mrzExtracted) {
// MRZ data is available
}
if (!completeness.faceImageExtracted) {
// face image wasn't captured
}
// v7
val processResult = session.process(image).getOrNull() ?: return
val completeness = processResult.resultCompleteness
if (completeness.mrzExtracted) {
// MRZ data is available
}
if (!completeness.faceImageExtracted) {
// face image wasn't captured
}
// v7
let frameResult = try await session.process(inputImage: capturedImage)
guard let completeness = frameResult.processResult?.resultCompleteness else { return }
if completeness.mrzExtracted {
// MRZ data is available
}
if !completeness.faceImageExtracted {
// face image wasn't captured
}
The core session API in v8000
In v8000, you can still call process for each frame.
What changed is the result completeness object it returns, which now provides detailed per-module status, including why extraction failed:
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
// v8000
const session = await blinkIdCore.createScanningSession();
const frameResult = await session.process(image);
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
}
// v8000
val processResult = session.process(image).getOrNull() ?: return
val completeness = 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
}
// v8000
let frameResult = try await session.process(inputImage: capturedImage)
guard let completeness = frameResult.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
}
The same logic through the UX package in v8000
The same per-frame result completeness is now available using the UX package.
On web, the UX manager already exposed a frame-process callback in v7, but in v8000 that callback also receives helpers to advance the flow, trigger a timeout, and retrieve the last frame (see Scan progression has changed). On Android and iOS, the camera-scanning UI now exposes an equivalent per-frame callback.
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
// 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
}
});
// v8000
BlinkIdCameraScanningScreen(
blinkIdSdk = blinkIdSdk,
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
}
}
)
// 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.
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
v7:
// 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:
// 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();
}
});
v7:
// 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:
// Check per-frame whether the fields you need have been extracted
BlinkIdCameraScanningScreen(
blinkIdSdk = blinkIdSdk,
onFrameProcessResult = { handle ->
val analysis = handle.processResult.inputImageAnalysisResult
if (analysis.documentClassInfo.country == Country.Croatia &&
analysis.documentClassInfo.type == Type.Id &&
analysis.extractedFields.contains(FieldType.FirstName) &&
analysis.extractedFields.contains(FieldType.LastName)
) {
handle.advanceToNextStep()
}
}
)
v7:
// 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:
// 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.
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
v7:
// 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:
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
},
});
v7:
// 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:
// Redaction is configured via a resolver that must be Parcelable
@Parcelize
class CroatiaIdRedactionResolver : RedactionSettingsResolver {
override fun resolveRedactionSettings(classInfo: DocumentClassInfo): RedactionSettings? {
if (classInfo.country == Country.Croatia && classInfo.type == Type.Id) {
return RedactionSettings(
redactionMode = RedactionMode.FullResult,
fields = listOf(FieldType.Sex, FieldType.DateOfBirth),
documentNumberRedactionSettings = DocumentNumberRedactionSettings(
prefixDigitsVisible = 0U,
suffixDigitsVisible = 2U
)
)
}
return null // use SDK defaults for other documents
}
}
BlinkIdCameraScanningScreen(
blinkIdSdk = blinkIdSdk,
uxSettings = BlinkIdUxSettings(
redactionSettingsResolver = CroatiaIdRedactionResolver()
),
// ...
)
v7:
// 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:
// 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()
)
v7:
// Per-document anonymization configured in scanning settings
const settings = new BlinkIdScanningSettings();
settings.anonymizationMode = AnonymizationMode.FullResult;
settings.customDocumentAnonymizationSettings = [
new DocumentAnonymizationSettings(
[FieldType.DocumentNumber, FieldType.Sex, FieldType.DateOfBirth],
new DocumentFilter(Country.Croatia, undefined, DocumentType.Id),
new DocumentNumberAnonymizationSettings(0, 2),
),
];
v8000:
// Redaction configured via a resolver passed to performScan
const redactionSettingsResolver: RedactionSettingsResolver = {
documentRedactionList: [
{
mode: "fullResult",
fields: [FieldType.Sex, FieldType.DateOfBirth],
documentNumberRedactionSettings: {
prefixDigitsVisible: 0,
suffixDigitsVisible: 2,
},
redactMrzResult: false,
redactBarcodeResult: false,
documentFilter: {
country: Country.Croatia,
documentType: DocumentType.Id,
},
},
],
};
await performScan({ sdkSettings, sessionSettings, redactionSettingsResolver });
v7:
// Per-document anonymization configured in scanning settings
final settings = BlinkIdScanningSettings();
settings.anonymizationMode = AnonymizationMode.fullResult;
settings.customDocumentAnonymizationSettings = [
DocumentAnonymizationSettings(
[FieldType.documentNumber, FieldType.sex, FieldType.dateOfBirth],
DocumentFilter(Country.croatia, null, DocumentType.id),
DocumentNumberAnonymizationSettings(prefixDigitsVisible: 0, suffixDigitsVisible: 2),
),
];
v8000:
// Redaction configured via a resolver passed to performScan
final redactionSettingsResolver = RedactionSettingsResolver([
RedactionSettings(
mode: RedactionMode.fullResult,
fields: [FieldType.sex, FieldType.dateOfBirth],
documentNumberRedactionSettings: DocumentNumberRedactionSettings(
prefixDigitsVisible: 0,
suffixDigitsVisible: 2,
),
documentFilter: [
DocumentFilter(
country: Country.croatia,
documentType: DocumentType.id,
),
],
),
]);
await blinkIdPlugin.performScan(
blinkIdSdkSettings: sdkSettings,
blinkIdSessionSettings: sessionSettings,
redactionSettingsResolver: redactionSettingsResolver,
);
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.
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 above.
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
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
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}});BlinkIdCameraScanningScreen(blinkIdSdk = blinkIdSdk,onFrameProcessResult = { handle ->val completeness = handle.processResult.resultCompletenessif (completeness.mrz?.status == ExtractionStatus.Extracted) {// MRZ extraction succeeded}if (completeness.faceImage?.failureReason == ExtractionFailureReason.Detection) {// Face was not detected on the document}})BlinkIDUXView(...).onFrameProcessResult { handle inguard 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
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
blinkIdUxManager.addOnFrameProcessCallback(async (frameResult, advanceToNextStep) => {// Explicitly advance the session to the next step when your criteria are metawait advanceToNextStep();});BlinkIdCameraScanningScreen(blinkIdSdk = blinkIdSdk,onFrameProcessResult = { handle ->// Explicitly advance the session to the next step when your criteria are methandle.advanceToNextStep()})BlinkIDUXView(...).onFrameProcessResult { handle in// Explicitly advance the session to the next stepawait handle.advanceToNextStep()} -
retrieve the raw frames
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
blinkIdUxManager.addOnFrameProcessCallback((frameResult, advanceToNextStep, triggerTimeout, getLastFrame) => {const rawFrame: ArrayBuffer = getLastFrame();});BlinkIdCameraScanningScreen(blinkIdSdk = blinkIdSdk,onFrameProcessResult = { handle ->val lastFrame = handle.getLastFrame()})BlinkIDUXView(...).onFrameProcessResult { handle in// Retrieve the last processed camera frameif let lastFrame = handle.getLastFrame() {let image: UIImage? = lastFrame.imagelet 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:
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
npm install @microblink/blinkid@8000.0.0
Or for core-only usage:
npm install @microblink/blinkid-core@8000.0.0
implementation("com.microblink:blinkid-ux:8000.0.0")
Or for core-only usage:
implementation("com.microblink:blinkid-core:8000.0.0")
In your Package.swift, update the version constraint:
.package(url: "https://github.com/BlinkID/blinkid-ios.git", .upToNextMajor(from: "8000.0.0"))
npm install @microblink/blinkid-react-native@8000.0.0
In your pubspec.yaml, update the version constraint:
dependencies:
blinkid_flutter: 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 for the full mapping.
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:
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
const blinkId = await createBlinkId({
licenseKey: "...",
uxManagerOptions: {
timeoutConfiguration: {
inactivityTimeoutMs: null, // null disables it; or pass a duration in milliseconds
},
},
});
BlinkIdCameraScanningScreen(
blinkIdSdk = blinkIdSdk,
uxSettings = BlinkIdUxSettings(
inactivityTimeoutDuration = Duration.ZERO, // ZERO disables it; or pass a custom Duration
),
// ...
)
let sessionSettings = BlinkIDSessionSettings(
inactivityTimeoutDuration: 0 // any value ≤ 0 disables it; or pass a custom TimeInterval
)
let analyzer = try await BlinkIDAnalyzer(
sdk: sdk,
blinkIdSessionSettings: sessionSettings
)
const sessionSettings: BlinkIdSessionSettings = {
inactivityTimeoutDuration: 0, // 0 or any value ≤ 0 disables it; or pass a duration in milliseconds
};
final sessionSettings = BlinkIdSessionSettings(
inactivityTimeoutDuration: 0, // 0 or any value ≤ 0 disables it; or pass a duration in milliseconds
);
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.
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
v7:
const settings: ScanningSettings = {
blurDetectionLevel: "low",
skipImagesWithBlur: false,
glareDetectionLevel: "low",
skipImagesWithGlare: false,
enableCharacterValidation: false,
scanPassportDataPageOnly: false,
croppedImageSettings: {
returnDocumentImage: true,
returnFaceImage: true,
returnSignatureImage: true,
},
};
v8000:
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: {},
};
v7:
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:
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:
let settings = ScanningSettings(
blurDetectionLevel: .low,
skipImagesWithBlur: false,
glareDetectionLevel: .low,
skipImagesWithGlare: false,
enableCharacterValidation: false,
scanPassportDataPageOnly: false,
croppedImageSettings: CroppedImageSettings(
returnDocumentImage: true,
returnFaceImage: true,
returnSignatureImage: true
)
)
v8000:
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()
)
v7:
const settings = new BlinkIdScanningSettings();
settings.blurDetectionLevel = DetectionLevel.Low;
settings.skipImagesWithBlur = false;
settings.glareDetectionLevel = DetectionLevel.Low;
settings.skipImagesWithGlare = false;
settings.enableCharacterValidation = false;
settings.scanPassportDataPageOnly = false;
settings.croppedImageSettings.returnDocumentImage = true;
settings.croppedImageSettings.returnFaceImage = true;
settings.croppedImageSettings.returnSignatureImage = true;
v8000:
const settings: BlinkIdScanningSettings = {
documentCaptureModule: {
blurSensitivityLevel: "low",
imageWithBlurRejected: false,
glareSensitivityLevel: "low",
imageWithGlareRejected: false,
documentImageReturnEnabled: true,
faceImageExtractionEnabled: true,
passportDataPageScanOnly: false,
},
vizModule: {
signatureImageExtractionEnabled: true,
characterValidationEnabled: false,
},
barcodeModule: {},
mrzModule: {},
};
v7:
final settings = BlinkIdScanningSettings();
settings.blurDetectionLevel = DetectionLevel.low;
settings.skipImagesWithBlur = false;
settings.glareDetectionLevel = DetectionLevel.low;
settings.skipImagesWithGlare = false;
settings.enableCharacterValidation = false;
settings.scanPassportDataPageOnly = false;
settings.croppedImageSettings.returnDocumentImage = true;
settings.croppedImageSettings.returnFaceImage = true;
settings.croppedImageSettings.returnSignatureImage = true;
v8000:
final settings = BlinkIdScanningSettings(
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(),
);
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.
blurDetectionLevelis nowdocumentCaptureModule.blurSensitivityLevelglareDetectionLevelis nowdocumentCaptureModule.glareSensitivityLeveltiltDetectionLevelis nowdocumentCaptureModule.tiltSensitivityLevel
skipImagesWith* renamed to imageWith*Rejected
These fields have also moved to the documentCaptureModule subfield.
skipImagesWithBluris nowdocumentCaptureModule.imageWithBlurRejectedskipImagesWithGlareis nowdocumentCaptureModule.imageWithGlareRejectedskipImagesWithInadequateLightingConditionsis nowdocumentCaptureModule.imageWithPoorLightingRejectedskipImagesOccludedByHandis nowdocumentCaptureModule.imageWithHandOcclusionRejected
croppedImageSettings have moved to documentCaptureModule
croppedImageSettings.dotsPerInchis nowdocumentCaptureModule.dotsPerInchcroppedImageSettings.extensionFactoris nowdocumentCaptureModule.extensionFactor
And these have additionally been renamed as well:
croppedImageSettings.returnDocumentImageis nowdocumentCaptureModule.documentImageReturnEnabledcroppedImageSettings.returnFaceImageis nowdocumentCaptureModule.faceImageExtractionEnabledcroppedImageSettings.returnSignatureImageis nowvizModule.signatureImageExtractionEnabled
Other renaming
combineResultsFromMultipleInputImagesis nowvizModule.resultAggregationEnabledreturnInputImagesis nowdocumentCaptureModule.inputImageReturnEnabledscanCroppedDocumentImageis nowdocumentCaptureModule.inputImageCroppedinputImageMarginis nowdocumentCaptureModule.inputImageMarginallowUncertainFrontSideScanis nowdocumentCaptureModule.unsupportedDocumentsAllowedscanUnsupportedBackis nowdocumentCaptureModule.secondSideWithNoExtractableDataSkippedscanPassportDataPageOnlyis nowdocumentCaptureModule.passportDataPageScanOnlyenableCharacterValidationis nowvizModule.characterValidationEnabled
Removed settings
CroppedImageSettingstype andcroppedImageSettingsproperty: image return and quality settings are now part ofdocumentCaptureModuleandvizModule(see renamed settings above)RecognitionModeFiltertype andrecognitionModeFilterproperty: use the per-module disable mechanism instead (see New settings)enableBarcodeScanOnly: replaced by the per-module disable mechanism; to scan barcodes only, disablemrzModuleandvizModule(see New settings for how to disable a module per platform)customDocumentRules: replaced by per-frame result completeness checks (see Removal of custom document rules)anonymizationModeandcustomDocumentAnonymizationSettings: replaced by a redaction settings resolver (see 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 completebarcodeImageReturnEnabled: 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.
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
v7:
const barcodeImg = result.subResults[0].barcodeInputImage;
v8000:
const barcodeImg = result.subResults[0].barcodeImage;
v7:
val barcodeImg = result.subResults[0].barcodeInputImage
v8000:
val barcodeImg = result.subResults[0].barcodeImage
v7:
let barcodeImg = result.subResults[0].barcodeInputImage
v8000:
let barcodeImg = result.subResults[0].barcodeImage
v7:
const barcodeImg = result.subResults[0].barcodeInputImage;
v8000:
const barcodeImg = result.subResults[0].barcodeImage;
The property name is unchanged in Flutter — both v7 and v8000 expose barcodeInputImage on SingleSideScanningResult.
final barcodeImg = result.subResults[0].barcodeInputImage;
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).
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
const settings: ScanningSettings = {
documentCaptureModule: {},
mrzModule: null,
vizModule: null,
barcodeModule: null,
};
val settings = ScanningSettings(
documentCaptureModule = DocumentCaptureModuleSettings(),
mrzModule = null,
vizModule = null,
barcodeModule = null,
)
let settings = ScanningSettings(
documentCaptureModule: DocumentCaptureModuleSettings(),
mrzModule: nil,
barcodeModule: nil,
vizModule: nil
)
const settings: BlinkIdScanningSettings = {
documentCaptureModule: {},
};
final settings = BlinkIdScanningSettings(
documentCaptureModule: DocumentCaptureModuleSettings(),
mrzModule: null,
barcodeModule: null,
vizModule: null,
);
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).
- Web (TS)
- Android (Kotlin)
- iOS (Swift)
- React Native (TS)
- Flutter (Dart)
const settings: ScanningSettings = {
documentCaptureModule: null,
mrzModule: null,
vizModule: null,
barcodeModule: {
pdf417ScanningEnabled: true,
},
};
val settings = ScanningSettings(
documentCaptureModule = null,
mrzModule = null,
vizModule = null,
barcodeModule = BarcodeModuleSettings(
pdf417ScanningEnabled = true,
)
)
let settings = ScanningSettings(
documentCaptureModule: nil,
mrzModule: nil,
barcodeModule: BarcodeModuleSettings(
pdf417ScanningEnabled: true
),
vizModule: nil
)
const settings: BlinkIdScanningSettings = {
barcodeModule: {
pdf417ScanningEnabled: true,
},
};
final settings = BlinkIdScanningSettings(
documentCaptureModule: null,
mrzModule: null,
barcodeModule: BarcodeModuleSettings(
pdf417ScanningEnabled: true,
),
vizModule: null,
);