Schema-shaped JSON — source coordinates on every value, and a review list when something doesn't check out.
No templates. No training. No silent wrong numbers.
Name your fields, and where you already know the shape a value must have, say that too. Typed JSON comes back with coordinates and flags on every value, and this exact call runs as-is.
curl -X POST https://api.space-ocr.com/ocr/fields \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": "https://example.com/receipt.jpg",
"imageType": "url",
"fields": [
{ "name": "store_name" },
{ "name": "invoice_no", "pattern": "^[0-9]{6}$" },
{ "name": "total", "type": "number", "required": true }
]
}'{
"status": "success",
"data": {
"values": {
"store_name": "Supermarket ABC",
"invoice_no": "10O482",
"total": "$4.94"
},
"cells": {
"invoice_no": {
"box": { "xmin": 612, "ymin": 96,
"xmax": 742, "ymax": 118 },
"quad": [ /* 4 corners */ ],
"verified": true,
"review": { "reasons": ["pattern_mismatch"] }
}
// …store_name, total — same shape
},
"review": {
"unit": "field", "declared": 3,
"returned": 3, "boxed": 3, "verified": 3,
"flagged": [
{ "path": "invoice_no",
"reasons": ["pattern_mismatch"] }
],
"by_reason": { "pattern_mismatch": 1 }
},
"normalized": { "invoice_no": "10O482", "total": 4.94 },
"image": { "width": 1654, "height": 2339 }
}
}No training, no processor setup, no document-type registration.
Same pages, three runs — 16 of 463 values moved.
Every value carries coordinates and a flag — review the flags, not every field.
The layer between a photo and the fields your database expects is already built.


“Where did this number come from?”
Each value carries box / quad coordinates pointing into the source image.
“The same ¥711 sits on four lines — why this one?”
Values are matched against the OCR text character by character before a box is chosen.
“Slips arrive rotated 90 degrees.”
Rotation and skew are read from the photo as it was taken.
“The one that passes while wrong is what worries me.”
Every value is cross-checked against the OCR pass — uncertain ones land on review.flagged.
Async + signed webhooks
/jobs polling · HMAC webhooks · OpenAPI 3.1.
No database to stand up
Create a folder and a sheet, rows pile up, and /view pulls them back with filters.
The five steps the pipeline runs on every call.
OCR finds every character and where it sits — the only step that produces coordinates.
It reads the image and that text together, and pulls out the fields you asked for or the document's own structure. It never invents coordinates.
Each value the model returns is anchored to the exact spot on the page where OCR read it.
Where they disagree, that spot is cropped and read once more — whatever still fails comes back flagged, with the reason attached.
Each value comes back with the box and quad it was read from.
Same images, same field schema, same grading script, three runs per engine. The raw responses and the grading code are public.

8 cases over 7 documents · 463 fields · 3 runs each · August 2026 — measured against Mistral Document AI.
The same checked values the API returns, in a screen built to read them: point at a value and the photo answers.
No setup, no code. Drag a stack of photos into the browser and the rows fill themselves.
Hover a cell and the exact region of the original lights up — and it works the other way too, from the photo back to the value.
Values that failed the cross-check stand out in colour instead of sitting quietly wrong, so you only review what deserves it.
Correct a value with the original right beside it. No second window, no hunting for the page it came from.
Export a sheet as CSV that opens cleanly in Excel, or a doc bundle as .md / .txt.
Pick a format when you upload. What it reads stacks up in a folder, and you can query and search it from there.
Name the fields you want and get them typed, with line items unfolded. Rows stack into a sheet you can query and export as CSV.
Headings, paragraphs, lists and tables keep their structure — ready to drop into a doc site, a wiki, or an LLM context window.
The raw reading, paragraph by paragraph. The plainest way to index, search or diff a scan.
Results stay in a folder you named. Folders nest, and sheets, document bundles and memos all live in them.
Pull the stacked rows back with filters. where · sort · select and pagination run on the server.
Walk the tree, or type once and everything matches: folder and file names, memo bodies, and the cell values read off the page.
Connect one MCP server. Hand it photos and it creates the folders and sheets they call for, stacking each photo as a row, then pulls back only the rows you ask about later. The results stay there, so there is no database to stand up.
Anywhere that speaks MCP