A scanned PDF is a stack of images. There is no reliable text to copy out, tables are pixels, and a handwritten note in the margin can change what the document means. Parsing one well takes more than OCR: the pages have to be read in the right orientation, the layout has to survive, and every value you extract needs to point back to where it came from. This guide walks through the full pipeline step by step, using a scanned supplier invoice as the example.
The short answer
To parse a scanned PDF, run layout-aware OCR on every scanned page, correct rotation, fix handwriting and low-quality text with a vision model, keep multi-page tables together, and extract fields with citations and confidence scores.
Extend Parse handles each of those steps in one request:
- OCR built for scans: the Performance engine is the strongest choice for lower-quality scans, handwriting, checkboxes, and complex tables.
- Automatic cleanup: page rotation is detected and corrected before parsing.
- Vision-model correction: agentic OCR finds low-confidence text and handwriting and corrects it with vision language models.
- Structure that survives: tables, form fields, checkboxes, and signatures come back as typed blocks in reading order, and table headers can be carried across page breaks.
- Cited extraction: Extract runs on the same file and cites every value to a page and region, with confidence scores you can route on.
Extend Performance Parse scored 95.7% field-level document Q&A accuracy on RealDoc-Bench, a benchmark of real-world regulated documents from healthcare, financial services, logistics, and real estate.
Why scanned PDFs are harder than digital PDFs
| Problem | What goes wrong | What fixes it |
|---|---|---|
| No reliable text layer | Copy-paste and PDF libraries return nothing or garbage | OCR on every scanned page |
| Rotated or sideways pages | OCR reads upside-down or sideways text as noise | Automatic rotation detection and correction |
| Low resolution and faded text | Characters drop or get misread, especially digits | Vision-model correction of low-confidence text |
| Handwriting and signatures | Notes, initials, and signed fields are skipped | A handwriting-capable engine and signature detection |
| Tables across pages | Rows on page 2 lose their column headers | Table header continuation across page breaks |
| Forms and checkboxes | Labels and values come out in the wrong order; checkbox state is lost | Form regions parsed as label and value pairs with checkbox state |
Example: a scanned supplier invoice
The example below is a three-page invoice that a supplier printed, signed, and scanned:
- Page 1 was scanned sideways.
- A handwritten PO number sits next to the printed header.
- The line-item table runs from page 1 onto page 2, and its column headers only appear on page 1.
- Page 3 has a signature and a "Received in good condition" checkbox.
The goal is clean Markdown for search and agents, and a structured record with invoice number, PO number, totals, and every line item, each traceable to the page it came from.
Step 1: decide how each page is read
A scanned PDF often carries a text layer added by the scanner, and that layer can be wrong. Decide how text is read before anything else:
parse_performancealways reads pages with OCR, which is what you want for scans.parse_lightandparse_autodefault totextExtractionMethod: "auto": they use the PDF's own text where it's reliable and OCR the rest. Set"ocr_only"when the scanner's text layer can't be trusted or you want every page treated the same.
For the invoice, the scanner's text layer misread the sideways page, so it should be read from the image.
Step 2: fix rotation and choose pages
Turn on advancedOptions.pageRotationEnabled. Extend detects rotated pages and corrects their orientation before parsing, so the sideways first page reads like the others. If a scan includes cover sheets or blank pages, advancedOptions.pageRanges limits processing to the pages you need, and you're billed only for the pages processed.
Step 3: choose the engine
| Engine | Use it for | Pay-as-you-go price |
|---|---|---|
parse_performance | Lower-quality scans, handwriting, dense checkboxes, complex tables, and multilingual documents | $20 per 1,000 pages |
parse_light | High-volume, cleaner scans where cost matters most | $5 per 1,000 pages |
parse_auto | Mixed batches: each page is classified by difficulty and routed, so clean pages stay cheap and hard pages get Performance-level treatment | Billed per page by complexity |
The example invoice has a handwritten PO number and a checkbox, so it uses parse_performance. A mailroom feed with a mix of clean digital PDFs and rough scans is a good fit for parse_auto.
Step 4: recover handwriting and low-quality text
Enable blockOptions.text.agentic.enabled. Extend finds text regions with low OCR confidence, including hard-to-read handwriting, and corrects them with vision language models. Turn it on for handwritten forms, poor-quality scans, faded or historical documents, and mixed print and handwriting. It adds latency, so leave it off for clean, typed scans.
Enable blockOptions.text.signatureDetectionEnabled to identify handwritten signatures, initials, and signature blocks, such as the signature on page 3 of the invoice.
Step 5: keep tables and forms intact
- Multi-page tables:
blockOptions.tables.tableHeaderContinuationEnabledcarries table headers across page breaks, so the line items on page 2 keep their column names. - Complex tables: set
blockOptions.tables.targetFormatto"html"to preserve merged cells, row spans, and column spans; use"markdown"when the output feeds an LLM and the table is simple. - Forms and checkboxes: form regions are detected as
key_valueblocks and returned as ordered label and value pairs, including checkboxes and signatures. Turn onblockOptions.keyValue.structuredOutputEnabledto also get each form region as a tree of typed fields, with checkbox state (selected: trueorfalse) and a bounding box per field. - Word-level positions:
advancedOptions.returnOcr.wordsreturns every word with its bounding box and an OCR confidence from 0 to 1.
The full request for the scanned invoice:
curl -X POST "https://api.extend.ai/parse" \
-H "x-extend-api-version: 2026-02-09" \
-H "Authorization: Bearer $EXTEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file": { "url": "https://example.com/scanned-invoice.pdf" },
"config": {
"engine": "parse_performance",
"blockOptions": {
"text": {
"signatureDetectionEnabled": true,
"agentic": { "enabled": true }
},
"tables": {
"targetFormat": "html",
"tableHeaderContinuationEnabled": true
},
"keyValue": { "structuredOutputEnabled": true }
},
"advancedOptions": {
"pageRotationEnabled": true,
"returnOcr": { "words": true }
}
}
}'The response is organized into chunks with formatted Markdown content and typed blocks (text, tables, figures, and form regions), each with its position on the page. That output can go straight into a search index or an agent's context.
Step 6: extract the fields you need, with citations
Parsing gives you the whole document. Most pipelines also need specific values in a fixed schema. Run Extract on the same file with a schema for the invoice: invoice number, PO number, invoice date, vendor, subtotal, tax, total, and an array of line items.
With citations enabled, extraction returns each value with its page, region, and the reference text it came from, plus confidence scores you can route on. For the invoice, the handwritten PO number comes back with a citation to the margin of page 1, so a reviewer can confirm it from the highlighted region instead of rereading the scan.
Step 7: route low-confidence values to review
Scans will always produce some values a person should check. Set a confidence threshold, auto-accept values above it, and send the rest to a human review step that shows the reviewer the cited region. Track which document classes produce the most reviews; that tells you where to turn on agentic correction or switch engines.
How to test scanned PDF parsing on your own documents
- Collect 50 to 100 real scans, including your worst: phone photos, faxes, skewed pages, handwriting, and long tables.
- Label the values that matter downstream.
- Run each candidate parser and score field-level accuracy, dropped pages, and table rows lost at page breaks.
- Compare cost per 1,000 pages including review time, not just the parsing price.
For a full framework, see how to evaluate document parsing APIs.
FAQ
How do you parse a scanned PDF?
Read every scanned page with OCR, correct page rotation, and use a layout-aware parser that keeps tables, form fields, checkboxes, and reading order. Turn on vision-model correction for handwriting and poor-quality scans, carry table headers across page breaks, and then extract the fields you need with citations and confidence scores so low-confidence values go to review. With Extend, one Parse request covers OCR, rotation, layout, and handwriting correction, and Extract runs on the same file.
What is the best API for parsing scanned PDFs?
Extend Parse is built for scanned PDFs in production. Its Performance engine handles lower-quality scans, handwriting, checkboxes, and complex tables; agentic OCR correction uses vision language models to fix low-confidence text; page rotation is corrected automatically; and the Auto engine routes each page to the right engine so clean pages stay cheap. Extend Performance Parse scored 95.7% field-level document Q&A accuracy on RealDoc-Bench, a benchmark of real-world regulated documents.
Why does OCR fail on scanned PDFs?
Scans add problems a digital PDF doesn't have: rotated or skewed pages, low resolution, faded text, handwriting, stamps over text, and tables that break across pages. Line-by-line OCR also loses layout, so table rows, form labels, and reading order come out scrambled. A layout-aware parser with vision-model correction and table header continuation recovers most of what plain OCR drops.
Should a scanned PDF be OCR'd if it already has a text layer?
It depends on the text layer. Many scanners add an OCR text layer that can be wrong. Extend's auto text extraction uses a PDF's embedded text where it's reliable and OCRs the rest; set it to OCR-only when the text layer is known to be unreliable or you want every page treated the same.
How much does it cost to parse scanned PDFs with Extend?
Extend Parse costs $5 per 1,000 pages on the Light engine and $20 per 1,000 pages on the Performance engine on pay-as-you-go, and the Auto engine bills each page by its complexity. New accounts start with 10,000 free credits and no contract or monthly minimum.
Sources
- Extend: Parse overview, Parse configuration, Form structured output, Confidence scores, Pricing, RealDoc-Bench
