Overview
The Biometrics module provides face verification and liveness detection capabilities through third-party provider integrations. It manages facial capture and verification to confirm that the person completing verification matches their identity document and is physically present (not a photo or video).
Accessing the Module
The Biometrics module is accessed through the SDK’s component factory:
const sdk = await OneSdk({
mode: 'production',
session: { token: 'your-token' }
});
// Create Biometrics component instance
const biometricsComponent = sdk.component('biometrics', options);
Supported Providers
The Biometrics module supports multiple face verification providers:
| Provider | Value | Learn More |
|---|
| Onfido | 'onfido' | onfido.com |
| Sumsub | 'sumsub' | sumsub.com |
| Incode | 'incode' | incode.com |
| IDVerse | 'idverse' | idverse.com |
| Daon | 'daon' | daon.com |
Each provider has different capabilities, UI/UX, liveness detection methods, and device support. Visit the provider’s website to understand their specific features and limitations.
Configuration Options
Basic Configuration
const biometricsComponent = sdk.component('biometrics', {
provider: {
name: 'onfido'
}
});
Common Options
In addition to provider-specific settings, you can configure:
| Option | Type | Description |
|---|
checkProcessingPool | object | Configure check processing polling behavior (optional) |
is_synchronous | boolean | Whether to run biometric checks synchronously (optional) |
Check Processing Pool:
checkProcessingPool: {
enabled: true, // Enable polling for check results
wait_time: 5, // Wait time between polls (seconds)
max_attempts: 1 // Maximum polling attempts
}
Provider-Specific Options
Onfido Provider
const biometricsComponent = sdk.component('biometrics', {
provider: {
name: 'onfido',
sdkVersion: '13.0.0', // Onfido SDK version
theme: 'light', // 'light' or 'dark'
biometricsVariant: 'standard', // 'standard', 'video', or 'motion'
fallback: 'standard', // Fallback method: 'standard' or 'video'
showExitButton: true, // Show exit button in UI
crossDevicePolicy: 'disable', // Cross-device flow: 'force' or 'disable'
customUI: { // Custom UI configuration
// See Onfido Custom UI options below
}
}
});
Onfido Options:
| Option | Type | Description |
|---|
sdkVersion | string | Version of the Onfido SDK to use. Default: '12'. Refer to the Onfido documentation for available versions. |
theme | 'light' | 'dark' | UI theme |
biometricsVariant | 'standard' | 'video' | 'motion' | Onfido-specific: Biometric capture variant. 'standard' uses photo-based liveness, 'video' uses video liveness, 'motion' uses motion-based liveness. |
fallback | 'standard' | 'video' | Fallback biometric method if primary method fails |
showExitButton | boolean | Display exit button in the UI |
crossDevicePolicy | 'force' | 'disable' | Enable/disable cross-device flow |
customUI | object | Custom UI styling configuration (see Custom UI section below) |
onUserExit | () => void | Callback function when user exits the flow |
_crossDeviceLinkMethods | array | Internal: cross-device link sharing methods |
Onfido Custom UI Properties:
The customUI object allows extensive styling customization:
customUI: {
// Typography
fontWeightBody: 400,
fontSizeBody: '16px',
fontSizeSubtitle: '18px',
fontSizeTitle: '24px',
// Colors - Background
colorBackgroundSurfaceModal: '#FFFFFF',
colorBackgroundIcon: '#353FF4',
colorBackgroundInput: '#FFFFFF',
// Colors - Content/Text
colorContentBody: '#475467',
colorContentTitle: '#101828',
colorContentSubtitle: '#344054',
colorContentInput: '#101828',
// Colors - Buttons (Primary)
colorContentButtonPrimaryText: '#FFFFFF',
colorBackgroundButtonPrimary: '#353FF4',
colorBackgroundButtonPrimaryHover: '#2835E5',
colorBackgroundButtonPrimaryActive: '#1F2AD1',
// Colors - Buttons (Secondary)
colorContentButtonSecondaryText: '#344054',
colorBackgroundButtonSecondary: '#FFFFFF',
colorBackgroundButtonSecondaryHover: '#F9FAFB',
colorBackgroundButtonSecondaryActive: '#F2F4F7',
// Colors - Buttons (Tertiary)
colorContentButtonTertiaryText: '#344054',
// Borders
borderRadiusButton: '8px',
borderStyleSurfaceModal: '1px solid #E4E7EC',
colorBorderInput: '#D0D5DD',
colorInputOutline: '#353FF4',
// Additional UI elements
colorIcon: '#667085',
colorBackgroundInfoPill: '#F2F4F7',
colorContentInfoPill: '#344054',
// ... see Onfido documentation for full list
}
Sumsub Provider
const biometricsComponent = sdk.component('biometrics', {
provider: {
name: 'sumsub',
config: {
theme: 'light', // 'light' or 'dark'
lang: 'en', // Language code (optional)
email: 'user@example.com', // Pre-fill email (optional)
phone: '+1234567890' // Pre-fill phone (optional)
},
options: {
addViewportTag: true, // Add viewport meta tag
adaptIframeHeight: true // Auto-adjust iframe height
}
}
});
Sumsub Options:
| Option | Type | Description |
|---|
config | object | Sumsub configuration object (see Config table below) |
options | object | Sumsub SDK options (see Options table below) |
Sumsub Config Object:
| Property | Type | Required | Description |
|---|
theme | 'dark' | 'light' | Yes | UI theme |
lang | string | No | Language code (e.g., 'en', 'es', 'fr') |
email | string | No | Pre-fill user’s email address |
phone | string | No | Pre-fill user’s phone number |
Sumsub Options Object:
| Property | Type | Required | Description |
|---|
addViewportTag | boolean | Yes | Whether to add viewport meta tag to page |
adaptIframeHeight | boolean | Yes | Whether to automatically adjust iframe height |
Incode Provider
const biometricsComponent = sdk.component('biometrics', {
provider: {
name: 'incode',
sdkVersion: '1.0.0' // Incode SDK version (optional)
}
});
Incode Options:
| Option | Type | Description |
|---|
sdkVersion | string | Version of the Incode SDK to use. Default: '1.75.2'. Refer to the Incode documentation for available versions. |
IDVerse Provider
const biometricsComponent = sdk.component('biometrics', {
provider: {
name: 'idverse',
skipFaceScanIntro: false, // Skip intro screen
logoUrl: 'https://...', // Custom logo URL
retryCount: 3, // Number of retry attempts
skipLoad: false, // Skip loading screen
workerPathString: '/path', // Custom worker path
assetPathString: '/assets' // Custom asset path
}
});
IDVerse Options:
| Option | Type | Description |
|---|
skipFaceScanIntro | boolean | Skip the face scan introduction screen (optional) |
logoUrl | string | URL to custom logo to display in the UI (optional) |
retryCount | number | Number of retry attempts allowed (optional) |
skipLoad | boolean | Skip the loading screen (optional) |
workerPathString | string | Custom path to worker scripts (optional) |
assetPathString | string | Custom path to asset files (optional) |
Daon Provider
const biometricsComponent = sdk.component('biometrics', {
provider: {
name: 'daon',
products: ['faceLiveness'] // Array of Daon products to use
}
});
Daon Options:
| Option | Type | Description |
|---|
products | string[] | Array of Daon product identifiers to enable |
Methods
mount()
Mounts the Biometrics component to a DOM element and starts the face verification flow.
Signature:
mount(domElementOrSelector: string | HTMLElement): void
Parameters:
| Parameter | Type | Required | Description |
|---|
domElementOrSelector | string | HTMLElement | Yes | CSS selector string (e.g., '#biometrics-container') or HTMLElement object where the component will be mounted |
Description:
Mounts the biometric capture interface to the specified DOM element and initiates the face verification flow. The provider’s camera interface will be displayed within this element.
Example:
// Mount to element by ID
biometricsComponent.mount('#biometrics-container');
// Mount to element reference
const container = document.getElementById('biometrics-container');
biometricsComponent.mount(container);
unmount()
Unmounts the Biometrics component from the DOM.
Signature:
Description:
Removes the Biometrics component from the DOM and cleans up resources, including stopping camera access. Call this when the user navigates away or the verification flow is complete.
Example:
biometricsComponent.unmount();
Events
The Biometrics module emits events throughout the verification lifecycle:
Provider-Specific Behavior: Events and statuses vary by provider. Not all providers emit all events, and some events are provider-specific. Always test with your chosen provider to understand which events are emitted and when.
vendor_sdk_loaded
Common Event: This event is emitted by all vendor-based modules (IDV, OCR, Biometrics, Device).
Emitted when the provider’s SDK has been successfully loaded.
biometricsComponent.on('vendor_sdk_loaded', ({ vendor }) => {
console.log('SDK loaded for:', vendor);
});
Parameters:
| Parameter | Type | Description |
|---|
vendor | string | The provider whose SDK was loaded ('onfido', 'sumsub', etc.) |
vendor_sdk_failed_loading
Common Event: This event is emitted by all vendor-based modules (IDV, OCR, Biometrics, Device).
Emitted when the provider’s SDK fails to load.
biometricsComponent.on('vendor_sdk_failed_loading', ({ vendor, errorObject }) => {
console.error(`Failed to load ${vendor} SDK:`, errorObject);
});
Parameters:
| Parameter | Type | Description |
|---|
vendor | string | The provider whose SDK failed to load |
errorObject | unknown | The error that occurred during loading |
session_data_generated
Emitted when a biometric verification session has been created with the provider.
biometricsComponent.on('session_data_generated', ({ session }) => {
console.log('Session created for entity:', session.entityId);
console.log('Vendor parameters:', session.vendorParameters);
});
Parameters:
| Parameter | Type | Description |
|---|
session.entityId | string | The entity ID for this verification session |
session.vendorParameters | unknown | Provider-specific session parameters |
session_data_failed_loading
Emitted when session data fails to load.
biometricsComponent.on('session_data_failed_loading', ({ code, message }) => {
console.error('Session failed:', message);
});
Parameters:
| Parameter | Type | Description |
|---|
code | unknown | Optional error code |
message | string | Error message describing the failure |
ready
Emitted when the biometric capture interface is ready for user interaction.
biometricsComponent.on('ready', ({ domElement }) => {
console.log('Biometrics UI ready');
// Camera capture can begin
});
Parameters:
| Parameter | Type | Description |
|---|
domElement | HTMLElement | The DOM element where the component is mounted |
Emitted when a non-positive flow has occurred but is likely recoverable by retrying.
biometricsComponent.on('input_required', (info, status) => {
console.log('Input required. Status:', status);
console.log('User can retry to continue verification');
// Handle different statuses
showRetryMessage(status);
});
Parameters:
| Parameter | Type | Description |
|---|
info.entityId | string | null | The entity ID, or null if not yet available |
status | IDVStatus | OCRStatus | The current verification status indicating what input is needed |
Description:
This event indicates that verification cannot proceed in its current state, but the issue is typically recoverable. Common scenarios include:
- User closed the verification session
- Session timeout occurred
- Waiting for selfie capture
- Awaiting user consent
- Camera permission denied
The user can typically retry the verification process to resolve these issues.
detection_complete
Emitted when the biometric capture process has completed successfully.
biometricsComponent.on('detection_complete', ({ provider }) => {
console.log('Face captured successfully by:', provider);
showMessage('Processing your biometric data...');
});
Parameters:
| Parameter | Type | Description |
|---|
provider | string | The provider that completed the capture (optional, may be undefined) |
detection_failed
Emitted when the biometric capture process fails.
biometricsComponent.on('detection_failed', ({ message }) => {
console.error('Capture failed:', message);
showError(message || 'Biometric capture failed. Please try again.');
});
Parameters:
| Parameter | Type | Description |
|---|
message | string | Error message describing why capture failed (optional) |
processing
Emitted when biometric data is being processed by the provider.
biometricsComponent.on('processing', ({ checkStatus, entityId }) => {
console.log('Processing biometric data:', checkStatus);
showLoadingIndicator();
});
Parameters:
| Parameter | Type | Description |
|---|
checkStatus | IDVStatus | The current status of the biometric check |
entityId | string | null | The entity ID being verified |
results
Emitted when the biometric verification process completes with results.
biometricsComponent.on('results', ({ provider, checkStatus, document, entityId }) => {
console.log('Verification complete');
console.log('Provider:', provider);
console.log('Status:', checkStatus);
if (checkStatus === 'COMPLETE') {
console.log('✓ Biometric verification passed');
navigateToSuccess();
} else {
console.log('✗ Verification status:', checkStatus);
handleFailure(checkStatus);
}
});
Parameters:
| Parameter | Type | Description |
|---|
provider | string | null | The provider that performed verification (optional) |
checkStatus | IDVStatus | Final verification status |
document | Document | null | Associated document data, if any |
entityId | string | null | The entity ID that was verified |
session_closed
Emitted when the verification session is closed normally.
biometricsComponent.on('session_closed', () => {
console.log('Biometric session closed');
cleanup();
});
Parameters: None
session_interrupted
Emitted when the verification session is interrupted by the user.
biometricsComponent.on('session_interrupted', (interruptInfo) => {
console.log('User interrupted verification');
saveProgress();
showMessage('You can resume verification later');
});
Parameters:
| Parameter | Type | Description |
|---|
interruptInfo | object | Information about the interruption |
Provider-Specific:
- Onfido: Emits this when the verification modal is closed.
vendor_event
Emitted for provider-specific events that don’t map to standard events.
biometricsComponent.on('vendor_event', (eventData) => {
console.log('Provider event:', eventData);
// Handle provider-specific logic
});
Parameters:
| Parameter | Type | Description |
|---|
eventData | object | Provider-specific event data |
Complete Example
import OneSdk from '@frankieone/one-sdk';
async function performBiometricVerification() {
try {
// Initialize SDK
const sdk = await OneSdk({
mode: 'production',
session: { token: await getSessionToken() }
});
// Create Biometrics component with Onfido provider
const biometricsComponent = sdk.component('biometrics', {
provider: {
name: 'onfido',
theme: 'light',
biometricsVariant: 'standard',
showExitButton: true,
fallback: 'video'
},
checkProcessingPool: {
enabled: true,
wait_time: 5,
max_attempts: 3
}
});
// Set up event listeners
biometricsComponent.on('vendor_sdk_loaded', ({ vendor }) => {
console.log(`${vendor} SDK loaded successfully`);
});
biometricsComponent.on('vendor_sdk_failed_loading', ({ vendor, errorObject }) => {
console.error(`Failed to load ${vendor} SDK:`, errorObject);
showError('Biometric verification unavailable. Please try again later.');
});
biometricsComponent.on('session_data_generated', ({ session }) => {
console.log('Biometric session created for:', session.entityId);
});
biometricsComponent.on('session_data_failed_loading', ({ message }) => {
console.error('Session failed:', message);
showError('Failed to start biometric verification');
});
biometricsComponent.on('ready', ({ domElement }) => {
console.log('Camera ready, please position your face');
showInstruction('Position your face in the frame');
});
biometricsComponent.on('input_required', (info, status) => {
console.log('Input required:', status);
showRetryButton();
});
biometricsComponent.on('detection_complete', ({ provider }) => {
console.log('Face captured successfully');
showMessage('Processing your biometric data...');
hideCamera();
});
biometricsComponent.on('detection_failed', ({ message }) => {
console.error('Capture failed:', message);
showError(message || 'Failed to capture face. Please try again.');
});
biometricsComponent.on('processing', ({ checkStatus }) => {
console.log('Processing:', checkStatus);
showLoadingIndicator();
});
biometricsComponent.on('results', ({ checkStatus, entityId }) => {
console.log('Verification complete');
if (checkStatus === 'COMPLETE') {
console.log('✓ Biometric verification passed');
navigateToSuccess();
} else if (checkStatus === 'FAILED') {
console.log('✗ Biometric verification failed');
showFailureScreen();
} else {
console.log('Status:', checkStatus);
handleOtherStatus(checkStatus);
}
});
biometricsComponent.on('session_interrupted', () => {
console.log('User interrupted verification');
saveProgress();
});
biometricsComponent.on('session_closed', () => {
console.log('Session closed');
cleanup();
});
// Mount and start biometric verification
biometricsComponent.mount('#biometrics-container');
} catch (error) {
console.error('Biometrics initialization failed:', error);
throw error;
}
}
Best Practices
-
Handle all events, not just
results - The results event only fires with COMPLETE or FAILED. Also listen to input_required (for recoverable states like INCOMPLETE or INTERRUPTED), error (for system failures), and processing (for intermediate states).
-
Set up event listeners before mounting - Register all event handlers before calling
mount() to avoid missing events.
-
Unmount on navigation - Always call
unmount() when the user leaves the page to clean up resources.
-
Provider-specific configuration - Review each provider’s documentation for optimal configuration.
-
Error handling - Always listen to the
error event and provide user-friendly error messages.
Common Issues
Component not displaying
Ensure the mount element exists in the DOM and has sufficient size:
#biometrics-container {
width: 100%;
min-height: 600px;
}
Session data failed to load
This usually means the backend session setup failed. Ensure your backend is correctly generating biometric verification tokens.
Provider-specific errors
Check the vendor_event emissions for provider-specific error details and consult the provider’s documentation.