space ocr
GuidesArticlesPricingDocs
developer

Same documents, same schema, different answers: space-ocr vs Mistral

A controlled benchmark on 8 hard documents, 463 fields, 3 runs per engine: field accuracy, run-to-run stability, and the coordinate gap no score table shows.

6 min read· 2026-08-08

Every OCR vendor's demo reads a clean printed invoice perfectly, ours included. That tells you nothing about the decision you are actually making. The questions that matter are what happens on the documents that are hard, whether the answer changes when you run the same page twice, and how you find the wrong values without re-checking every single one by hand.

So we measured it. We took the eight hardest documents in our own regression corpus, sent the exact same requests to space-ocr and to Mistral Document AI, and scored everything with the same script. This post is the result, with the method laid out in enough detail that you can disagree with it precisely.

The setup: 8 real documents (Japanese delivery slips, a supermarket receipt that prints each item across two lines, a 22-row wholesale price sheet photographed off a monitor, a commission statement), 463 scorable fields in total. Three arms, each getting identical images, identical field schemas and the same extract-verbatim instruction: space-ocr's production fields endpoint, Mistral's OCR with JSON-schema annotations (mistral-ocr-latest), and Mistral's vision LLM with structured output (mistral-medium). Three runs per arm, whitespace-stripped exact match against a frozen ground truth, all 72 raw outputs archived. August 2026.

Benchmark result card: space-ocr 91.1%, Mistral OCR 70.0%, Mistral vision LLM 73.5% on 8 documents and 463 fields
8 hard documents, 463 fields, 3 runs each, same schema and scorer. August 2026.

The headline: space-ocr read 91.1% of the 463 fields to an exact match, averaged over three runs. Mistral's OCR annotations landed at 70.0%, its vision LLM at 73.5%. And in case the gap is formatting noise, we removed every mismatch that differed only by delimiters or spacing and counted content errors alone: roughly 23 per run for space-ocr against 119 and 93 for the two Mistral arms.

Here is the part worth understanding before you generalize: Mistral reads characters well. On the cleanest document in the set, a dense printed price sheet with 22 rows, Mistral OCR tied us at 139 of 141 fields. The gap opens where documents get structurally awkward. On the receipt that prints an item's name on one line and its quantity and price on the next, Mistral scored 2.3 of 13 fields per run; it folded the totals block into the item rows and could not pair the two lines. On a cluttered delivery slip it put quantities in the specification column. The characters were mostly right. The table they landed in was not.

Consistency was its own finding. Across three identical runs our per-run totals moved by 16 fields. Mistral OCR's moved by 100: the same document that scored 58 of 72 in one run came back at 3 of 72 in another, with every column of a 43-row table silently scrambled. Nothing in the response tells you which kind of run you just paid for.

Side by side: space-ocr draws 138 per-field boxes on a 22-row price sheet; Mistral returns a single block rectangle covering the whole table
The same price sheet through both engines. Left: one anchored box per field. Right: the entire table returned as a single block.

This image is the real argument, and it is invisible in any score table. On that price sheet space-ocr returned 138 individual boxes, one per field, each tied to the pixels it was read from. Mistral returned one rectangle for the whole table, because its response has no per-field coordinates at all, on any document; block outlines are as fine as it gets. There is also no verification signal of any kind. When a Mistral value is wrong, it is silently wrong, and the only way to find it is to check everything.

Every space-ocr value carries its box, a text_verified flag saying whether the characters under that box match, a needs_review flag with a machine-readable reason, and as of this release an ocr_confidence score and an optional label anchor for values that repeat on the page. The honest framing of this benchmark is not that Mistral cannot read; on clean dense print it can. It is that one of these APIs shows you which answers to trust, and the other asks you to trust all of them.

✓ Verified

How the verification works: the language model returns values plus word-token hints, never coordinates. The engine matches each returned value character by character against the symbols the OCR pass actually detected on the page, scores the match as match_ratio (0.85 and above counts as confident), and cross-checks the two engines against each other; disagreements become needs_review flags with reasons. Boxes are xmin/ymin/xmax/ymax, normalized 0 to 1000. One fairness note on the numbers above: the ground truth was frozen against our pipeline's output conventions, so every live engine, ours included, loses points on segmentation-boundary differences. Treat the absolute scores as floors and the relative comparison as the finding. The full method and all 72 raw runs are archived.

Pricing, since a benchmark post should say it plainly: a successful scan costs $0.05, a failed one is refunded automatically, and the first 100 pages every month are free, no card required. Run your own five documents through both APIs before you believe anyone's chart, including this one. The steps below are the exact procedure we used.

  1. Pick hard documents, not demos
    Choose 5 to 10 real pages that hurt: multi-line records, repeated values, photos of screens, dense tables. Clean samples cannot separate vendors.
  2. Freeze one schema and one instruction
    Write the field list once, with the same names and descriptions, and send it identically to every engine. Ask for values exactly as printed.
  3. Write the ground truth by hand
    Transcribe the expected value for every field before running anything, and do not edit it afterwards.
  4. Run each engine at least three times
    One run hides instability. Score every run with the same script and look at the spread, not just the mean.
  5. Count the silent errors separately
    For each wrong value, note whether the engine flagged it. A wrong value with a review flag costs a glance; a wrong value with no signal costs whatever your process built on top of it.
Is Mistral OCR bad at reading documents?
No. On clean dense print its character reading tied ours. The gap we measured is in document structure (pairing multi-line records, keeping table columns straight), in run-to-run stability, and in the absence of per-field coordinates and trust signals.
Can I reproduce this benchmark?
Yes. The corpus definition, the exact requests, the scoring script and all 72 raw outputs are archived. The post describes the full method: same images, same field schemas, same instruction, same scorer, three runs per arm.
Why should I trust a vendor's own benchmark?
Treat it as a starting point, not a verdict. We published the method, the caveats, and the case where Mistral tied us. The strongest evidence is the structural one you can verify in a single call: one API returns per-field coordinates and review flags, the other does not.
Does space-ocr win on every document?
No. On the cleanest printed table the two engines read the same number of fields. The differences that held across the corpus were structure handling, consistency between runs, and the verification layer.
What do per-field coordinates actually give me?
Auditability. A human can click a value and see exactly where it was read, review only the flagged fields instead of everything, and catch the wrong values before they reach a spreadsheet or an ERP.

Run your own benchmark

100 pages free every month. Every value comes back with its box and a trust verdict.