KYC Docs Get credentials
Docs › Blink SDK › Customisation

Customisation

Make the capture screens feel like your product: brand colours, your own wording, Arabic or English, or your own screens entirely.

Brand colours

PlatformTheme
AndroidBlinkTheme(accent, background, text, onAccent) — ARGB ints
iOSBlinkTheme(accent:)
Webtheme: { accent, background } — CSS colours
React Nativetheme: { accent, background, text, onAccent } — ARGB numbers such as 0xff15803d
Fluttertheme: BlinkTheme(accent:, background:, text:, onAccent:) — Color values
VerifyActivity.ktkotlin
val config = BlinkConfig.builder(sessionToken)
    .theme(BlinkTheme.builder()
        .accent(0xFF15803D.toInt())
        .background(0xFF0E1E4D.toInt())
        .text(0xFFFFFFFF.toInt())
        .buttonCornerRadius(12f)
        .brandName("Your Bank")
        .privacyPolicyUrl("https://yourbank.com/privacy")
        .build())
    .build()

Accent colours sit on a dark camera stage, so a bright brand colour usually reads well there even if it is too light for text on white.

Every element

Beyond the brand colours, each part of the capture screens can be set on its own. Every field below is optional and keeps the built-in look when you leave it out. Requires Android blink-kyc-android 1.0.9 or iOS BlinkKyc 1.0.10, and 1.0.11 of the Flutter and React Native packages, which pass the same fields through to the native screens.

FieldChanges
titleColor, titleTextSizeScreen titles. Help-page titles are drawn a third larger.
helperTextColor, helperTextSizeCamera instructions and help-page descriptions.
helperBackgroundColorA rounded background behind the live camera instruction.
secondaryButtonColor, secondaryButtonTextColorRetake, Change selection and other secondary buttons.
buttonTextSizeEvery button label, including Capture.
buttonPositionButtons pinned to the bottom, or directly below the content, on help and message screens. Unset keeps each screen's own placement.
guideColor, guideSuccessColorThe document frame and face oval while searching, and once placed correctly.
scrimColor, scrimOpacityThe dimmed area outside the document frame and the face oval: its colour, and how see-through it is from 0 (clear) to 1 (opaque). Black at 0.6 unless set. The colour's own alpha is ignored.
instructionPosition, livenessInstructionPositionInstruction at the top, middle or bottom — set separately for the ID camera and the face camera.
logoShown in the capture screens' top bar instead of brandName.
documentHelpImage, documentBackHelpImage, livenessHelpImage, nfcHelpImageYour own illustrations for the ID, back-of-ID, face and chip screens.

Images

On Android an image is BlinkImage.resource(R.drawable.…) or BlinkImage.file(path); on iOS it is BlinkImage.resource("AssetName") or BlinkImage.file(path). They are loaded before the camera opens, so a missing image fails the session with BLINK_CONFIG rather than being silently skipped.

VerifyActivity.ktkotlin
val theme = BlinkTheme.builder()
    .titleColor(0xFFFFFFFF.toInt())
    .helperTextColor(0xFFE2E8F0.toInt())
    .helperBackgroundColor(0x99000000.toInt())
    .guideSuccessColor(0xFF22C55E.toInt())
    .buttonPosition(BlinkButtonPosition.BELOW_CONTENT)
    .livenessInstructionPosition(BlinkInstructionPosition.TOP)
    .logo(BlinkImage.resource(R.drawable.bank_logo))
    .livenessHelpImage(BlinkImage.resource(R.drawable.kyc_face_help))
    .build()
VerifyViewController.swiftswift
let theme = BlinkTheme.builder()
    .titleColor(0xFFFFFFFF)
    .helperTextColor(0xFFE2E8F0)
    .helperBackgroundColor(0x99000000)
    .guideSuccessColor(0xFF22C55E)
    .buttonPosition(.belowContent)
    .livenessInstructionPosition(.top)
    .logo(BlinkImage.resource("BankLogo"))
    .livenessHelpImage(BlinkImage.resource("FaceHelp"))
    .build()

Android, iOS, React Native and Flutter use the same field names, so one theme reads the same on all four. The Web SDK keeps its existing accent and background options.

React Native and Flutter

From 1.0.11 both packages take a theme in BlinkConfig and hand it to the native screens. Every theme field on this page is available; leave one out and the native default applies.

VerifyScreen.tsxtypescript
await BlinkKyc.present({
  sessionToken,
  theme: {
    accent: 0xff15803d,                // colours are ARGB numbers
    scrimColor: 0xff0e1e4d,
    scrimOpacity: 0.35,
    buttonPosition: 'BELOW_CONTENT',   // or 'BOTTOM'
    livenessInstructionPosition: 'TOP',
    logo: { resource: 'bank_logo' },
    introColor: 0xff0f766e,
  },
});
lib/kyc.dartdart
await BlinkKyc.present(BlinkConfig(
  sessionToken: sessionToken,
  theme: const BlinkTheme(
    accent: Color(0xFF15803D),
    scrimColor: Color(0xFF0E1E4D),
    scrimOpacity: 0.35,
    buttonPosition: BlinkButtonPosition.belowContent,
    livenessInstructionPosition: BlinkInstructionPosition.top,
    logo: BlinkImage.asset('assets/bank_logo.png'),
    introColor: Color(0xFF0F766E),
  ),
));
PackageImages
React Native{ resource: 'name' } — an Android drawable or an iOS asset-catalogue image of your app — or { file: '/path/to/image.png' }
FlutterBlinkImage.asset('assets/…') for an asset declared in pubspec.yaml, BlinkImage.resource('name') or BlinkImage.file(path)

An invalid value, such as a scrimOpacity above 1 or an image that cannot be found, fails the call with BLINK_CONFIG before the camera opens.

Opening page and document camera

The page before the camera ("Scan your passport") and the document camera itself have their own fields. Unset, the opening page is white with dark blue (#143A68) and light blue, and the camera's frame is a grey dashed line that turns solid green once the document is in place. Requires Android blink-kyc-android 1.0.10 or iOS BlinkKyc 1.0.10, and 1.0.11 of the Flutter and React Native packages.

FieldChanges
introColorThe opening page's button, progress bar, step label, checklist numbers and artwork, and the camera's document pill and Capture button. The light tints behind the artwork, the numbers and the selfie card are made from it (same hue, fixed lightness), so they follow it automatically. The button text turns dark on a light colour.
introBackgroundThe opening page's background and the camera's bottom sheet (white).
introTitleColor, introTextColorHeadings, and the subtitle and checklist text, on both.
introIconYour own icon in the opening page's tile instead of the built-in passport or ID card.
guideColor, guideSuccessColorThe camera frame while searching (grey dashes) and once ready (green).
documentGuideArttrue draws the illustrated passport / ID card guide inside the frame instead of the plain frame. Off by default.
VerifyActivity.javajava
BlinkConfig config = BlinkConfig.builder(sessionToken)
        .theme(BlinkTheme.builder()
                .introColor(0xFF0F766E)
                .introBackground(0xFFF8FAFC)
                .introIcon(BlinkImage.resource(R.drawable.bank_logo))
                .guideSuccessColor(0xFF22C55E)
                .build())
        .build();
VerifyViewController.swiftswift
let config = try BlinkConfig.builder(sessionToken)
    .theme(BlinkTheme.builder()
        .introColor(0xFF0F766E)
        .introBackground(0xFFF8FAFC)
        .introIcon(BlinkImage.resource("BankLogo"))
        .guideSuccessColor(0xFF22C55E)
        .build())
    .build()

The opening page keeps Start scanning disabled until the camera is allowed: a card above it asks for the camera, and offers Open settings once the customer has refused it for good. On the document camera, instructionPosition no longer moves the guidance: it sits under the frame. The selfie camera still follows livenessInstructionPosition.

Their wording

Every line is a BlinkStrings field, in English and Arabic:

ScreenFields
Opening pageintroEyebrow, introStep ({step} of {total}), documentTitle, documentSubtitle, documentChecklistTitle, documentTip1Title…documentTip3Title with documentTip1…documentTip3, journeySelfieTitle, journeySelfieNote, documentStartButton
Camera permission cardcameraAccessTitle, cameraAccessBody, cameraDeniedBody, cameraAllowButton, cameraSettingsButton
Document cameracaptureTitle, capturePassport, captureIdCard, captureDataPage (with frontSideTitle / backSideTitle for cards), captureWaiting, captureDetected, captureHintDataPage / captureHintFront / captureHintBack, capturedHintDataPage / capturedHintFront / capturedHintBack, captureDocumentButton

From 1.0.13 the document camera's guidance (the captureHint… and capturedHint… lines, and its messages about light, fingers and glare) shows in the white sheet above the Capture button. The sheet's former heading and tip, captureSheetDataPage, captureSheetFront, captureSheetBack and captureSheetBody, are no longer shown; setting them is harmless.

Text & language

On Android and iOS every piece of customer-facing copy can be replaced with BlinkStrings, starting from Blink's English or Arabic and changing only the fields you need. From 1.0.12 that includes the selfie's faceCoveredPrompt (“Keep your whole face uncovered”) and faceSunglassesPrompt (“Take off your sunglasses”).

VerifyActivity.ktkotlin
val strings = BlinkStrings.english().toBuilder()
    .documentTitle("Verify your identity")
    .captureButton("Take photo")
    .build()
val config = BlinkConfig.builder(sessionToken).strings(strings).build()
VerifyViewController.swiftswift
let strings = BlinkStrings.english().toBuilder()
    .documentTitle("Verify your identity")
    .captureButton("Take photo")
    .build()
let config = try BlinkConfig.builder(sessionToken).strings(strings).build()

For Blink's complete built-in Arabic copy, with right-to-left screens, set the locale to ar: .locale("ar") on the Android and iOS builders, or locale: 'ar' in the Flutter and React Native BlinkConfig. English is the default. The Flutter and React Native packages cannot replace individual sentences yet. Hosted links default to Arabic unless the link carries lang=en.

Your own screens

To design every screen yourself, let the SDK tell you what to capture and hand it the bytes. Blink still issues the challenges, receives the upload and decides.

PlatformHow
Android.capture(CaptureHooks) — see Headless capture.
iOS.capture(CaptureHooks) — see Headless capture.
Web.capture({ document, liveness }) — see Headless capture.

The Flutter and React Native packages always run the built-in screens.

The built-in screens capture better. They guide the customer, check sharpness, glare and framing, and only take the photo when it is usable. Your own screens should do the same, or expect more DOCUMENT_UNREADABLE outcomes.

Dark mode

The capture screens use a dark camera stage in both system themes, set by background. The rest of your app is unaffected.