Document Parsing API — turn any PDF into clean
Markdown & JSON
Layout, tables and reading order preserved. Structured input for your LLM, RAG or extraction pipeline — no templates, bring your own schema or none.
- 500 pages free
- No credit card
PDF to Markdown and
PDF to JSON
One call in, the whole document out — the same document, either format. Headings keep their level and the table keeps its columns and its per-column alignment; in JSON that table comes back as a header plus rows you can index, not a string you have to re-parse. Switch the tab to see both.
Full reference in the developer documentation · machine-readable index of the whole site at llms.txt
# Supplier Performance Review — Q2 2026
**Supplier:** Nordwind Logistik GmbH · **Contract:** NL-2026-114
**Period:** 2026-04-01 → 2026-06-30
## 1. Summary
On-time delivery improved to 96.4% (Q1: 91.2%). Two incidents were recorded,
both resolved inside the contractual 48-hour window.
## 2. Delivery performance
| Metric | Q1 2026 | Q2 2026 | Target |
| --------------------- | ------: | ------: | ------: |
| On-time delivery | 91.2% | 96.4% | 95.0% |
| Damage rate | 0.8% | 0.3% | < 0.5% |
| Avg. lead time (days) | 4.6 | 3.9 | 4.0 |
| Invoices disputed | 12 | 4 | < 5 |
## 3. Open actions
- [ ] Re-audit cold-chain packaging (owner: K. Brandt, due 2026-08-15)
- [x] Close incident INC-2026-0431
> Figures exclude the Hamburg depot, migrated 2026-05-12.{
"mode": "parse",
"pages": 1,
"markdown": "# Supplier Performance Review — Q2 2026\n\n**Supplier:** …",
"blocks": [
{
"type": "title",
"page": 1,
"confidence": 0.99,
"text": "Supplier Performance Review — Q2 2026"
},
{
"type": "group",
"page": 1,
"confidence": 0.98,
"text": "Supplier: Nordwind Logistik GmbH · Contract: NL-2026-114"
},
{
"type": "heading",
"page": 1,
"confidence": 0.99,
"text": "2. Delivery performance"
},
{
"type": "table",
"page": 1,
"confidence": 0.97,
"header": ["Metric", "Q1 2026", "Q2 2026", "Target"],
"rows": [
["On-time delivery", "91.2%", "96.4%", "95.0%"],
["Damage rate", "0.8%", "0.3%", "< 0.5%"],
["Avg. lead time (days)", "4.6", "3.9", "4.0"],
["Invoices disputed", "12", "4", "< 5"]
]
},
{
"type": "footer",
"page": 1,
"confidence": 0.94,
"text": "Figures exclude the Hamburg depot, migrated 2026-05-12."
}
]
} Reading order is preserved across the page, so the output follows the document rather than the coordinates of the text on it. Both formats ship in the same payload, so you don't have to choose: take the Markdown for anything that goes to a model and the blocks for anything programmatic.
Why structured parsing beats raw OCR text and DIY
A text-only OCR gives you characters and loses the document: no table, no reading order, no idea which line was a heading. A general-purpose model goes further and invents — it answers for every page, including the ones it could not read, and a confident wrong value is indistinguishable from a correct one. Parsing here is a pipeline, not a prompt: layout detection runs before any language model touches the page, every block carries its type and its position, and a read we cannot stand behind comes back flagged instead of tidied up.
Benchmarked against the obvious alternatives, with code: GPT-4o vs Claude vs Invofox for document parsing
The failure modes we see most often are collected in: document parsing pain points
Sending the PDF to a general-purpose model
one prompt, one answer
- Answers for every page, including the ones it couldn't read. When a region is illegible it writes something plausible rather than saying so.
- No structure you can depend on — the shape of the response shifts with the prompt, the page and the run.
- Nothing ties a line of output back to a place in the document, so no one can audit it later.
- Multi-column pages, merged table cells and footnotes get flattened into whatever reading order the model inferred.
- The vendor deprecates a model version and the same document parses differently next quarter.
Parsing with Invofox
a pipeline, not a prompt
- A region we can't read comes back flagged, or null. It is never filled in with a guess.
- Every document returns the same shape: typed blocks in reading order, plus the Markdown.
- Each block carries its type, its page and its position, so any output traces back to the spot it came from.
- Layout detection runs first, so columns, spanning headers, merged cells and footnotes survive as structure.
- Model changes are ours to absorb, and they ship behind an accuracy gate — not into your output unannounced.
Built for RAG and LLM pipelines
Parsing is the preprocessing step in front of a model: it turns a directory of PDFs into input a retrieval stack or an agent can actually work with. It's document-agnostic on purpose, so these are sorted by the job, not by document type — and none of them start with a list of fields.
-
Feeding a RAG index
Turn a document archive into Markdown your embedding pipeline can work with. Structure survives, so a table doesn't collapse into a wall of numbers and a heading still marks where a section begins.
-
Context for an agent
Hand an agent the document as text it can reason over, with the blocks labelled — instead of pasting raw OCR and hoping the model reconstructs the layout on its own.
-
Search and knowledge bases
Index the whole document, not the six fields somebody thought to put in a schema. People search for the clause, the footnote and the line item too.
-
Archive and migration
Move decades of scanned paper into a system that expects text. One pass, one output shape, no separate project per document type.
-
Human review and audit
Put the parsed blocks next to the page so a reviewer can see where a value came from, instead of reading the PDF and the JSON side by side and comparing by eye.
-
Document types you've never met
When a new format lands, parsing gives you something usable on the first call — before anyone decides which fields matter or writes a schema for it.
Parsing vs field extraction — which do you need?
The industry uses the word "parsing" for both, so people ask us for one and mean the other. The difference isn't quality or price — it's whether you can name the fields you want before you've seen the document.
Parsing
no schemaThe document's content and structure, whatever the document turns out to be.
A document. Nothing else — no schema, no field list, no template to draw.
The full document as Markdown, plus every block typed — title, heading, table, figure, footer — in reading order and anchored to its page.
The same shape for every document you send. A contract and a delivery note come back described the same way.
You don't yet know what you'll need from it: RAG, agents, search, migrating an archive, or reading a document type nobody has seen before.
Decide which values matter. It hands you the whole document — picking is your job, or extraction's.
Field extraction
your schemaThe specific fields you named, typed and validated before delivery.
A document and a schema — the fields you want, with their types.
Exactly those fields as JSON, with per-field confidence, programmatic validation and database checks applied before they reach you.
Your schema, exactly. The shape doesn't move when the layout does.
You know precisely what you need and something downstream is waiting for it — an ERP, an LOS, a payroll run, a ledger.
Return the parts of the document you didn't ask about.
Extraction has always run parsing first — it's step one of the same pipeline. What's new isn't the parser. It's that you can now take its output directly, instead of only the fields we built on top of it.
Formats, limits and what it costs.
The parts you'd otherwise have to book a call to find out.
- 500 pages free
Start without talking to us
No card, no call. The free tier runs the same pipeline as production — it isn't a reduced-accuracy demo.
- 2 output formats
Markdown and typed JSON
Markdown for anything that goes to a model; typed blocks when you need to address a specific part of the document programmatically. One call returns both.
- 0 templates
Nothing to configure per layout
No zones to draw, no per-vendor template to keep alive. A supplier redesigning their invoice doesn't become a support ticket.
Two things parsing deliberately does not do: chunk your text, and embed it. Chunk size is a function of your embedding model, your context window and your reranker — a parser that guesses those has made a decision you'll want to change. You get the structure with its boundaries intact; your retrieval stack owns the rest.
Questions worth asking us.
Still have questions? Talk to us