Skip to main content

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:
ProviderValueLearn 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:
OptionTypeDescription
documentsarrayArray of document configurations specifying types and countries (optional)
checkProcessingPoolobjectConfigure 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:
OptionTypeDescription
sdkVersionstringVersion of the Onfido SDK to use. Default: '12'. Refer to the Onfido documentation for available versions.
theme'light' | 'dark'UI theme
maxDocumentCountnumberMaximum number of documents to capture
product'idv'Product type (always 'idv' for IDV module)
biometricsVariantstringBiometric capture variant: 'standard', 'video', or 'motion'
useOneStepbooleanEnable one-step capture workflow
showExitButtonbooleanDisplay exit button in the UI
fallback'standard' | 'video'Fallback biometric method
crossDevicePolicy'force' | 'disable'Enable/disable cross-device flow
customUIobjectCustom UI configuration object

Incode Provider

const idvFlow = sdk.flow('idv', {
  provider: {
    name: 'incode',
    product: 'idv',
    lang: 'en'  // Language code
  }
});
Incode Options:
OptionTypeDescription
product'idv'Product type (required)
langstringLanguage 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:
OptionTypeDescription
product'idv' | 'poa'Product type: 'idv' for identity verification or 'poa' for proof of address
configobjectSumsub configuration object (see Config table below)
optionsobjectSumsub SDK options (see Options table below)
Sumsub Config Object:
PropertyTypeRequiredDescription
theme'dark' | 'light'YesUI theme
langstringNoLanguage code (e.g., 'en', 'es', 'fr')
emailstringNoPre-fill user’s email address
phonestringNoPre-fill user’s phone number
Sumsub Options Object:
PropertyTypeRequiredDescription
addViewportTagbooleanYesWhether to add viewport meta tag to page
adaptIframeHeightbooleanYesWhether to automatically adjust iframe height

Truuth Provider

const idvFlow = sdk.flow('idv', {
  provider: {
    name: 'truuth',
    sdkVersion: '1.0.0'  // Optional SDK version
  }
});
Truuth Options:
OptionTypeDescription
sdkVersionstringVersion 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:
ParameterTypeRequiredDescription
domElementOrSelectorstring | HTMLElementYesCSS 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:
unmount(): void
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:
idvFlow.unmount();

isPreloaded()

Checks if IDV data has been previously captured for this entity. Signature:
isPreloaded(): boolean
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:
  1. Whether the individual module has preloaded data
  2. 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.
StatusDescription
CHECK_NOT_STARTEDVerification check has not been initiated
CHECK_PROCESSINGVerification check is currently processing
COMPLETEVerification completed successfully
FAILEDVerification failed
INCOMPLETEVerification incomplete (missing data or steps)
DOCUMENTS_INVALIDProvided documents are invalid
PROVIDER_OFFLINEVerification provider is offline/unavailable
AWAITING_CONSENTWaiting for user consent
WAITING_SELFIE_UPLOADWaiting for selfie/biometric upload
WAITING_DOC_UPLOADWaiting for document upload
INTERRUPTEDVerification flow was interrupted (provider-specific)
Status-to-Event Mapping: The results event only fires for terminal statuses. Non-terminal statuses surface through other events:
StatusEvent
COMPLETEresults
FAILEDresults
INCOMPLETEinput_required
DOCUMENTS_INVALIDinput_required
AWAITING_CONSENTinput_required
WAITING_SELFIE_UPLOADinput_required
WAITING_DOC_UPLOADinput_required
INTERRUPTEDinput_required
PROVIDER_OFFLINEerror
CHECK_PROCESSINGprocessing
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);
});

input_required

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

  1. 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).
  2. Set up event listeners before mounting - Register all event handlers before calling mount() to avoid missing events.
  3. Unmount on navigation - Always call unmount() when the user leaves the page to clean up resources.
  4. Provider-specific configuration - Review each provider’s documentation for optimal configuration.
  5. 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.