Free passport OCR API

This is a free passport OCR API you can call before you have an account. The documentation prints a public sandbox key, and that key runs 10 real recognitions per IP address — no signup, no credit card, no sales call anywhere in the way. Register and 20 more credits land in the account. After that a recognised document costs one cent, flat, at any volume. Send a photograph or a scan of a passport, identity card or travel document; get back structured JSON with the holder, the document, every field found, and the machine-readable zone with its check digits verified. A failed scan costs nothing.

Run your first recognition without an account

Copy the key from the documentation and post an image. That is the whole integration:

IMG=$(base64 -i passport.jpg | tr -d '\n')

curl -s https://api.doc.cheap/v1/scans \
  -H "Authorization: Bearer sk_sandbox_public" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: first-call-1" \
  -d '{"image":"'"$IMG"'","options":{"mode":"full"}}'

sk_sandbox_public is the public sandbox key — it is published on purpose, it is not a secret, and it is rate-limited. Idempotency-Key means a retried request is not a second charge, which matters the day you replay a queue.

What comes back

One response shape, eight groups, every key always present. The field explorer lists every key with its type, and the API reference is the contract itself.

{
  "meta": { "schema_version": "1.0", "status": "recognized", "billed": true,
            "confidence": "high",
            "timing": { "upload_ms": 118, "processing_ms": 684, "total_ms": 826 } },
  "document": { "kind": "passport", "country": "GRC", "country_name": "Greece",
                "is_expired": false, "days_remaining": 2001 },
  "holder": { "given_names": "ELENI SOFIA", "surname": "PARADEIGMA",
              "birth_date": "1994-03-08", "sex": "F", "nationality": "GRC" },
  "mrz": { "status": "passed", "reason": null, "lines": ["…", "…"] },
  "fields": [ "…" ], "images": { "…": null },
  "quality": { "overall": "pass" },
  "authenticity": { "overall": "not_checked", "checks": [] }
}
  • meta.status is one of exactly five strings: recognized, no_document_found, unreadable, unsupported_document, rejected.
  • Dates are ISO-8601, always. A missing value is null, never an absent key.
  • meta.billed is on every response and says whether that call cost anything.
  • fields[] carries every field the document holds, read from the encoded zone and from the printed zone separately, each with its own confidence, so the two readings can be compared. Values in their own script arrive beside the Latin transliteration, tagged with their language.

The example holder is a synthetic specimen: an invented person, with real check-digit arithmetic over invented values. The zone she carries is set out on the MRZ format page.

What it costs after the free calls

1¢ per document. Flat, every account, at any volume.

One number, whatever the volume: no bands, no price list to ask for, nothing to negotiate. One credit is one cent is one recognised document.

Only recognised documents are billed. Only a successfully recognised document is charged. A scan that finds no document, cannot read the image, or cannot determine the type answers with its verdict and costs nothing.

  • ✓ 10 free recognitions on the public sandbox key, with no account at all.
  • ✓ 20 free documents when you register, credited to your balance.

How billing works How that compares with the alternatives

What happens to the image

Nothing is kept. The image is never written to disk — it lives in memory for the duration of the request. A result is retained only for the retain_hours you ask for, and the default is 0: nothing stored, nothing to fetch back, nothing to leak.

Set retain_hours above zero only when you want to re-read a result later; it is your choice, per call.

When the photo cannot be read

The answer says so, and it is free. meta.status distinguishes the cases, and in all three meta.billed is false:

  • no_document_found — nothing document-shaped in the frame.
  • unreadable — found it, could not read it — glare, blur, resolution.
  • unsupported_document — read it, do not support that type.

Every response carries its own timing split, and the live median is published on the status page rather than promised here.

Free tools that need no key at all

Calling it from an assistant instead of from code? The MCP server exposes the same recognition as three tools.

Frequently asked questions

What is passport OCR?

Passport OCR is the machine reading of a passport's data page from a photograph or scan. It has two halves. The machine-readable zone is the two lines of 44 characters at the bottom of the page, printed in a font designed to be read by a machine and protected by check digits. The visual zone is everything printed for a human: the same name, number and dates, plus the ones the zone does not carry — place of birth, issuing authority, the portrait. Reading only the first half is easier and tells you less; reading both lets you compare them.

Is there a free passport OCR API?

Yes, within limits. This one publishes a sandbox key in the documentation that runs 10 real recognitions per IP address with no account and no card, and registering adds 20 credits — 30 documents before any payment. Offline, the open PassportEye library with tesseract reads the machine-readable zone for free on your own machine; it does not read the printed side, and its accuracy on phone photographs depends entirely on your own image pre-processing. “Free forever at volume” does not exist in this category from anyone, ourselves included.

How much does a passport OCR API cost?

Here, $0.01 per document, flat, at any volume, and nothing when the recognition fails. Published list prices elsewhere differ in their units — some vendors bill by the page, we bill by the document — so compare on the same unit before you compare the numbers. The figures, each read on the vendor's own page and linked to it, are on the comparison page.

Do you store the passport image?

No. The image is never written to disk; it exists in memory for the length of the request and is gone when the response is sent. Results are kept only for the retain_hours you pass, which defaults to 0 — nothing retained. There is no document store here, which is the short answer to what happens to your users' passports.

What happens if the photo is unreadable?

You get an answer and no charge. The response carries meta.status — unreadable when the document was found but could not be read, or no_document_found when nothing document-shaped was in the frame — and meta.billed false. The quality group carries the verdict on the image itself. Re-shoot without glare across the zone, fill the frame with the data page, and keep the zone above roughly 300 DPI.