PDF OCR Reliability Checker for RAG avatar

PDF OCR Reliability Checker for RAG

Pricing

from $1,400.00 / 1,000 document processeds

Go to Apify Store
PDF OCR Reliability Checker for RAG

PDF OCR Reliability Checker for RAG

Extract text from native and scanned PDFs for RAG pipelines. Every line keeps its page and bounding box, while every page receives a reliability verdict and actionable warnings. Mixed PDFs are handled page by page, so incomplete extraction does not look like success.

Pricing

from $1,400.00 / 1,000 document processeds

Rating

0.0

(0)

Developer

Jeremy Laidi

Jeremy Laidi

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Document → text with page, position and a reliability verdict

Three things for every document:

  1. the text, page by page;
  2. provenance — the page and bounding box of every line, in PDF points;
  3. a reliability verdict per page, with the thresholds published so you can check the call instead of trusting it.

Native text layer and OCR are decided per page, not per document — a report with a clean first page and scanned annexes is common, and treating it as one thing loses either the annexes or the accuracy.

What you get back

{
"url": "...",
"ok": true,
"pagesTotal": 9, "pagesProcessed": 2, "pagesOcr": 2,
"language": "fra",
"usablePagesRatio": 1.0,
"medianLexicalValidity": 0.772,
"warnings": [],
"pages": [{
"page": 1, "source": "ocr",
"reliability": { "verdict": "good", "words": 312,
"wordShapeScore": 1.0, "lexicalValidity": 0.772,
"lexiconChecked": true, "ocrConfidence": 93.1 },
"lines": [{ "text": "PROCES VERBAL", "bbox": [230.6, 22.1, 347.8, 33.8] }]
}],
"markdown": "<!-- page 1 | ocr | good -->\n..."
}

verdict is one of good, fair, poor, empty, ocr_failed.

ocr_failed is not empty. A blank page and a page the engine could not read are different facts, and conflating them is how a document silently loses half its content. When recognition fails, the verdict says so and carries the underlying error.

If you are an agent deciding whether to call this

Call it when you have a PDF whose content you will quote, cite or act on, and being wrong is expensive — contracts, public records, invoices, reports — and especially when you do not know whether the file is a clean export or a scan.

Do not call it when you only need rough text from a known-good digital PDF and cost matters more than certainty. Cheaper extractors do that job and do it well. Do not call it for HTML pages: this reads PDFs.

What you get to decide with:

  • usablePagesRatio — how much of this document you can rely on. 1.0 means every page passed.
  • warnings — names the pages that did not, in plain language.
  • pages[].reliability.verdict — per page: good, fair, poor, empty, ocr_failed. Treat ocr_failed as "this page exists and could not be read", never as a blank page.
  • thresholds — the exact rule behind every verdict, returned with the response so you can apply your own standard instead of ours.

Cost: $2.00 per document, plus $0.05 per scanned page actually recognised. A document that fails is not charged.

Escalation rule that works: if usablePagesRatio is below 1, do not summarise the document as if it were complete. Name the missing pages to the human, or fetch a better copy.

Why this exists — measured on 12 real documents

A corpus of 12 French municipal records, 157 pages, all public:

Pages with no text layer at all32 of 157 — 20 %
Documents that come back completely empty without OCR5 of 12
Documents partly scanned1

That last one is the case that costs you. It runs to 52 pages, 17 of them with no text layer. A text-layer-only extraction returns 7,842 characters from it: no error, no warning, apparently a success — with a third of the document silently missing.

This actor reads those pages, and says per page how far to trust what it read. The corpus and the measurement are reproducible: the documents are public records, the test is "does this page carry a text layer".

Where this sits, honestly

Confidence scores and bounding boxes are not new. Dedicated document-AI platforms — Reducto, LlamaParse, Nutrient, Unstructured, Docling, and the hyperscaler services — have offered them for years, and if you are choosing a document platform you should look at those first. This is not a category challenger and does not pretend to be.

What it is: that behaviour inside Apify, at a flat per-document price, with one property those services do not all give you — a failed recognition is never reported as an empty page, and the thresholds behind the verdict are returned with every result so you can check the call instead of trusting it.

An agent cannot tell good extraction from bad. It will summarise, cite and act on either. The verdict gives it a decision it can make: retry, escalate to a human, or trust the page.

Verdicts are computed from three independent signals — the engine's own confidence, the share of tokens shaped like real words, and validity against a dictionary for the detected language. None is sufficient alone: confidence is flattering on regular noise, word shape misses wrong digits, a dictionary misses proper nouns. If no dictionary exists for the detected language, the verdict is capped at fair — the best grade is not awarded on a check that was not performed.

Measured, not claimed

On a controlled pair (the same document with a text layer, then scanned), 10 lines out of 10 matched, with a provenance gap of 0.6 pt horizontally and 3.8 pt vertically — under 1.5 mm. The vertical offset is systematic: a text layer box includes ascenders and descenders, an OCR box hugs the ink.

On 6 real French municipal records (11 pages, 6 native, 5 scanned): OCR confidence 87.3–94.3, lexical validity 0.708–0.795 against 0.681–0.823 for the native pages of the same corpus. OCR performs at the level of the document's own text layer — it is not a fallback.

Thresholds are returned with every result. They were set before measurement and recalibrated once, downward, for a stated reason: the native text layer of real administrative documents scores 0.68–0.82, so demanding 0.80 of OCR would demand more than the document contains. The ceiling is the text layer, not 1.0.

What this does not do

lexicalValidity checks that words exist, not that they are the right ones. A misread figure stays invisible to it: 12000 read as 72000 is perfectly lexical. For any number you intend to rely on, the verdict is not a substitute for a human check. Real errors seen in output: Eeletons for Égletons, 3°ME for 3ÈME.

Languages shipped: French, English, German, Spanish, Italian, Dutch.

By default the fetch honours robots.txt. ignoreRobotsTxt exists for documents you own or are authorised to fetch — the choice, and its consequences, are yours.

Pricing

EventPrice
document — one per document successfully read$2.00
ocr-page — one per scanned page actually recognised$0.05

A failed document is never charged. A page whose recognition failed is not charged as an OCR page. A ten-page scan costs $2.50; a native PDF of any length costs $2.00.