PDF OCR Reliability Checker for RAG
Pricing
from $1,400.00 / 1,000 document processeds
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
Maintained by CommunityActor 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:
- the text, page by page;
- provenance — the page and bounding box of every line, in PDF points;
- 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. Treatocr_failedas "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 all | 32 of 157 — 20 % |
| Documents that come back completely empty without OCR | 5 of 12 |
| Documents partly scanned | 1 |
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
| Event | Price |
|---|---|
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.