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

# How It Works

> What happens between the photo upload and the JSON response, and how to turn the result into approve, review or reject.

You send one image and get the extracted data back in the same response. The approve, review or reject decision stays on your side.

```mermaid theme={null}
flowchart TD
    A["<b>1 · Upload</b><br/>Passbook photo"] --> B["<b>2 · Extract</b><br/>OCR and image checks"]
    B --> C["<b>3 · Respond</b><br/>Data, scores, is_scan"]
    C --> D{"Bankbook?"}
    D -->|no| R1["Reject"]
    D -->|yes| E{"Physical?"}
    E -->|no| M1["Manual review"]
    E -->|yes| F{"Text clear?"}
    F -->|no| M2["Manual review"]
    F -->|yes| G{"Details match?"}
    G -->|no| R2["Correct or reject"]
    G -->|yes| OK(["Approve"])
```

## The pipeline

**1. Detect and straighten**

The service locates the passbook in the image and auto-rotates skewed or upside-down photos.

**2. Read the text**

Two OCR models run in parallel on the name and account number; the better result is kept automatically.

**3. Classify the image**

A template matcher scores how closely the document resembles known Thai bankbooks (`similarity_score`). A separate classifier flags scans and screenshots (`is_scan`) and detects the form: paper passbook or electronic statement.

**4. Respond**

The API returns the extracted fields, the bank enum and the scores. Field definitions are in the [API reference](/api-reference/bankbooks/extract-data).

## Signals you get back

| Signal | Answers the question |
| - | - |
| `similarity_score` | Is this a bankbook at all? |
| `is_scan` | Is it a photo of a physical passbook, or a screenshot or scan? |
| `confidence_score` | How sure is the OCR about the extracted text? |
| `account_name`, `account_number`, `bank_name` | Do the details match what the user told you? |

## Making a decision

Bankbooks returns signals, not a verdict: your system decides whether to approve, reject or send the case to a reviewer. What each signal means and the recommended thresholds are in the [API reference](/api-reference/bankbooks/extract-data); the order below turns them into one policy.

Apply the checks in order; the first one that fires decides the outcome.

| # | Check | Condition | Recommended action |
| - | - | - | - |
| 1 | Is it a bankbook? | `similarity_score` below 0.75–0.8, or HTTP 404 | Reject and ask the user for a clear photo of the passbook's first page. Typical causes: a card, a statement, an unrelated document. |
| 2 | Is it a physical passbook? | `is_scan` = `true` | Send to manual review rather than auto-reject. Ask for a fresh photo if your policy requires a physical document. |
| 3 | Can the text be trusted? | `confidence_score` below 0.75 | Send to manual review. About 6% of submissions land here. |
| 4 | Does the name match? | `account_name` vs. the name you hold for the user | Approve on a match; review or reject on a mismatch. Use approximate matching (below). |
| 5 | Does the account match? | `account_number` and `bank_name` vs. the payout details the user entered | Approve on a match; ask the user to correct the details on a mismatch. |

> [!WARNING]
>
> Don't hard-reject on `is_scan` alone. The flag is advisory and can miss screenshots made outside a bank's mobile app.

### Matching Thai names

The API reference explains why Thai names need approximate matching. In practice:

* Compare against the Thai `account_name`, not `account_name_en` — the English name is a transliteration and its spelling varies between documents.
* Strip honorifics such as นาย, นาง and นางสาว and extra whitespace before comparing.
* Compare account numbers with hyphens and spaces removed.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.