Markdown Is Not Structured Data
Mistral OCR is good at what it does. You give it a PDF or an image, it gives you back markdown. Tables become markdown tables. Headers become ##. Paragraphs become text. The OCR accuracy on clean documents is solid, and the API is straightforward.
But markdown is a representation format, not a data format. If you need the invoice total as a number, you’re parsing markdown. If you need line items as an array of objects, you’re parsing markdown. If you need to know whether the extracted date is actually a date and not a misread string — you’re writing validation logic on top of parsed markdown.
The OCR step is only half the problem. The other half is turning that text into something your application can use. And that half is where most of the engineering time goes.
The Parsing Gap
Here’s what a typical Mistral OCR integration looks like in practice. You call the API, you get markdown back, and then the real work starts.
An invoice comes back as something like:
## Invoice #INV-2024-0847
| Item | Qty | Unit Price | Total |
|---------------|-----|------------|----------|
| Widget Pro | 10 | $45.00 | $450.00 |
| Adapter Cable | 25 | $12.50 | $312.50 |
**Total Due: $762.50**
**Due Date: March 15, 2026**
That looks readable. It is readable — for a human. For your code, you now need to:
- Parse the markdown table into rows and columns
- Extract currency values from strings like “$450.00” and convert them to numbers
- Handle the bold-wrapped “Total Due” label
- Parse the date from a string into a proper date type
- Deal with the fact that different invoices use different markdown structures
You just traded one parsing problem (PDF) for another (markdown). The second one is easier, sure. But it’s still a parser you have to write, test, and maintain across every document variation you encounter.
Schema In, Structured Data Out
The Document Extraction API skips the markdown step entirely. You define a schema that describes what you want, and you get typed JSON back.
import { IterationLayer } from "iterationlayer";
const client = new IterationLayer({ apiKey: "YOUR_API_KEY" });
const result = await client.extract({
files: [{ url: "https://example.com/invoice.pdf" }],
schema: {
fields: [
{ name: "invoice_number", type: "text" },
{ name: "total_amount", type: "currency_amount" },
{ name: "due_date", type: "date" },
{ name: "line_items", type: "array", fields: [
{ name: "description", type: "text" },
{ name: "quantity", type: "integer" },
{ name: "unit_price", type: "currency_amount" },
]},
],
},
});
The response comes back as structured JSON. totalAmount is a number, not a string with a dollar sign. dueDate is a date, not “March 15, 2026” in whatever format the document happened to use. lineItems is an array of objects, not a markdown table you need to parse cell by cell.
No markdown-to-JSON conversion. No regex on top of OCR output. No custom parsing per document layout.
17 Field Types vs. Raw Text
Mistral OCR gives you text. What that text means is your problem.
Document Extraction has 17 purpose-built field types that handle interpretation and validation at the extraction step:
- TEXT and TEXTAREA for strings
- INTEGER and DECIMAL for numbers
- CURRENCY_AMOUNT and CURRENCY_CODE for financial data
- DATE, DATETIME, and TIME for temporal values
- ADDRESS decomposed into street, city, region, postal code, country
- IBAN with format validation
- ARRAY for repeating structures like line items
- BOOLEAN, EMAIL, COUNTRY, ENUM, and CALCULATED for everything else
When you define a field as CURRENCY_AMOUNT, you don’t get back "$1,234.56" — you get a numeric value. When you define ADDRESS, you get a structured object, not a block of text you have to decompose yourself. The extraction step does the work that would otherwise live in your application code.
Confidence Scores Change the Automation Calculus
Every field in a Document Extraction response includes a confidence score between 0.0 and 1.0. This is the difference between “best-effort text output” and “production-ready data pipeline.”
With Mistral OCR, you get markdown. If the OCR misreads a character or a table cell, the markdown just contains wrong text. You find out when a downstream process breaks or a human catches the error.
With confidence scores, you can build threshold-based automation:
- Above 0.90 — auto-accept, no human review needed
- Between 0.70 and 0.90 — flag for review
- Below 0.70 — reject or escalate
This turns document processing from a binary works-or-doesn’t pipeline into a graduated one. High-confidence extractions flow through automatically. Low-confidence ones get human attention. You control the tradeoff between speed and accuracy per field, per document type, per business requirement.
Source Citations
Every extracted value links back to where it was found in the source document. Your reviewers don’t have to hunt through a 40-page PDF to verify a flagged field — the citation points them directly to the relevant section.
This matters for compliance workflows, audit trails, and any scenario where you need to prove that an extracted value actually appears in the original document. Mistral OCR gives you the full text — finding where a specific value came from is a search problem you solve yourself.
Multi-File, Multi-Format
Mistral OCR processes one document at a time — PDFs and images. That covers many use cases, but not all of them.
Document Extraction accepts up to 20 files in a single request and combines them into one extraction result. A purchase order split across a PDF and two Excel attachments? One API call, one schema, one response. An insurance claim with a form, photos of damage, and a CSV export from the claimant’s system? Same thing.
The format support goes beyond PDFs and images:
- PDF, DOCX, XLSX, CSV
- JSON, HTML
- PNG, JPEG, GIF, WebP
This reflects how documents actually exist in the wild. Business data doesn’t live neatly in one PDF — it’s scattered across formats, attachments, and systems. A parser that only handles PDFs and images pushes the format-juggling work back to you.
Accuracy on Complex Layouts
OCR accuracy on clean, well-formatted documents is a solved problem. The hard cases are what separate tools: multi-column layouts, nested tables, forms with handwritten annotations, scanned documents with noise.
Independent benchmarks paint a clear picture. Reducto’s RD-FormsBench — a benchmark specifically designed for structured form extraction — tested multiple OCR and extraction services on complex form layouts. Mistral OCR scored around 45% accuracy. For comparison, Gemini-based extraction hit approximately 80% on the same benchmark.
These numbers matter because complex layouts are exactly the documents you need automation for. Simple, clean invoices from one vendor are easy to parse with anything — regex, templates, OCR. The messy documents from dozens of different sources, with inconsistent layouts and mixed content types, are where your parser earns its keep.
What You’re Actually Comparing
This isn’t really a comparison between two equivalent tools. It’s a comparison between two different steps in the pipeline.
Mistral OCR is an OCR engine. It converts visual documents into text. That’s a necessary step, and it does it well for straightforward layouts. But the text still needs parsing, validation, typing, and structuring before it’s useful to your application.
Document Extraction is an end-to-end extraction service. OCR is part of what happens internally, but the output is structured, typed, validated JSON — ready to use without intermediate processing. It’s the difference between getting ingredients delivered and getting a meal delivered.
If you already have robust parsing logic and just need better OCR, Mistral OCR might be the right tool. If you want structured data from documents without building and maintaining a parser — that’s what Document Extraction is for.
When to Use Which
Mistral OCR makes sense when:
- You need full-text markdown representation of documents
- You already have downstream parsing logic that works
- Your documents are clean, single-format, single-language
- You’re building search or retrieval systems where the full text matters
Document Extraction makes sense when:
- You need structured, typed data from documents
- You process documents from multiple sources with varying layouts
- You want confidence-based automation without custom validation
- You handle multi-file, multi-format document bundles
- You need audit trails with source citations
Get Started
Check the docs for the full schema reference, field type details, and API guides. The TypeScript and Python SDKs handle authentication, file uploads, and response typing — so going from “I have a document” to “I have structured data” is a few lines of code.
And because Document Extraction is part of a composable API suite, the structured data it returns flows directly into Document Generation or Image Generation — same auth, same credit pool, no glue code.
Iteration Layer runs on EU infrastructure (Frankfurt), which matters if your data residency requirements rule out US-hosted services.
Sign up for a free account, no credit card required. Try it on the documents that currently give your parser the most trouble.