Last updated
Last updated
# Liveness Workflow — Init Configuration
```js
VidaSDK.init({
/* ═══════════════════════════════════════════════════
* REQUIRED
* ═══════════════════════════════════════════════════ */
// Your JWT Token
token: '<your-token>',
// Your Signing Key
signingKey: '<your-signing-key>',
/* ═══════════════════════════════════════════════════
* GENERAL
* ═══════════════════════════════════════════════════ */
// DOM element ID where SDK renders. Element must exist in the DOM. Optional
elementId: 'root',
// Workflow type. Defaults to 'liveness'
workflow: 'liveness',
// UI language. Options: 'EN' | 'ID'
locale: 'EN',
// User context for fraud detection. userInfo.id is required if device fraud shield is enabled.
userInfo: { id: 'user-123' },
// Partner's transaction ID for tracking.
partnerTransactionId: '',
// Client ID to enable device fraud detection. If set, userInfo.id becomes required.
fraudShieldClientId: '',
/* ═══════════════════════════════════════════════════
* UI VISIBILITY
* ═══════════════════════════════════════════════════ */
// Hide the session ID display.
hideSessionId: false,
// Hide the network status offline alert.
hideNetworkStatusAlert: false,
/* ═══════════════════════════════════════════════════
* CALLBACKS
* ═══════════════════════════════════════════════════ */
// Called when liveness verification completes successfully.
onComplete: (data) => console.log('onComplete', data),
// Called when liveness verification fails.
onError: (data) => console.log('onError', data),
// Called when a selfie is captured. Receives base64 image string.
onSelfieCapture: (image) => console.log('onSelfieCapture', image),
/* ═══════════════════════════════════════════════════
* WORKFLOW CONFIGS
* ═══════════════════════════════════════════════════ */
workflowConfigs: {
liveness: {
// Skip the tutorial/onboarding screen.
skipTutorialScreen: false,
// Skip the selfie review confirmation screen. Directly submits the captured selfie.
skipSelfieReviewScreen: false,
// Camera frame shape overlay. Options: 'circle' | 'oval' | 'square' | 'rectangle'
cameraFrameShape: 'oval',
// Face detection timeout in milliseconds. Must be a positive integer.
detectionTimeOut: 90000,
// Duration (ms) to show countdown alert before timeout. Must be less than detectionTimeOut.
detectionTimeOutCountdownDuration: 20000,
// Hide the countdown alert that appears before detection timeout.
hideDetectionTimeOutCountdownAlert: false,
// Maximum retry attempts allowed. Must be a positive integer.
maxRetryAttempts: 3,
// Hide the error message when max retries are exhausted.
hideMaxRetryError: false,
// Hide the static head shape overlay on the camera screen.
hideStaticHeadShape: false,
// Skip the white screen flash effect in low-light conditions.
skipDarkLightingScreenFlash: false,
// Hide the help button on the camera capture screen.
hideHelpOnCaptureScreen: false,
// Hide error codes displayed on the selfie review screen.
hideErrorCodeOnSelfieReview: false,
// Granular control to hide description text on individual screens.
hideDescriptions: {
tutorial: false, // Hide tutorial screen description
cameraAccess: false, // Hide camera access prompt description
camera: false, // Hide camera screen description
selfieReview: false, // Hide selfie review screen description
},
},
},
/* ═══════════════════════════════════════════════════
* THEME CONFIGS
* All fields are optional. Shown values are defaults.
* ═══════════════════════════════════════════════════ */
themeConfigs: {
// Typography
fontFamily: 'Plus Jakarta Sans, sans-serif', // Font family for all SDK text
fontFamilyUrl: 'https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap', // Fonts URL to load a custom font
titleTextColor: '#333334', // Title text color
titleTextFontSize: '20px', // Title text font size
descriptionTextColor: '#4C4D4F', // Description text color
descriptionFontSize: '14px', // Description text font size
bodyTextColor: '#4C4D4F', // Body text color
bodyTextFontSize: '14px', // Body text font size
// Primary button
primaryButtonBgColor: '#00EB76', // Background color
primaryButtonBorderColor: 'none', // Border color
primaryButtonHoverBgColor: '#00EB76', // Hover background color
primaryButtonDisabledBgColor: '#BBBBBB', // Disabled background color
primaryButtonTextColor: '#142C42', // Text color
primaryButtonHoverTextColor: '#FFFFFF', // Hover text color
primaryButtonBorderRadius: '6px', // Border radius
// Secondary button
secondaryButtonBgColor: '#FFFFFF', // Background color
secondaryButtonBorderColor: '#DCE1E7', // Border color
secondaryButtonHoverBgColor: '#F4F4F5', // Hover background color
secondaryButtonDisabledBgColor: '#BBBBBB', // Disabled background color
secondaryButtonTextColor: '#142C42', // Text color
secondaryButtonHoverTextColor: '#142C42', // Hover text color
secondaryButtonBorderRadius: '6px', // Border radius
// Camera & frame
cameraFrameBorderInitialColor: '#FFFFFF', // Initial frame border color
cameraFrameBorderAnimationColor: '#00EB76', // Animated frame border color (progress)
cameraFrameOverlayColor: '#000000', // Overlay color outside the frame
instructionIconColor: '#000000', // Tutorial instruction icon color
cameraInstructionTextColor: '#FFFFFF', // Camera feedback text color
cameraInstructionBgColor: '#00172F', // Camera feedback background color
cameraInstructionFontSize: '12px', // Camera feedback font size
cameraCaptureButtonColor: '#FFFFFF', // Capture button color
// Alerts & errors
errorAlertBgColor: '#FEE2E2', // Error alert background color
errorAlertTextColor: '#991919', // Error alert text color
errorAlertTextFontSize: '14px', // Error alert font size
errorTextColor: '#DC2626', // Error text color
// UI controls
loadingSpinnerColor: '#00EB76', // Loading spinner color
backButtonColor: '#000000', // Back button color
modalCloseButtonColor: '#000000', // Close button color
sessionIdFontSize: '12px', // Session ID font size
backgroundColor: '#FFFFFF', // SDK background color
},
/* ═══════════════════════════════════════════════════
* LOCALE CONFIGS
* Custom text overrides for EN and ID locales.
* All fields are optional — SDK uses defaults if not provided.
* Only 'EN' and 'ID' locale keys are supported.
* ═══════════════════════════════════════════════════ */
localeConfigs: {
liveness: {
EN: {
sessionId: 'Session ID', // Session ID label
networkStatus: 'You seem to be offline. Please check your internet connection', // Offline status message
// Tutorial screen
livenessTutorial: {
title: 'Capture Your Selfie', // Screen title
description: 'Position your face within the frame.', // Screen description
instructions: {
holdPhoneSteady: 'Hold the phone steady using both hands', // (Visible for mobile/tanlet devices) Instruction: steady phone
avoidGlasses: "Don't wear glasses", // Instruction: no glasses
avoidBrightPlace: 'Avoid being in a very bright place', // (Visible for color flash) Instruction: avoid bright light
faceFullyVisible: 'Ensure your face is fully visible within the frame', // (Visible for desktop devices) Instruction: face visibility
},
actionButton: 'Start Selfie Capture', // Start button text
},
// Selfie capture screen (camera screen)
selfieCapture: {
title: 'Capture Your Selfie', // Screen title (when camera allowed)
description: 'Follow the instructions provided and ensure your face is clearly visible', // Screen description
helpText: 'Need Help?', // Help button text
helpBackButton: 'Back', // Help overlay back button
selfieCaptureTipsTitle: 'Capture Your Selfie', // Selfie tips overlay title
docCaptureTipsTitle: 'Document Capture Tips', // Doc tips overlay title
noFaceDetected: 'Put your face in the frame', // Feedback: no face found
faceDetected: 'Stay still', // Feedback: face detected, capturing
placeFaceinFrame: 'Put your face in the frame', // Feedback: face outside frame
multipleFaceDetected: 'Ensure no additional faces are visible in the frame', // Feedback: multiple faces
faceTooFar: 'Move closer', // Feedback: face too far
faceNotStraight: 'Keep your face straight', // Feedback: face angle off
faceToodark: 'Move to well-lit area', // Feedback: too dark
faceTooBright: 'Too bright', // Feedback: too bright
eyesClosed: 'Open your eyes', // Feedback: eyes closed
detectionTimeOut: '${time} seconds left to complete your verification', // Countdown alert. ${time} is replaced with seconds remaining.
// Camera permission prompt
permission: {
title: 'Allow Camera Access', // Permission screen title
description: 'To continue, please enable camera access. We cannot verify your identity without using your camera.', // Permission description
actionButton: 'Allow', // Permission action button
},
// Camera error screen
error: {
title: 'The camera is either not supported or the access is denied.', // Error title
description: 'If you denied camera access by mistake, follow these steps:', // Error description
actionButton: 'Retry', // Retry button
unsupportedDeviceTitle: 'Unable to proceed', // Unsupported device error title
unsupportedDeviceDescription: 'Unsupported device. Switch to a compatible device or use a desktop/mobile browser.', // Unsupported device description
moduleDownloadErrorTitle: 'Unable to proceed', // Face detection module download error title
moduleDownloadErrorDescription: 'Module download failed. Check your connection and try again', // Module download error description
browserPrivacyModeErrorTitle: 'Unable to proceed', // Private/incognito mode error title
browserPrivacyModeErrorDescription:
'Face detection failed. Do not use a private window, and disable browser tracking protection for this site before trying again.', // Privacy mode error description
},
},
// Selfie review screen
selfieReview: {
title: 'Review Photo', // Screen title
description: 'Ensure the image is well-lit, clear, and that all features are visible', // Screen description
primaryActionButton: 'Submit Photo', // Submit button
secondaryActionButton: 'Retake Selfie', // Retake button
tryLaterButton: 'Try Again Later', // Try later button (shown on max retry)
// Backend error messages (error code → display text)
backendError_1041: 'Liveness verification failed', // Liveness failed
backendError_1051: 'Remove any obstructions from your face', // Face obstruction
backendError_1052: 'Move closer', // Face too far
backendError_1053: 'Please ensure the lighting is sufficient and the photo is clear', // Bad image quality
backendError_1054: 'Ensure no additional faces are visible in the frame', // Multiple faces
backendError_1055: 'Put your face in the frame', // No face detected
backendError_1058: 'Please ensure the lighting is sufficient and the photo is clear', // Face too dark
backendError_1059: 'The selfie is blurry, hold your phone steady', // Blurry image
backendError_1060: 'Keep your face straight', // Face not straight
backendError_1062: 'Open your eyes', // Eyes closed
backendError_1063: 'Please ensure the lighting is sufficient and the photo is clear', // Unnatural color
backendError_1064: "The selfie is too dark, ensure there's enough lighting for a clear photo", // Under exposure
backendError_1074: "The selfie is too dark, ensure there's enough lighting for a clear photo", // Under exposure (alt)
backendError_1065: 'The selfie is too bright, please adjust the lighting for a clear photo', // Over exposure
backendError_1075: 'The selfie is too bright, please adjust the lighting for a clear photo', // Over exposure (alt)
backendError_1066: 'The selfie is blurry, hold your phone steady', // Blurry (alt)
backendError_1076: 'The selfie is blurry, hold your phone steady', // Blurry (alt)
sessionExpired: 'Session expired. Please restart the selfie process to continue', // Session timeout
unknownError: 'Oops! Something went wrong, please try again later', // Generic error
maxRetryExhausted: "You've reached the maximum number of attempts. Please try again later", // Max retry reached
},
},
ID: {
sessionId: 'ID Sesi',
networkStatus: 'Sepertinya Anda offline. Silakan periksa koneksi internet Anda',
livenessTutorial: {
title: 'Ambil Swafoto',
description: 'Posisikan wajah Anda dalam bingkai.',
instructions: {
holdPhoneSteady: 'Pegang telepon dengan stabil menggunakan kedua tangan',
avoidGlasses: 'Jangan memakai kacamata',
avoidBrightPlace: 'Hindari berada di tempat yang terlalu terang',
faceFullyVisible: 'Pastikan wajah Anda terlihat sepenuhnya dalam bingkai',
},
actionButton: 'Mulai Pengambilan Selfie',
},
selfieCapture: {
title: 'Ambil Swafoto',
description: 'Ikuti petunjuk yang diberikan dan pastikan wajah Anda terlihat jelas',
helpText: 'Butuh Bantuan?',
helpBackButton: 'Kembali',
selfieCaptureTipsTitle: 'Ambil Swafoto',
docCaptureTipsTitle: 'Tip Pengambilan Dokumen',
noFaceDetected: 'Tempatkan wajah Anda dalam bingkai',
faceDetected: 'Tetap diam',
placeFaceinFrame: 'Tempatkan wajah Anda dalam bingkai',
multipleFaceDetected: 'Pastikan hanya satu wajah di layar',
faceTooFar: 'Mendekat',
faceNotStraight: 'Hadapkan wajah ke layar',
faceToodark: 'Pindah ke tempat cerah',
faceTooBright: 'Terlalu silau',
eyesClosed: 'Buka mata Anda',
detectionTimeOut: 'Waktu hampir habis, ${time} detik tersisa untuk verifikasi',
permission: {
title: 'Izinkan akses kamera',
description:
'Untuk melanjutkan, Anda perlu mengizinkan akses kamera. Kami tidak dapat memverifikasi Anda tanpa menggunakan kamera.',
actionButton: 'Izinkan',
},
error: {
title: 'Kamera tidak didukung atau akses ditolak.',
description: 'Jika Anda tidak sengaja menolak akses kamera, ikuti langkah-langkah berikut:',
actionButton: 'Coba kembali',
unsupportedDeviceTitle: 'Tidak dapat melanjutkan',
unsupportedDeviceDescription: 'Perangkat tidak didukung. Gunakan perangkat lain atau beralih ke desktop/mobile.',
moduleDownloadErrorTitle: 'Tidak dapat melanjutkan',
moduleDownloadErrorDescription: 'Pengunduhan modul gagal. Pastikan koneksi internet stabil dan coba lagi',
browserPrivacyModeErrorTitle: 'Tidak dapat melanjutkan',
browserPrivacyModeErrorDescription:
'Deteksi wajah gagal. Jangan gunakan jendela private, dan nonaktifkan perlindungan pelacakan browser untuk situs ini sebelum mencoba lagi.',
},
},
selfieReview: {
title: 'Tinjau Foto',
description: 'Pastikan pencahayaan foto baik dan tampak jelas',
primaryActionButton: 'Kirim Foto',
secondaryActionButton: 'Ulangi Selfie',
tryLaterButton: 'Coba Lagi',
backendError_1041: 'Verifikasi Liveness gagal',
backendError_1051: 'Jangan ada penghalang di wajah',
backendError_1052: 'Mendekat',
backendError_1053: 'Pastikan pencahayaan cukup agar foto terlihat jelas',
backendError_1054: 'Pastikan hanya satu wajah di layar',
backendError_1055: 'Tempatkan wajah Anda dalam bingkai',
backendError_1058: 'Pastikan pencahayaan cukup agar foto terlihat jelas',
backendError_1059: 'Swafoto buram, pastikan perangkat stabil',
backendError_1060: 'Hadapkan wajah ke layar',
backendError_1062: 'Buka mata Anda',
backendError_1063: 'Pastikan pencahayaan cukup agar foto terlihat jelas',
backendError_1064: 'Swafoto terlalu gelap, pastikan pencahayaannya cukup agar foto terlihat jelas',
backendError_1074: 'Swafoto terlalu gelap, pastikan pencahayaannya cukup agar foto terlihat jelas',
backendError_1065: 'Swafoto terlalu terang, atur pencahayaan agar foto terlihat jelas',
backendError_1075: 'Swafoto terlalu terang, atur pencahayaan agar foto terlihat jelas',
backendError_1066: 'Swafoto buram, pastikan perangkat stabil',
backendError_1076: 'Swafoto buram, pastikan perangkat stabil',
sessionExpired: 'Sesi telah habis. Mohon ulangi proses swafoto untuk melanjutkan',
unknownError: 'Ups! Terjadi kesalahan, silakan coba lagi nanti',
maxRetryExhausted: 'Anda telah mencapai batas maksimum percobaan. Silakan coba lagi nanti',
},
},
},
},
});
```