Skip to main content

Overview

The IDV (Identity Verification) flow uses camera-based document capture powered by Incode. The SDK handles the entire capture experience — the user points their camera at an ID document and the SDK automatically detects, captures, and processes it. This is the simplest embedded flow to implement. Modules used: idv, form (WELCOME, CONSENT, LOADING screens)
Instead of building from scratch, fork an existing flow from the public sample codes.

Flow Diagram

1

Welcome Screen

Initial greeting and introduction to the verification process.
2

Consent Screen

Capture user consent for data processing.
3

IDV Capture

The SDK renders camera capture UI for document scanning.
4

Processing

The SDK processes the captured document and runs verification checks.
5

Result

Your application receives the verification result and displays the outcome.

Full Implementation

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>OneSDK IDV Flow</title>
    <script src="https://assets.frankiefinancial.io/one-sdk/v1/oneSdk.umd.js"></script>
    <style>
      body { margin: 0; font-family: sans-serif; background: #fff; }
      #onesdk-wrapper { position: relative; width: 100%; height: 100vh; }
      #onesdk-container { width: 100%; height: 100%; }
      #loading-overlay {
        position: absolute; top: 0; left: 0; width: 100%; height: 100%;
        z-index: 10; background: #fff;
      }
    </style>
  </head>
  <body>
    <div id="onesdk-wrapper">
      <div id="onesdk-container"></div>
      <div id="loading-overlay"></div>
    </div>

    <script>
      async function startOneSDK() {
        try {
          // 1. Generate session token (move to your backend in production)
          const tokenResponse = await fetch(
            "https://backend.kycaml.uat.frankiefinancial.io/auth/v2/machine-session",
            {
              method: "POST",
              headers: {
                authorization: "machine " + btoa("<CUSTOMER_ID>:<CUSTOMER_CHILD_ID>:<API_KEY>"),
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                permissions: {
                  preset: "one-sdk",
                  reference: "idv-" + Date.now(),
                },
              }),
            }
          );
          const session = await tokenResponse.json();

          // 2. Initialize OneSDK
          const oneSdk = await OneSDK({
            session: session,
            mode: "development",
            recipe: {
              form: {
                provider: { name: "react" },
              },
            },
          });

          const appContainer = "#onesdk-container";

          // 3. Create form and IDV components
          const welcome = oneSdk.component("form", {
            name: "WELCOME",
            type: "ocr",
          });

          const consent = oneSdk.component("form", { name: "CONSENT" });

          const idv = oneSdk.flow("idv");

          const idvLoading = oneSdk.component("form", {
            name: "LOADING",
            title: { label: "Loading..." },
            descriptions: [{ label: "" }],
          });

          const processingLoading = oneSdk.component("form", {
            name: "LOADING",
            title: { label: "Processing..." },
            descriptions: [
              {
                label: "Please do not refresh this page or click the back button.",
              },
            ],
          });

          const submitLoading = oneSdk.component("form", {
            name: "LOADING",
            title: { label: "Submitting verification..." },
            descriptions: [
              {
                label: "Please do not refresh this page or click the back button.",
              },
            ],
          });

          // 4. Wire up welcome → consent → IDV
          welcome.on("form:welcome:ready", () => {
            consent.mount(appContainer);
          });

          consent.on("form:consent:ready", () => {
            idvLoading.mount("#loading-overlay");
            idv.mount(appContainer);
          });

          // 5. Handle loading — IDV init and post-capture processing
          let detectionStarted = false;

          idv.on("loading", (isLoading) => {
            if (!detectionStarted && !isLoading) {
              idvLoading.unmount();
            }
          });

          idv.on("detection_complete", () => {
            detectionStarted = true;
            processingLoading.mount("#loading-overlay");
          });

          // 6. Handle results
          idv.on("results", async ({ checkStatus }) => {
            processingLoading.unmount();
            if (checkStatus) {
              submitLoading.mount(appContainer);
              try {
                await oneSdk.individual().submit({ verify: true });
                document.getElementById("onesdk-container").innerHTML =
                  "<h2>Verification complete</h2><p>Your identity has been verified.</p>";
              } catch (err) {
                console.error("Submission error:", err);
              }
            }
          });

          // 7. Handle errors
          idv.on("error", ({ message, payload }) => {
            console.error("IDV error:", message, payload);
            document.getElementById("onesdk-container").innerHTML =
              "<h2>Verification error</h2><p>Please try again.</p>";
          });

          // 8. Mount welcome screen to start
          welcome.mount(appContainer);
        } catch (error) {
          console.error("OneSDK initialization failed:", error);
        }
      }

      startOneSDK();
    </script>
  </body>
</html>

Step-by-Step Breakdown

1. Initialize the SDK

Pass the session object to OneSDK(). Include the recipe.form.provider configuration since this flow uses form components for the WELCOME and CONSENT screens. Create WELCOME and CONSENT form components to collect user consent before starting the IDV capture. Set type: "ocr" on the WELCOME screen. Consent must be collected before verification can proceed — without it, submission will fail.

3. Create the IDV Flow

Call sdk.flow("idv") to create the identity verification flow. This returns a component that manages the entire camera capture experience.

4. Wire Up Events

Listen for events:
  • form:welcome:ready on welcome — user completed the welcome screen, mount consent
  • form:consent:ready on consent — user gave consent, mount the IDV flow
  • loading on IDV — show/hide loading screen while IDV component initializes (before capture)
  • detection_complete on IDV — document capture finished, show processing loading screen
  • results on IDV — processing complete, checkStatus indicates success
  • error on IDV — an error occurred during capture or processing
Unmount clears the container. Calling .unmount() on a component removes all content from the element it was mounted to — not just the component itself. Loading screens in this flow are mounted to a separate overlay element (#loading-overlay) so that unmounting them does not destroy the IDV component underneath. See the IDV with Review flow for a detailed explanation.

5. Handle Results

When results fires with checkStatus: true, mount a loading screen then call sdk.individual().submit({ verify: true }) to trigger the verification check. The loading screen prevents a blank screen during the async submission.

Submitting Verification

After the IDV flow returns results, mount a loading screen then submit for verification:
idv.on("results", async ({ checkStatus }) => {
  processingLoading.unmount();
  if (checkStatus) {
    submitLoading.mount(appContainer);
    try {
      const result = await oneSdk.individual().submit({ verify: true });
      // Handle verification result
    } catch (error) {
      console.error("Verification submission failed:", error);
    }
  }
});
See Individual Module for all submission options.

Provider Configuration

Configure the IDV provider in the SDK recipe:
const oneSdk = await OneSDK({
  session: session,
  mode: "production",
  recipe: {
    ocr: {
      provideReviewScreen: false,
      provider: { name: "incode" },
    },
    biometrics: {
      provider: { name: "incode" },
    },
  },
});
See Vendor Customizations for all provider options.

Customization Reference

AspectReference
SDK initialization optionsSDK Initialization
IDV flow configurationIDV Module
Form screen configurationForm Module
Individual submissionIndividual Module
Event names and payloadsEvents
Error handling patternsError Scenarios
Provider configurationVendor Customizations