Working demo · built in n8n

Scan in. Searchable PDF and indexed fields out.

Four scanned documents — an English invoice, a contract page, a Spanish delivery note and a handwritten-field expense claim — went through a single pipeline: stored, OCR'd, classified, extracted, validated and indexed. None of them had a text layer. Every figure below was pulled out of an image.

2:10, no audio. The middle section is the actual pipeline running, not an animation.

The four stages

1 · StoreThe original upload is written once and never modified. Audit trails and re-processing when the OCR engine improves both depend on that.
2 · OCRRuns on a copy, producing a text layer and a searchable PDF. The original stays exactly as it arrived.
3 · Extract + validateThe model classifies and proposes fields; deterministic code then re-checks totals against numbers actually in the text, catches impossible dates and scores confidence.
4 · IndexOne row per document: type, language, counterparty, number, dates, total, confidence, flags, summary, links and a text snippet. That row is what makes retrieval work.

What came out

documenttypelangcounterpartynumberdatetotalOCR chars
Supplier invoiceinvoiceenHalverson Architects LtdINV-2026-04172026-09-14GBP 2,086.80710
Contract pagecontractenMeridian Health / Calder Systems—2026-10-01USD 84,000.00988
Delivery notedelivery_noteesHostelería del Norte S.A.ALB-99312026-09-18EUR 3,613.50681
Expense claimexpense_claimenFieldstone Engineering—2026-09-29388.59 (currency not stated)686

What it refused to be confident about

This is the part that separates extraction from guessing. Each document carries its own review flags:

documentflags raised
Supplier invoiceVAT number contains spaces; bank sort-code/account separator ambiguous
Contract pageNo document number present; three candidate dates (commencement and two signatures); the $84,000 is an annual licence fee, not a total contract value
Delivery noteCustomer tax ID not stated; unit prices absent, only line totals; signature line present but nothing captured
Expense claimCurrency never stated in the document; line-item dates have no year; employee name field ambiguous in the OCR order

The source scans

Image-only PDFs with scan artefacts — rotation, blur, speckle. Zero text layer. Open any of them and try to select text:

Invoice (EN) Contract page (EN) Albarán / delivery note (ES) Expense claim (EN)

How this scales to the platform

This is the processing core, not the product. Scaling it is orchestration rather than new science: swap the OCR engine for Tesseract or a commercial SDK inside isolated containers and the pipeline is unchanged; replace the loop with a queue and a worker pool, which is where a 99.5% success rate is actually won or lost; expose the same engine through the API that the per-tool SEO pages call, so consumer tools and automation share one implementation; and attach deletion policy, regional processing and audit logging to the index row rather than to the app. Conversion engines are commodities — the orchestration, the cost per operation and the failure handling are the product.