> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frankieone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OCR Only

> Document capture and data extraction without biometrics — ideal when you only need to collect and verify document information.

## Overview

The OCR Only flow captures identity documents via camera and extracts structured data (name, date of birth, document number, etc.) without requiring biometric verification. This is useful when you need document data collection without facial matching — for example, collecting document details for a background check or credit application.

**Modules used:** [`ocr`](/docs/sdk-reference/ocr-module), [`form`](/docs/sdk-reference/form-module) (WELCOME, CONSENT, DOCUMENT, LOADING, RESULT screens)

<Callout icon="star" color="#3DD892" iconType="regular">
  Instead of building from scratch, fork an existing flow from the [public sample codes](https://github.com/FrankieOne/frontend-onesdk-public-sample-codes/).
</Callout>

<Callout icon="bell" color="#FFCA16" iconType="regular">
  **Daon provider:** Document selection and the `documents` parameter are not required when using the Daon provider — Daon provides its own document type selection screen. To use custom document selection instead of Daon's built-in screen, contact your FrankieOne account team.
</Callout>

## Flow Diagram

<Steps>
  <Step title="Welcome Screen">
    Initial greeting and introduction.
  </Step>

  <Step title="Consent Screen">
    Capture user consent for data processing.
  </Step>

  <Step title="Document Selection">
    User selects the type of document to capture.
  </Step>

  <Step title="OCR Capture">
    Camera-based document capture and automatic data extraction.
  </Step>

  <Step title="Result">
    Capture outcome displayed.
  </Step>
</Steps>

## Full Implementation

<Tabs>
  <Tab title="Vanilla HTML/JS">
    ```html theme={null}
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>OneSDK OCR Only</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: "ocr-" + Date.now(),
                    },
                  }),
                }
              );
              const session = await tokenResponse.json();

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

              const appContainer = "#onesdk-container";

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

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

              const documentForm = oneSdk.component("form", {
                name: "DOCUMENT",
                showPreps: true,
              });

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

              const resultSuccess = oneSdk.component("form", {
                name: "RESULT",
                type: "manual",
                state: "SUCCESS",
                title: { label: "Document captured" },
                descriptions: [{ label: "Your document has been captured and data extracted." }],
                cta: { label: "Done" },
              });

              // 4. Wire up form navigation
              welcome.mount(appContainer);

              welcome.on("form:welcome:ready", () => {
                consent.mount(appContainer);
              });

              consent.on("form:consent:ready", () => {
                documentForm.mount(appContainer);
              });

              // 5. Handle document selection → OCR capture
              documentForm.on("form:document:ready", ({ inputInfo }) => {
                ocrLoading.mount("#loading-overlay");
                const docType = inputInfo.documentType;

                const ocr = oneSdk.component("ocr", {
                  documents: [{ type: docType, countries: ["AUS"] }],
                });

                ocr.mount(appContainer);

                ocr.on("loading", (isLoading) => {
                  if (!isLoading) {
                    ocrLoading.unmount();
                  }
                });

                ocr.on("error", (err) => {
                  console.error("OCR error:", err);
                });

                // 6. Handle OCR results → Result screen
                ocr.on("results", ({ document }) => {
                  if (document) {
                    resultSuccess.mount(appContainer);
                  }
                });
              });
            } catch (error) {
              console.error("OneSDK initialization failed:", error);
            }
          }

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

  <Tab title="React">
    ```jsx theme={null}
    import { useEffect, useRef } from "react";
    import OneSdk from "@frankieone/one-sdk";

    export default function OCROnlyFlow({ session }) {
      const initRef = useRef(false);

      useEffect(() => {
        if (!session || initRef.current) return;
        initRef.current = true;

        (async () => {
          try {
            const oneSdk = await OneSdk({
              session,
              mode: "development",
              recipe: {
                ocr: { maxDocumentCount: 3 },
                form: {
                  provider: { name: "react" },
                },
              },
            });

            const appContainer = "#onesdk-container";

            const welcome = oneSdk.component("form", { name: "WELCOME", type: "ocr" });
            const consent = oneSdk.component("form", { name: "CONSENT" });
            const documentForm = oneSdk.component("form", { name: "DOCUMENT", showPreps: true });

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

            const resultSuccess = oneSdk.component("form", {
              name: "RESULT", type: "manual", state: "SUCCESS",
              title: { label: "Document captured" },
              descriptions: [{ label: "Your document has been captured and data extracted." }],
              cta: { label: "Done" },
            });

            welcome.mount(appContainer);

            welcome.on("form:welcome:ready", () => consent.mount(appContainer));
            consent.on("form:consent:ready", () => documentForm.mount(appContainer));

            documentForm.on("form:document:ready", ({ inputInfo }) => {
              ocrLoading.mount("#loading-overlay");
              const ocr = oneSdk.component("ocr", {
                documents: [{ type: inputInfo.documentType, countries: ["AUS"] }],
              });

              ocr.mount(appContainer);

              ocr.on("loading", (isLoading) => {
                if (!isLoading) ocrLoading.unmount();
              });

              ocr.on("error", (err) => console.error("OCR error:", err));

              ocr.on("results", ({ document }) => {
                if (document) resultSuccess.mount(appContainer);
              });
            });
          } catch (error) {
            console.error("OneSDK initialization failed:", error);
          }
        })();
      }, [session]);

      return (
        <div id="onesdk-wrapper" style={{ position: "relative", width: "100%", height: "100vh" }}>
          <div id="onesdk-container" style={{ width: "100%", height: "100%" }} />
          <div
            id="loading-overlay"
            style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", zIndex: 10, background: "#fff" }}
          />
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

## Step-by-Step Breakdown

### 1. Initialize the SDK

Pass the session object to [`OneSDK()`](/docs/sdk-reference/sdk-initialization). Include the `ocr` and `form.provider` recipe configuration.

### 2. Configure Components

Create [form components](/docs/sdk-reference/form-module) for the Welcome, Consent, Document, Loading, and Result screens. The [`ocr`](/docs/sdk-reference/ocr-module) component is created dynamically after document selection.

### 3. Wire Up Events

Use [`.on(event)`](/docs/sdk-reference/events) listeners to navigate through each step. A loading screen is shown on a [separate overlay](#loading-screen) while the OCR component initializes. After OCR emits `results`, mount the result screen.

### 4. Handle Results

After the OCR component emits `results` with extracted document data, display the result screen. See [Error Scenarios](/docs/sdk-reference/error-scenarios) for failure handling.

## Loading Screen

A loading screen is shown while the OCR component initializes. It is mounted to a separate overlay div so that `unmount()` does not clear the OCR component underneath.

```javascript theme={null}
const ocrLoading = oneSdk.component("form", {
  name: "LOADING",
  title: { label: "Loading..." },
  descriptions: [{ label: "" }],
});

ocrLoading.mount("#loading-overlay");
ocr.mount("#onesdk-container");

ocr.on("loading", (isLoading) => {
  if (!isLoading) {
    ocrLoading.unmount(); // Safe — only clears #loading-overlay
  }
});
```

<Callout icon="bell" color="#FFCA16" iconType="regular">
  **Unmount clears the container.** Calling `.unmount()` on a component removes **all content** from the element it was mounted to — not just the component itself. Always mount loading screens to a **separate element** when they need to overlay another component. See the [IDV with Review flow](/docs/embedded-flows/idv-review#loading-screens) for more details.
</Callout>

## Document Type Configuration

Configure which document types are accepted for OCR capture:

```javascript theme={null}
const ocr = oneSdk.component("ocr", {
  documents: [
    { type: "DRIVERS_LICENCE", countries: ["AUS"] },
    { type: "PASSPORT", countries: ["AUS", "NZL"] },
  ],
});
```

See [OCR Module](/docs/sdk-reference/ocr-module) for all supported document types and configuration options.

## Extracted Data Handling

The OCR `results` event provides structured document data:

```javascript theme={null}
ocr.on("results", ({ document }) => {
  if (document) {
    const { ocrResult } = document;

    // Available fields depend on document type
    const dateOfBirth = ocrResult.dateOfBirth;
    const fullName = ocrResult.fullName;
    const documentNumber = ocrResult.documentNumber;

    // Show result or process data directly
    resultSuccess.mount(appContainer);
  }
});
```

## Customization Reference

| Aspect                      | Reference                                                    |
| --------------------------- | ------------------------------------------------------------ |
| SDK initialization options  | [SDK Initialization](/docs/sdk-reference/sdk-initialization) |
| OCR component configuration | [OCR Module](/docs/sdk-reference/ocr-module)                 |
| Form screen configuration   | [Form Module](/docs/sdk-reference/form-module)               |
| Screen names and types      | [Form Screens](/docs/sdk-reference/form-module/screens)      |
| Event names and payloads    | [Events](/docs/sdk-reference/events)                         |
| Error handling patterns     | [Error Scenarios](/docs/sdk-reference/error-scenarios)       |
