Overview
The IDV (Identity Verification) module provides an integrated document capture and biometric verification flow through third-party provider integrations. It manages the complete identity verification process with minimal configuration required.
Accessing the Module
The IDV module is accessed through the SDK’s flow factory:
const sdk = await OneSdk({
mode: 'production',
session: { token: 'your-token' }
});
// Create IDV flow instance
const idvFlow = sdk.flow('idv', options);
Supported Providers
The IDV module supports multiple identity verification providers:
| Provider | Value | Learn More |
|---|
| Onfido | 'onfido' | onfido.com |
| Sumsub | 'sumsub' | sumsub.com |
| Incode | 'incode' | incode.com |
| Truuth | 'truuth' | truuth.id |
| Daon | 'daon' | daon.com |
Each provider has different capabilities, UI/UX, supported documents, and geographic coverage. Visit the provider’s website to understand their specific features and limitations.
Configuration Options
Basic Configuration
const idvFlow = sdk.flow('idv', {
provider: {
name: 'onfido'
}
});
Common Options
In addition to provider-specific settings, you can configure:
| Option | Type | Description |
|---|
documents | array | Array of document configurations specifying types and countries (optional) |
checkProcessingPool | object | Configure check processing polling behavior (optional) |
Documents Array:
documents: [
{
type: 'DRIVERS_LICENCE', // Document type
countries: ['AUS', 'NZL'] // ISO country codes (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 idvFlow = sdk.flow('idv', {
provider: {
name: 'onfido',
sdkVersion: '13.0.0', // Onfido SDK version
theme: 'light', // 'light' or 'dark'
maxDocumentCount: 3, // Maximum documents to capture
product: 'idv', // Product type
biometricsVariant: 'standard', // 'standard', 'video', or 'motion'
useOneStep: false, // Enable one-step capture
showExitButton: true, // Show exit button in UI
fallback: 'standard', // Fallback method: 'standard' or 'video'
crossDevicePolicy: 'disable', // Cross-device flow: 'force' or 'disable'
customUI: { // Custom UI configuration
// See Onfido documentation for customUI options
}
}
});
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 |
maxDocumentCount | number | Maximum number of documents to capture |
product | 'idv' | Product type (always 'idv' for IDV module) |
biometricsVariant | string | Biometric capture variant: 'standard', 'video', or 'motion' |
useOneStep | boolean | Enable one-step capture workflow |
showExitButton | boolean | Display exit button in the UI |
fallback | 'standard' | 'video' | Fallback biometric method |
crossDevicePolicy | 'force' | 'disable' | Enable/disable cross-device flow |
customUI | object | Custom UI configuration object |
Incode Provider
const idvFlow = sdk.flow('idv', {
provider: {
name: 'incode',
product: 'idv',
lang: 'en' // Language code
}
});
Incode Options:
| Option | Type | Description |
|---|
product | 'idv' | Product type (required) |
lang | string | Language code (e.g., 'en', 'es', 'fr', 'de', 'pt', 'zh') |
Supported Languages:
'bn', 'ca', 'zh', 'hr', 'nl', 'en', 'en-BZ', 'en-DG', 'fr', 'de', 'ht', 'hi', 'hmn', 'hu', 'id', 'it', 'ms', 'pl', 'pt', 'pt-BR', 'pt-PT', 'ro', 'sr', 'sr-LATN', 'so', 'es', 'es-ES', 'tl-PH', 'tr', 'vi'
Sumsub Provider
const idvFlow = sdk.flow('idv', {
provider: {
name: 'sumsub',
product: 'idv', // or 'poa' for proof of address
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 |
|---|
product | 'idv' | 'poa' | Product type: 'idv' for identity verification or 'poa' for proof of address |
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 |
Truuth Provider
const idvFlow = sdk.flow('idv', {
provider: {
name: 'truuth',
sdkVersion: '1.0.0' // Optional SDK version
}
});
Truuth Options:
| Option | Type | Description |
|---|
sdkVersion | string | Version of the Truuth SDK to use. Default: '1.0'. Refer to Truuth documentation for available versions. |
Daon Provider
const idvFlow = sdk.flow('idv', {
provider: {
name: 'daon',
products: ['IdentityX', 'VeriFLY'], // Daon products to use
processInstanceParameters: [
{
name: 'param1',
mandatory: true,
default: 'value'
}
]
}
});
Methods
mount()
Mounts the IDV component to a DOM element and starts the verification flow.
Signature:
mount(domElementOrSelector: string | HTMLElement): void
Parameters:
| Parameter | Type | Required | Description |
|---|
domElementOrSelector | string | HTMLElement | Yes | CSS selector string (e.g., '#idv-container') or HTMLElement object where the component will be mounted |
Description:
Mounts the IDV Smart UI to the specified DOM element and initiates the identity verification flow. The provider’s interface will be displayed within this element.
Example:
// Mount to element by ID
idvFlow.mount('#idv-container');
// Mount to element reference
const container = document.getElementById('idv-container');
idvFlow.mount(container);
unmount()
Unmounts the IDV component from the DOM.
Signature:
Description:
Removes the IDV component from the DOM and cleans up resources. Call this when the user navigates away or the verification flow is complete.
Example:
isPreloaded()
Checks if IDV data has been previously captured for this entity.
Signature:
Returns: boolean - true if IDV verification data exists for this entity, false otherwise
Description:
Returns true if the entity has existing IDV verification data (indicated by an attestation document). This allows you to skip the verification flow for returning users who have already completed identity verification.
The method checks:
- Whether the individual module has preloaded data
- Whether the entity has an attestation document (indicating completed IDV verification)
Example:
const idvFlow = sdk.flow('idv', {
provider: { name: 'onfido' }
});
if (idvFlow.isPreloaded()) {
console.log('User has completed IDV verification');
// Skip verification, proceed to next step
proceedToNextStep();
} else {
console.log('User needs to complete IDV verification');
// Mount and start verification
idvFlow.mount('#idv-container');
}
Use Cases:
- Skip verification UI for returning users with completed IDV
- Show different messaging for users with existing verification
- Conditionally render verification components based on verification status
This method checks for the presence of verification data, not the verification result. A user may have completed verification but failed checks. Always verify the actual verification status through your backend before granting access.
access()
Accesses reactive data accessors for the IDV component state.
Signature:
access(fieldName: string): Accessor
Returns: Currently returns void (not implemented)
Note: This method is present for API consistency but is not yet implemented for the IDV module.
statuses
Object containing all possible IDV status constants.
Type: Readonly<typeof IDVStatus>
Description:
Provides access to IDV status enum values for comparison in event handlers and status checks.
Available Statuses:
Provider-Specific: Not all statuses are used by all providers. The specific statuses emitted depend on your chosen verification provider’s workflow and capabilities.
| Status | Description |
|---|
CHECK_NOT_STARTED | Verification check has not been initiated |
CHECK_PROCESSING | Verification check is currently processing |
COMPLETE | Verification completed successfully |
FAILED | Verification failed |
INCOMPLETE | Verification incomplete (missing data or steps) |
DOCUMENTS_INVALID | Provided documents are invalid |
PROVIDER_OFFLINE | Verification provider is offline/unavailable |
AWAITING_CONSENT | Waiting for user consent |
WAITING_SELFIE_UPLOAD | Waiting for selfie/biometric upload |
WAITING_DOC_UPLOAD | Waiting for document upload |
INTERRUPTED | Verification flow was interrupted (provider-specific) |
Status-to-Event Mapping:
The results event only fires for terminal statuses. Non-terminal statuses surface through other events:
| Status | Event |
|---|
COMPLETE | results |
FAILED | results |
INCOMPLETE | input_required |
DOCUMENTS_INVALID | input_required |
AWAITING_CONSENT | input_required |
WAITING_SELFIE_UPLOAD | input_required |
WAITING_DOC_UPLOAD | input_required |
INTERRUPTED | input_required |
PROVIDER_OFFLINE | error |
CHECK_PROCESSING | processing |
Example:
const idvFlow = sdk.flow('idv', { provider: { name: 'onfido' } });
idvFlow.on('input_required', (info, status) => {
if (status === idvFlow.statuses.WAITING_DOC_UPLOAD) {
console.log('Waiting for document upload');
} else if (status === idvFlow.statuses.WAITING_SELFIE_UPLOAD) {
console.log('Waiting for selfie upload');
}
});
idvFlow.on('results', (results) => {
if (results.checkStatus === idvFlow.statuses.COMPLETE) {
console.log('Verification completed successfully');
} else if (results.checkStatus === idvFlow.statuses.FAILED) {
console.log('Verification failed');
}
});
Events
The IDV 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.
session_data_generated
Emitted when session data for the vendor is generated.
Arguments:
{
session: {
entityId: string | null;
vendorParameters: object;
}
}
Example:
idvFlow.on('session_data_generated', ({ session }) => {
console.log('Session created for entity:', session.entityId);
console.log('Vendor parameters:', session.vendorParameters);
});
detection_complete
Emitted when initial detection/capture is complete.
Arguments: None
Example:
idvFlow.on('detection_complete', () => {
console.log('Document and biometric capture complete');
showProcessingMessage();
});
detection_failed
Emitted when detection/capture fails.
Arguments:
{
message: string;
payload?: Record<string, unknown>;
}
Example:
idvFlow.on('detection_failed', ({ message, payload }) => {
console.error('Detection failed:', message);
console.error('Details:', payload);
showErrorMessage(message);
});
Emitted when a non-positive flow has occurred but is likely recoverable by retrying.
Arguments:
(
info: { entityId: string | null },
status: IDVStatus
)
Description:
Emitted when the check could not be completed due to user input — not because of a system failure. For example, the user uploaded the wrong document type, or the user closed the session before completing it. Retrying the step will always help resolve input_required.
Common scenarios:
- Waiting for document or selfie upload
- Awaiting user consent
- User closed or interrupted the verification session (remounting the module allows them to resume)
There is no way to differentiate between user abandonment and session timeout within the SDK. Both surface as input_required with INTERRUPTED status. Whether to limit retry attempts depends on your business process.
Example:
idvFlow.on('input_required', ({ entityId }, status) => {
console.log('Input required. Status:', status);
console.log('User can retry to continue verification');
if (status === idvFlow.statuses.WAITING_DOC_UPLOAD) {
showMessage('Please upload your document to continue');
enableRetry();
} else if (status === idvFlow.statuses.WAITING_SELFIE_UPLOAD) {
showMessage('Please capture your selfie to continue');
enableRetry();
} else if (status === idvFlow.statuses.AWAITING_CONSENT) {
showMessage('Please provide consent to continue');
enableRetry();
}
});
processing
Emitted when verification checks are processing.
Arguments:
{
checkStatus: IDVStatus;
entityId: string | null;
[key: string]: any;
}
Example:
idvFlow.on('processing', (status) => {
console.log('Processing verification. Status:', status.checkStatus);
showLoadingSpinner();
});
results
Emitted when verification reaches a terminal state. Only fires with COMPLETE or FAILED status. Other statuses surface through input_required, error, or processing events.
Arguments:
{
checkStatus: IDVStatus;
entityId: string | null;
[key: string]: any;
}
Example:
idvFlow.on('results', (results) => {
console.log('Verification results received');
console.log('Status:', results.checkStatus);
console.log('Entity ID:', results.entityId);
if (results.checkStatus === idvFlow.statuses.COMPLETE) {
navigateToSuccess();
} else if (results.checkStatus === idvFlow.statuses.FAILED) {
showFailureScreen(results);
}
});
session_interrupted
Emitted when the user interrupts the verification session.
Arguments: None
Provider-Specific:
- Onfido: Emits this when the verification modal is closed.
Example:
// Onfido-specific event
idvFlow.on('session_interrupted', () => {
console.log('User interrupted the verification (Onfido)');
saveProgress();
});
session_closed
Emitted when the verification session is closed.
Arguments: None
Example:
idvFlow.on('session_closed', () => {
console.log('Verification session closed');
idvFlow.unmount();
});
session_data_failed_loading
Emitted when session data fails to load.
Arguments: None
Example:
idvFlow.on('session_data_failed_loading', () => {
console.error('Failed to load session data');
showErrorMessage('Unable to start verification. Please try again.');
});
vendor_event
Emitted for provider-specific events.
Arguments:
{
[key: string]: any; // Provider-specific event data
}
Example:
idvFlow.on('vendor_event', (event) => {
console.log('Provider event:', event);
// Handle provider-specific events
});
Common Events
The IDV module also emits common events inherited from the event system:
error - When an error occurs
warning - For non-critical warnings
info - Informational messages
loading - Loading state changes
See Event System Reference for details.
Complete Example
import OneSdk from '@frankieone/one-sdk';
async function performIDV() {
try {
// Initialize SDK
const sdk = await OneSdk({
mode: 'production',
session: { token: await getSessionToken() }
});
// Create IDV component with Onfido provider
const idvFlow = sdk.flow('idv', {
provider: {
name: 'onfido',
theme: 'light',
product: 'idv',
biometricsVariant: 'standard',
showExitButton: true
}
});
// Check if user has already completed IDV
if (idvFlow.isPreloaded()) {
console.log('User has existing IDV verification data');
// Skip verification for returning user
return navigateToNextStep();
}
// Set up event listeners
idvFlow.on('session_data_generated', ({ session }) => {
console.log('IDV session started for:', session.entityId);
});
idvFlow.on('detection_complete', () => {
console.log('Capture complete, processing...');
showMessage('Processing your verification...');
});
idvFlow.on('detection_failed', ({ message }) => {
console.error('Capture failed:', message);
showError(message);
});
idvFlow.on('processing', (status) => {
console.log('Verification processing:', status.checkStatus);
});
idvFlow.on('results', (results) => {
console.log('Verification complete');
if (results.checkStatus === idvFlow.statuses.COMPLETE) {
console.log('✓ Verification passed');
navigateToSuccess();
} else if (results.checkStatus === idvFlow.statuses.FAILED) {
console.log('✗ Verification failed');
showFailureScreen();
} else {
console.log('Status:', results.checkStatus);
handleOtherStatus(results);
}
});
idvFlow.on('session_interrupted', () => {
console.log('User closed verification');
saveProgress();
});
idvFlow.on('error', (error) => {
console.error('IDV error:', error);
showError('Verification error. Please try again.');
});
// Mount and start verification
idvFlow.mount('#idv-container');
} catch (error) {
console.error('IDV 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 such as PROVIDER_OFFLINE), 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:
#idv-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 IDV tokens.
Provider-specific errors
Check the vendor_event emissions for provider-specific error details and consult the provider’s documentation.