Image OCR Text Extractor for Scanned Files avatar

Image OCR Text Extractor for Scanned Files

Pricing

Pay per event

Go to Apify Store
Image OCR Text Extractor for Scanned Files

Image OCR Text Extractor for Scanned Files

Recognize printed English and Russian text in authorized PNG, JPEG or scanned PDF files: page text, word boxes, confidence and clear size or timeout notices.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Tim Zinin

Tim Zinin

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 hours ago

Last modified

Categories

Share

Recognize printed English and Russian text from authorized PNG, JPEG or scanned PDF files, with page output, word boxes, confidence and explicit size or timeout notices.

Evidence status (2026-09-05). The actor was built on the Apify platform (build AavGtlq39X4eN7xMS), its pay-per-event tariff was read back from the platform, and five private acceptance runs on Apify infrastructure produced the rows shown in this document: an English page, a Russian page, a blank page, an image above the pixel limit and a scanned PDF capped at one page.

R1. What you get

Recognize printed English and Russian text from an authorized PNG, JPEG or scanned PDF and receive one record per complete nonempty page. Each result includes the recognized text, word bounding boxes, per-word confidence, mean confidence, actual image dimensions and engine version. This lets an importer retain page evidence and send uncertain text for human review instead of treating every recognition as equally reliable.

The actor uses Tesseract with installed English and Russian language models. It does not call a language model, remote OCR API or another actor. It does not translate text, infer document meaning, reconstruct spreadsheet tables or promise handwriting recognition. Confidence is an engine score rather than a probability that a name, amount or source statement is correct.

A plain image has one page. A PDF is rasterized page by page at the documented150DPI policy and then recognized. Complete nonempty pages are useful units even when a later PDF page fails or a page cap leaves a remainder. The actor keeps those completed page results and adds a free partial/error notice; it never charges a partly returned text fragment as a complete page.

R2. Who uses it

Archive operators can turn their own printed scans into searchable text while keeping page and word coordinates for review. Developers can add a bounded OCR stage after a digital-PDF extractor reports that a file has no usable text layer. Teams receiving controlled scanned forms can build a staging workflow that stores recognized words separately from any business interpretation of those words.

The strongest fit is clean printed English or Russian material with known ownership, sufficient resolution and a simple page layout. A representative pilot should include the actual fonts, compression, orientation and background quality your source produces. An easy synthetic marker is useful for regression, but it is not a measured accuracy benchmark for an invoice archive or historical collection.

A poor fit is a workflow that requires guaranteed field extraction, handwriting support, automatic translation, complex reading-order reasoning or error-free interpretation of consequential values. The actor returns OCR evidence. Your receiving application must decide whether confidence, formatting and source quality are adequate for its own use and when a person should compare the result with the original image.

R3. How to run

Choose Try, inspect the input form, keep the small fixture prefill for your first check, and select Start. After the run, open Dataset for records and the default key-value store's OUTPUT record for the summary. Download JSON if you need to preserve nested arrays, numeric values, booleans and nulls. A spreadsheet export can hide those distinctions, so use CSV as a presentation format rather than the authoritative conversion archive.

Replace the fixture URLs with direct public HTTP or HTTPS download URLs for files you own or are authorized to process. A document viewer URL, cloud-drive preview or login page is not necessarily a download. Test your final URL without your browser's authenticated session. This actor sends no browser cookies and accepts no username/password URL. If a file service requires a signed query string, keep the run and output private: source URLs are included in provenance and may expose that temporary access link to anyone who can read the dataset.

Keep input and result limits small until a representative file succeeds. Then save the exact input as a task. A task stores configuration; it does not change the actor's hard safety bounds. For recurring work, connect that task to Apify's existing scheduling feature and choose a frequency that matches your document publication cycle. The actor does not create schedules, messages, tickets or workflows on your behalf.

Inspect both useful records and free notices before adding automation. A successful process status is not a count of useful documents. Conversely, a run that later fails can retain useful records already delivered. Save the run ID, build version, input, dataset ID and OUTPUT summary together so a colleague can reconcile the actual observation without inferring it from a screenshot or a file name.

The prefill is ocr-en.png with languages:["eng"], maxPagesPerFile1 and maxPixelsPerPage5000000. It is an original1400×500 printed image containing WAVE-A OCR ENGLISH MARKER. The local proof also runs the Russian fixture with languages:["rus"], a white blank image, a two-page raster PDF with cap1 and an exact pixel-overflow image.

For Russian input, choose rus; for mixed English/Russian pages, choose both eng and rus. This selects recognition models and does not translate output. Start with one representative page before creating a larger batch. Review the full text and a few boxes against the source image, then decide what confidence or review policy belongs in your own downstream workflow.

R4. Pricing

The price is $0.005 per start + $0.008 per recognized page, read back from the platform tariff on 2026-09-05 (apify-actor-start $0.005, result-found $0.008, model PAY_PER_EVENT). One useful image page in a run is $0.013; five useful pages are $0.045; ten useful pages in one permitted batch are $0.085. A blank or failed page has no result event. Those arithmetic examples are not receipts.

The primary paid unit is one complete nonempty recognized page, whether supplied as an image or as a page of a PDF. A complete useful record is delivered with one named result-found event in the same Actor.pushData call. There is no separate request to charge a result and no page/cell/text-fragment surcharge hidden inside the record. A free notice has found:false and resultCount:0, and is written without a result event. You can therefore see more dataset rows than paid results.

Platform evidence for the tariff above (charged event counts of the accepted runs): English page aNRv2FYPLcG8eZKa6 result-found: 1; Russian page W8Y2B4tQJhiHtTSd7 1; blank page c4n6orsiMNgOuWnJn 0; image above the pixel limit esvzig43UNgR7MQAA 0; scanned PDF dogY4aJpl8X8v0Jtj 1. The start event is charged once per GB of run memory: the default run pays one start unit per GB, while the acceptance runs were started with 4096 MB and therefore show apify-actor-start: 4. Keep the default memory unless a large scan needs more; a different memory setting changes the start charge shown by the platform, not the meaning of a result event.

At runtime the actor reads actual pricing from the initialized Apify SDK. A platform run with unreadable pricing, no positive result-found price, invalid event prices, or a priced automatic dataset-item event fails closed. The actor will not use an explanatory dataset write if that write could itself be billable. In that situation the explanation is in the run log and failed status. A start event may already exist, so a failure is not a promise of a zero invoice.

The remaining budget is checked immediately before a paid write, inside the same lock as the write. This matters at the boundary: a cap one microdollar below the next complete unit must not be rounded up to buy that unit. Concurrent calls share the lock, and the last paid record still counts if the SDK returns an event-limit flag with its successful write. Subsequent paid work stops; previously delivered records remain available.

If storage or charging fails during a paid write, the result can be uncertain. A row may have reached storage before the charge acknowledgement failed. The actor stops, records deliveryUncertain and fails the run; it does not retry the same row automatically. Inspect the dataset and charged event counters before rerunning that input. There is no persistent replay ledger, so a new successful run can deliver and bill the same file contents again.

Set a run budget independently of input caps. An input cap bounds document processing; a monetary cap bounds additional result events. Neither is a quota for the other. A tiny budget can prevent delivery even when the parser produced useful content, while a large budget does not permit files beyond byte, page, cell, pixel or runtime bounds. Use requested/processed/unprocessed and delivered/paid/free together when explaining that difference to your team.

R5. Input contract

FieldPrefillContract
fileUrls["https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-en.png"]One to three public HTTP(S) files you are authorized to process. PNG, JPEG or PDF, <=10MB each; no credentials, fragments or private addresses. The prefill is an original EN image.
languages["eng"]Installed Tesseract recognition models. Select eng, rus or both. This configures recognition; it does not translate or detect each word language.
maxPagesPerFile1Images have one page; scan PDFs can yield up to five complete pages. Across the input files * this cap must be <=10. Remaining pages produce a free partial notice.
maxPixelsPerPage5000000Pixel limit before image decoding or PDF rasterization. PDF dimensions are checked at150DPI; oversized pages are refused, not silently cropped or reduced to fit. Maximum5MP.

Every field is validated before expensive work. Unknown properties, wrong types and oversized arrays are rejected; numeric strings are not silently coerced to integers. Arrays of source URLs are checked before any multiplicative resource limit. URLs must be absolute, at most2048 characters, HTTP or HTTPS, with no credentials or fragment. Duplicate identical normalized URLs in the same input are processed once; query parameters are retained because they can select a different file or grant access to a particular version.

Private, loopback, link-local and cloud-metadata addresses are refused. This applies to numeric addresses, unusual IPv4/IPv6 spellings, DNS answers and redirect destinations. The connection is pinned to the verified DNS addresses so a second lookup cannot redirect the socket to a private address. A public-looking name is not sufficient evidence that its resolved address is safe. The same transport protects robots requests and the actual file download.

A file can redirect at most five times. Every hop is checked before a connection, and each new origin has its own robots check. The actor follows normal public redirects without adding authentication. It retains the requested URL in input and the final file URL in sourceUrl, with redirect evidence where applicable. If the final destination is private, robots-disallowed or inaccessible, the result is a free error and the last known good downstream record should remain intact.

The download cap is checked against Content-Length when available and against received bytes while streaming. The streaming check is essential: a server may omit the header, advertise a compressed size or provide an incorrect length. The bounded downloader handles bytes directly. It does not run a binary document through a text decoder and then attempt to reconstruct it. All parsers receive the exact downloaded binary buffer after transport-level decompression.

Robots is checked per origin. A404 robots response means no published rules were found; it is not a copyright license. A disallow rule prevents the file request. Invalid, unavailable or blocked robots does not trigger a permissive fallback. File access401/403 is not bypassed. Requests, redirects, retries and robots retrieval share a maximum rate of one request per second per host. Providing more URLs does not increase per-host concurrency.

OCR-specific bounds:1–3 file URLs,1–5 maximum pages per file and file-count×page-cap no greater than10. PNG and JPEG are single images; multipage image containers and animated PNG are outside the contract. Downloads are limited to10,000,000 bytes per file and30,000,000 bytes across the run. The pixel limit is configurable from10000 through5,000,000 per page.

Image dimensions are checked from bounded PNG/JPEG metadata before native image decoding. A valid PNG containing5,000,001 pixels is refused before the OCR command runs. The actor does not resize that image down to fit without telling you. If your authorized image exceeds the contract, prepare an appropriately sized source through your own image pipeline and keep that transformation separate from the original file identity.

PDF page dimensions and rotation are inspected before rasterization. At150DPI, the proposed output width and height are calculated from page geometry. A page whose resulting raster exceeds the pixel cap is rejected before pdftoppm. Explicit target dimensions bound raster allocation, and the generated PNG is checked again before OCR. Returned boxes refer to this actual raster, not to PDF point coordinates or a viewer's zoom level.

One30-second deadline covers rasterization and OCR together for each PDF page; an image page uses that deadline for recognition. PDF metadata inspection has a separate bounded10-second stage within the overall240-second work deadline. A page does not receive another full30 seconds just because its rasterization already consumed most of its budget.

The text limit is100000 extracted characters per page, with at most10000 nonempty words and a2MB serialized page record. Subprocess output is bounded before TSV parsing. A page that exceeds text, word or output limits yields a free error with no partial paid text. Temporary source and raster files are removed after completion or failure; the actor does not retain them as an archive of the input.

R6. Real happy, partial and failure output

The examples below are dataset rows from private acceptance runs executed on Apify infrastructure on 2026-09-05 with the deployed build and the live tariff. They are unedited except the words arrays, which are shortened for display with a marker string inside the array; the run datasets hold every word box. The source files are the hosted Wave A fixtures (syntheticFixture:true), generated with fixed control phrases rather than customer material.

The first JSON block contains the literal production prefill. The blocks after it are the actual rows of the accepted runs, one run per fixture: Examples A, B and E are paid recognized pages, Examples C and D are the two free notices; run dogY4aJpl8X8v0Jtj also delivered a free partial notice for the second page beyond maxPagesPerFile=1 (not shown).

{
"fileUrls": [
"https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-en.png"
],
"languages": [
"eng"
],
"maxPagesPerFile": 1,
"maxPixelsPerPage": 5000000
}

Example A — English page, paid (result-found counted once). Run aNRv2FYPLcG8eZKa6.

{
"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-en.png",
"sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-en.png",
"found": true,
"status": "ok",
"resultCount": 1,
"partial": false,
"error": "",
"warnings": [],
"checkedAt": "2026-09-05T19:13:39.109Z",
"schemaVersion": "1.0",
"fileId": "39d685d9383f5fe8fb9fce67ddb474409bf089928e86547a80e059148b986f7f",
"sha256": "39d685d9383f5fe8fb9fce67ddb474409bf089928e86547a80e059148b986f7f",
"filePageCount": 1,
"pageNumber": 1,
"text": "WAVE-A OCR ENGLISH MARKER\nORIGINAL SYNTHETIC DOCUMENT\nNUMBER 12345",
"language": "eng",
"meanConfidence": 91.5169,
"words": [
{
"text": "WAVE-A",
"confidence": 91.194489,
"bbox": {
"x": 61,
"y": 74,
"width": 176,
"height": 33
}
},
{
"text": "OCR",
"confidence": 89.975922,
"bbox": {
"x": 249,
"y": 73,
"width": 99,
"height": 35
}
},
"display-shortened: 7 more word boxes omitted here; the run dataset holds all 9"
],
"imageWidth": 1400,
"imageHeight": 500,
"engineVersion": "5.5.1",
"syntheticFixture": true,
"redirectChain": []
}

Example B — Russian page, paid. Run W8Y2B4tQJhiHtTSd7.

{
"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-ru.png",
"sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-ru.png",
"found": true,
"status": "ok",
"resultCount": 1,
"partial": false,
"error": "",
"warnings": [],
"checkedAt": "2026-09-05T19:13:44.945Z",
"schemaVersion": "1.0",
"fileId": "b0a333c7d20236aabfd747aa2a8f8d7f9ddfb2c6e769eb1c4b1e40a886f4bd45",
"sha256": "b0a333c7d20236aabfd747aa2a8f8d7f9ddfb2c6e769eb1c4b1e40a886f4bd45",
"filePageCount": 1,
"pageNumber": 1,
"text": "ПРОВЕРКА РУССКОГО ТЕКСТА\nТЕСТОВЫЙ ДОКУМЕНТ\nНОМЕР 12345",
"language": "rus",
"meanConfidence": 92.394,
"words": [
{
"text": "ПРОВЕРКА",
"confidence": 92.066078,
"bbox": {
"x": 64,
"y": 73,
"width": 244,
"height": 35
}
},
{
"text": "РУССКОГО",
"confidence": 90.212395,
"bbox": {
"x": 325,
"y": 73,
"width": 240,
"height": 35
}
},
"display-shortened: 5 more word boxes omitted here; the run dataset holds all 7"
],
"imageWidth": 1400,
"imageHeight": 500,
"engineVersion": "5.5.1",
"syntheticFixture": true,
"redirectChain": []
}

Example C — blank page, free not_found. Run c4n6orsiMNgOuWnJn.

{
"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-blank.png",
"sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-blank.png",
"found": false,
"status": "not_found",
"resultCount": 0,
"partial": false,
"error": "",
"warnings": [],
"checkedAt": "2026-09-05T19:13:49.235Z",
"schemaVersion": "1.0",
"fileId": "6ca1ee8c99f3031de489f108897e514d5c2d6ac1ad47cc1bac6463821a4631d9",
"sha256": "6ca1ee8c99f3031de489f108897e514d5c2d6ac1ad47cc1bac6463821a4631d9",
"filePageCount": 1,
"pageNumber": 1,
"text": "",
"language": "eng",
"meanConfidence": null,
"words": [],
"imageWidth": 1400,
"imageHeight": 500,
"engineVersion": "5.5.1",
"syntheticFixture": true,
"redirectChain": []
}

Example D — image above maxPixelsPerPage, free limit_exceeded notice. Run esvzig43UNgR7MQAA.

{
"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-over-limit.png",
"sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-over-limit.png",
"found": false,
"status": "limit_exceeded",
"resultCount": 0,
"partial": true,
"error": "Image 5000001x1 exceeds pixel limit 5000000 or has invalid dimensions",
"warnings": [],
"checkedAt": "2026-09-05T19:13:53.724Z",
"schemaVersion": "1.0",
"fileId": "8932ca21e868cd7feca0d158bd96cc04f64f3574ac5b5ecc6cad506dde9e874b",
"sha256": "8932ca21e868cd7feca0d158bd96cc04f64f3574ac5b5ecc6cad506dde9e874b",
"filePageCount": null,
"pageNumber": null,
"text": "",
"language": "eng",
"meanConfidence": null,
"words": [],
"imageWidth": null,
"imageHeight": null,
"engineVersion": "5.5.1",
"syntheticFixture": true,
"redirectChain": []
}

Example E — scanned PDF page, paid. Run dogY4aJpl8X8v0Jtj.

{
"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-scan.pdf",
"sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/ocr-scan.pdf",
"found": true,
"status": "ok",
"resultCount": 1,
"partial": false,
"error": "",
"warnings": [],
"checkedAt": "2026-09-05T19:13:58.716Z",
"schemaVersion": "1.0",
"fileId": "fdbd82b6b51454d44b6d7e595fa5bf29547a972cb21e0b6c06a18fcd956e9417",
"sha256": "fdbd82b6b51454d44b6d7e595fa5bf29547a972cb21e0b6c06a18fcd956e9417",
"filePageCount": 2,
"pageNumber": 1,
"text": "WAVE-A OCR ENGLISH MARKER\nORIGINAL SYNTHETIC DOCUMENT\nNUMBER 12345",
"language": "eng",
"meanConfidence": 91.2542,
"words": [
{
"text": "WAVE-A",
"confidence": 91.411591,
"bbox": {
"x": 61,
"y": 74,
"width": 176,
"height": 33
}
},
{
"text": "OCR",
"confidence": 91.613892,
"bbox": {
"x": 249,
"y": 73,
"width": 99,
"height": 35
}
},
"display-shortened: 7 more word boxes omitted here; the run dataset holds all 9"
],
"imageWidth": 1400,
"imageHeight": 500,
"engineVersion": "5.5.1",
"syntheticFixture": true,
"redirectChain": []
}

R7. Field dictionary

input

string: requested normalized file URL, preserved even after redirects. Keep it with the task input; it is not necessarily the final download address.

sourceUrl

string: final public response URL used by the parser, or requested URL when no response was available. Treat query strings as potentially sensitive provenance.

found

boolean: true only for one complete useful paid unit. A row can exist with found:false because free explanations also use the dataset.

status

string: domain outcome listed below. Consumer routing should check status together with found, partial and error.

resultCount

integer: one for a complete useful unit, zero for a free notice. It is not the number of pages, words, sheets or cells nested in that unit.

partial

boolean: this row describes an incomplete observation or a limit. The run can still be partial while a particular completed row is not.

error

string: empty on useful completion and clean absence; nonempty on access, transport, format, resource or parsing failure. Do not erase it during export.

warnings

array of strings: bounded explanatory limitations or source details. A warning does not by itself imply a failed or billable record; inspect the documented outcome.

checkedAt

ISO8601 UTC string: time the actor produced this observation, not source creation/publication time or a certification of freshness.

schemaVersion

string: currently1.0. Use it when validating downstream shapes and retain the actor build identifier alongside your export.

syntheticFixture

boolean: whether the supplied source belongs to our named hosted fixture prefix. An arbitrary customer document is not synthetic simply because it contains the same marker.

fileId and sha256

The lowercase SHA256 of the downloaded original image or PDF bytes. For a PDF, all page records share the same file identity. It is not the hash of the intermediate raster or recognized text. A recompressed image or regenerated PDF can change this value while looking similar to a reader; use your own content comparison if that distinction matters to the workflow.

filePageCount and pageNumber

filePageCount is1 for a supported single image or the known total number of pages in a parsed PDF. pageNumber is the one-based physical page that was recognized or refused at the page-processing stage. A file-level source or early-format error can have a null page number because no page could safely be identified. A free remainder notice can likewise have pageNumber:null while reporting a known filePageCount.

text

The complete recognized text for that page, assembled from returned word rows in Tesseract's line groups. It can contain line breaks. It is not HTML, Markdown, a reconstructed table or a guaranteed semantic reading order. Text remains source-derived data and is never treated as a command, a formula to evaluate or an instruction to fetch another URL.

A blank recognition has text:"" with found:false,resultCount:0,error:"" and words:[]. A failed or over-limit page also contains no recognized text in the free notice but carries a nonempty error. Consumers must use status/error to distinguish those two cases rather than branching only on text length.

language

A string describing the requested model combination: eng, rus or eng+rus in the supplied deduplicated order. It is not the detected language of each word and does not indicate translation. Mixed-model output can still contain recognition errors. Recheck a representative page when changing languages because model selection can change word spelling and segmentation.

words

An array of objects containing text, confidence and bbox. Each text is a nonempty recognized word as emitted by the engine. confidence is a finite score from0 to100. The actor does not promise stable word segmentation across different engine versions, page resolutions or language selections, so array index is an observation-local position rather than a permanent semantic word identifier.

bbox contains x,y,width,height in integer pixels. x and y identify the top-left corner in the actual image coordinate system, with y increasing down the image. Width and height are positive; every rectangle must stay within imageWidth×imageHeight. The actor validates these invariants and rejects a malformed engine result rather than exporting a misleading out-of-bounds box.

meanConfidence

The unweighted arithmetic mean of the returned nonempty words' confidence values, rounded to four decimal places. It is null when there are no recognized words. It is not a calibrated probability, a character-accuracy percentage or a guarantee that a specific amount is correct. A page with one uncertain critical word can have a high overall mean because many ordinary words were easy to recognize.

imageWidth and imageHeight

The actual recognition-image dimensions in pixels. For PNG/JPEG they come from the accepted image metadata. For PDF they describe the bounded generated raster after the150DPI policy and rotation handling. A file-level refusal can leave them null. Multiplying two present dimensions gives the page pixel count; neither dimension nor the number of word boxes is a separate billing quantity.

engineVersion and redirectChain

engineVersion is read from the executable used for that run. The accepted platform rows record Tesseract 5.5.1 from the Alpine image; the local proof records Tesseract5.5.2 on Mac; the prepared container pins a different verified package version and still needs its own acceptance. Do not relabel the local output as a container5.5.1 result. redirectChain records file-download redirects, while sourceUrl records the final source used. Rasterization itself does not add network redirects.

R8. Evidence and boundaries

The fixtures are generated from original printed control phrases rather than downloaded customer or third-party scans. A white PNG establishes clean absence. The scan PDF contains two pages made only from raster images, with no text layer supplied to OCR. The extra ocr-over-limit.png is structurally valid and has exactly5,000,001 pixels, making the negative result a size-policy test rather than merely an invalid-file error.

The actual local proof uses Tesseract5.5.2 and Poppler26.03.0 installed on the developer Mac, including eng/rus models. It verifies marker recovery, word-box bounds, empty behavior, PDF page handling and output semantics. It does not measure the prepared Linux image, platform startup or Apify compute cost.

The published apify/actor-node:20 image was inspected and is Alpine3.23.4. The Dockerfile therefore keeps that base and installs exact Alpine packages through apk: Tesseract5.5.1-r0, its eng/rus data packages5.5.1-r0 and Poppler25.12.0-r0. The requested apt command is incompatible with that base. This build records the difference explicitly; Docker is unavailable locally, so the first container execution belongs to Claude's platform acceptance.

For accepted cloud evidence, preserve build ID, original SHA, language choice, pixel/page limits, engine version, full dataset rows, OUTPUT and chargedEventCounts. Compare a representative real owned document in addition to the synthetic prefill. A changed engine can alter words and confidence while the input hash stays identical; that is an extraction revision, not a source-byte revision.

R9. Decision routing

Route a row to your useful-results branch only when found is true, resultCount is one and error is empty. Apply the domain completeness rules below before merging its nested data into a canonical table or search index. Preserve provenance at the destination. A consumer should be able to trace a single derived text fragment or cell back to its input file, page or sheet and the run that produced it.

Route a clean absence to an observation log. It means no useful content was produced within this actor's supported operation on those bytes. It does not mean a business entity is absent, a file is legally empty, or a customer has no data. Do not replace a previous successful document with empty data solely because a later URL returned a notice; compare the byte identity, source status and run completeness first.

Route a source or parser error to a retry or review queue with the original reason. A temporary network outage can justify a bounded later retry, whereas a password requirement, unsupported format or hard size limit needs a changed input or a different supported workflow. Retrying identical unsupported bytes every minute adds work without addressing the refusal. Keep the last good result until a verified replacement is available.

Route partial runs using OUTPUT.unprocessed and the domain counters. A cap can leave an input unprocessed, or a parser can reject the whole oversized unit after inspecting it. These are different from a complete negative. Split a large batch at the input-file boundary, preserving the input list and already delivered identities. Do not blindly rerun the entire batch unless repeated delivery and possible repeated billing are acceptable.

Route a fatal budget, pricing, storage or charge error to an operator. Those failures concern delivery integrity rather than the contents of a source document. Reconcile billed event counts and dataset contents before resuming. A workflow that checks only the process status will miss uncertain writes; a workflow that checks only dataset length will miss pricing failures or incomplete batches.

For a complete page, require found:true,resultCount:1,error:"" and nonempty text. Validate the word-box schema before drawing highlights. Apply a domain-specific review policy to critical values instead of relying solely on meanConfidence. A high page mean should not automatically approve an ambiguous account number, name or date.

For not_found, record that the engine produced no nonempty words from a valid accepted page. It can mean a truly blank page, unsupported writing or an image whose text was not recognizable under the chosen models. It is not proof that no visible information exists. Review the source when the business workflow expected content.

For partial, retain already complete pages and schedule only the remaining authorized work where practical. A cap1 run on a two-page PDF yields a complete page1 record plus a free notice. A later page's timeout or pixel refusal does not turn page1 into a failed or refunded OCR unit. Use fileId and pageNumber to avoid mixing records from different source revisions.

R10. Commercial playbooks

Playbook1: searchable scanned archive. Keep original authorized scans in your own archive and supply direct URLs in small batches. Store one parent file record by SHA, then recognized pages with pageNumber,text and engineVersion. Index the text and retain word boxes for a reviewer to locate uncertain terms in the recognition image. Record limits and blank pages as attempts requiring review rather than deleting the archive entry.

Playbook2: OCR handoff after digital extraction. A digital-PDF import stage flags a file as requiring OCR. Pass that same authorized source to this actor with the appropriate languages and page cap. Retain its original file hash so digital and OCR observations can be linked. Apply your own field extraction or manual review after OCR; the actor does not claim to identify invoice fields or approve the meaning of recognized text.

R11. Integration recipes

Use the actor through the normal Apify API or SDK. Supply the same JSON input you tested in the Console, set a suitable timeout and memory allocation, and use a maximum total charge limit appropriate for the unit price. Store your API token in your workflow's credential store or environment, not in shared source files, URLs inside documents or copied README examples. Consult the official Apify run API for the current request and authentication details.

An asynchronous integration starts a run, stores its ID and waits for a terminal result before reading the dataset. A platform webhook can notify an existing endpoint that a run finished; the webhook payload is an event, not the converted document. Retrieve the default dataset and OUTPUT summary for the specific run identified in that event. Verify the run ID and deduplicate webhook delivery because webhook redelivery should not repeat your downstream insertion.

In n8n, a practical sequence is a scheduled trigger or authorized file-list source, an Apify run step, a wait/poll step, dataset retrieval and a conditional branch on found/status/error. Follow that with a staging table or document store. Use the run ID as the workflow correlation key. Keep the token in n8n credentials and avoid logging the entire signed source URL when your workflow distributes logs beyond the people who can access the file.

Treat one dataset record as the parent record. When you flatten its nested arrays into child tables, copy the file identity, sourceUrl, checkedAt and relevant page/sheet/row coordinates into every child. Store a child identifier that is stable within that conversion. Flattening for analysis does not create extra actor result events, and counting flattened rows is not a way to calculate the actor invoice.

JSON is the authoritative export for nested and typed results. CSV exports can serialize arrays into a cell and spreadsheet tools can reinterpret leading zeros, date-like strings or long numbers. If a downstream tool needs a flat CSV, build it from a validated JSON result with explicit column types and escaping. Keep the original JSON next to the derived file so a reviewer can distinguish actor output from export-time coercion.

Before an automated merge, validate both shape and outcome. Reject records with nonempty error from the success branch, inspect warnings according to your quality policy and verify required domain fields. Commit the merge only after the unit's completeness requirements pass. If a later run fails, record that attempt separately and preserve the previous successful content rather than interpreting the failure as a deletion.

For large result exports, use the platform's normal dataset pagination and store each page under the same run identifier. Page retrieval is a read of an already created dataset, not a new conversion run. Starting another actor run to recover an export download can cause repeated conversion and billing. Retry the export operation against the existing dataset when the actor run itself was already complete.

Separate transport retries from business retries. The actor already performs a bounded retry for eligible source failures. Your orchestrator can perform a later retry when the source is expected to recover, but it should record why that retry was scheduled and which inputs were not delivered. Never let both layers recursively retry an entire batch without a total attempt limit and an explicit treatment of already delivered units.

A useful storage model has files(fileId,sourceUrl), recognized_pages(fileId,pageNumber,engineVersion,text,language,imageWidth,imageHeight) and optional word_evidence rows. If a source is rerun with a new engine or language setting, preserve that extraction revision alongside the source hash. Do not overwrite a reviewed transcription without an explicit reconciliation step.

To draw word highlights, use the returned imageWidth/imageHeight as the coordinate space and scale the bounding boxes with the displayed image. For PDF previews, maintain your own mapping between the OCR raster and the viewer's page geometry; directly treating pixels as PDF points produces incorrect overlays. Any transformed or cropped preview should preserve its transformation parameters next to the evidence.

For a review queue, keep the recognized word, page identity, box and your own reason for review. A low word confidence can be one signal, but your application's required fields and source quality can matter more than a global threshold. Store human corrections as a separate reviewed layer so the raw engine output remains available for model-version comparisons.

R12. Operating guide

Files are processed sequentially to keep peak memory and request pressure bounded. The actor does not launch a separate browser per file, enqueue an unbounded crawl or parallelize all supplied documents. More input URLs can increase total work and the chance of reaching the240-second work deadline; it does not create unlimited processing time. The platform run timeout is300 seconds, leaving time to record a summary and close the SDK.

Source requests have their own bounded timeout and at most two retries, only for eligible network failures,429 and server errors. Backoff is at least one second and then three seconds; Retry-After is respected when it fits within the remaining deadline. Empty success responses, unsupported bytes and normal4xx format/access failures are not repaired by repeated downloading. A deadline-limited retry leaves an explicit error instead of silently substituting fixture data.

There is no cross-run cache that can be assumed to suppress a result event. Deduplicate your file list before scheduling if repeated conversion is unnecessary. Use source revision identifiers or your own prior hashes where you already possess the file bytes. Be careful with expiring links: two different signed URLs may refer to the same file, while one stable URL may return a new revision. The actor cannot infer your business retention or replay policy from URL spelling alone.

Monitor the OUTPUT counters and free notices alongside charged event counts. A rising limit rate can mean your documents changed shape or size. A rising source-error rate can mean access restrictions, expired links, robots changes or an outage. A drop in useful outputs with stable HTTP success can mean unsupported content rather than a network failure. Inspect a representative affected file and change one cause at a time.

Before upgrading the actor build used by a schedule, replay your approved regression inputs against the new build under a small budget. Compare source hashes, domain fields, useful-unit counts and exact negative semantics. Keep the previous output export and build identifier so a changed reading order, date representation or OCR word segmentation is distinguishable from an upstream content change.

Run logs and datasets can contain source URLs and extracted content. Choose access permissions and retention periods appropriate for those materials. Temporary parser files are implementation scratch space, not a backup of the source archive. Keep source originals in your own authorized storage if you need them for a later audit. Deleting a local temporary file does not delete an already exported dataset or a downstream copy.

A complete local test suite verifies defined boundaries, but ongoing production monitoring is still necessary. Recheck the default source, MIME and SHA after fixture hosting changes. Recheck container dependencies and resource usage after a build change. Platform memory or engine changes can affect startup cost even if the same marker still appears in output; cost conclusions need measured platform runs, not a developer-laptop timing.

Both language models are packaged in the container; a run does not fetch models based on user input. Recognition uses one native worker thread to bound parallel pressure. This does not establish a platform memory or cost guarantee: raster quality, fonts, page content and engine initialization can change resource usage even at the same pixel count.

The release price requires a measured economics gate. At the proposed$0.008 per page, the plan requires total infrastructure cost C no greater than$0.0016 per paid page, equivalent to P≥5C under the stated revenue-share target. Claude will measure cold startup, a5MP image and the maximum scan-PDF batch after the first push. Startup, storage, transfer, blank pages and failed attempts must be included in the compared workload, rather than reporting only the Tesseract command duration.

If the measured gate fails, the actor remains private pending an explicit scope or pricing decision. There is no fallback to a hidden remote OCR provider, a language model or lower unannounced resolution. The build's local marker recovery should not be marketed as proof of margin or production throughput.

R13. FAQ

Where should I report a reproducible issue? Use the actor's Store Issues channel after publication, with the run ID, actor build, relevant input limits, status/error and a minimal file you have permission to share. Do not post passwords, API tokens, confidential extracted text or active signed URLs in a public issue. If the document cannot be shared, provide a sanitized original fixture that reproduces the same parser behavior.

Does a public URL prove authorization? No. You are responsible for ownership, permission and downstream use. A robots allow rule concerns crawler access, while copyright, confidentiality and source terms concern other obligations. This product does not grant a license to redistribute an archive or access content behind a login. It processes the public file routes you supply under the documented network and format restrictions.

Why did I receive a free row instead of useful text or cells? Read status and error together. Clean absence has an empty error. A resource, format or transport refusal has a reason. The notice exists so your workflow can distinguish an empty supported input from an unsuccessful attempt. Removing that distinction would make failed imports look like intentional empty data.

Can I increase the limit beyond the form maximum? No. Runtime validation enforces the same hard caps even when input is sent directly through the API. Split documents at an authorized preparation step, reduce the batch or choose a product with a larger documented contract. A larger monetary cap does not disable byte, page, cell, pixel or deadline limits.

Will a repeat run be free because the URL is unchanged? No. This actor has no persistent cross-run replay ledger. Repeating a successful conversion can create another result event even if the URL or file hash is unchanged. Reuse an existing dataset for another export, or implement deduplication in your own workflow if your use case needs it.

Is confidence or a successful parse a guarantee of correctness? No. Structured output means the engine completed the documented operation on the received bytes. It does not certify the source statement, file author's intent, financial totals, legal interpretation or downstream business decision. Apply your domain's review requirements before making consequential decisions from extracted content.

Is this page a guarantee of platform cost or availability? No. The prices above were read back from the deployed tariff on 2026-09-05 and the examples come from accepted platform runs of the same build; check the tariff shown on the Store page before a large run, because a tariff change is an operator action, not something inferred from this text.

Does it recognize handwriting? Handwriting accuracy is outside the supported printed-text claim. A page can produce some words without being reliable enough for your use. Evaluate representative source material and retain a manual-review path.

Does eng+rus translate Russian into English? No. It loads both recognition models and returns recognized text. The language field records the requested combination, not a translation result or per-word language detection.

What does a confidence of96 mean? It is the engine's score for recognition evidence. It is not a96% probability that the page or a specific value is correct. Review critical words in context and compare them with the original pixels.

Why was a small PDF rejected as too large? Compressed file size and raster pixel count are different limits. A tiny PDF can describe a very large physical page. The actor checks the planned150DPI dimensions before rasterization and refuses pages above the pixel cap.

Does maxPagesPerFile1 discard the rest without notice? No. A PDF with more pages produces a free partial notice and an unprocessedPages counter. A successfully recognized first page remains a complete unit. A PNG or JPEG always represents a single supported image page.

Can a blank page still cost a start? A blank page has no result event. A platform start event may already have occurred under the displayed tariff, and infrastructure cost still exists for the operator. The proposed price arithmetic distinguishes that start from recognized-page events.

Can I get a fragment when a page times out? No. An incomplete page does not release partial text or word boxes as a paid result. The free timeout notice identifies the page when known; complete earlier pages of the PDF remain delivered.

R14. Sources, rights and support

Process only documents and images you own or are authorized to transform. Retain applicable notices, attribution and confidentiality restrictions in derived data. Conversion into JSON does not remove copyright or make private information public. Avoid redistributing a source archive just because the input was technically accessible through a public download link.

The original Wave A fixtures are generated for testing and include fixed control phrases rather than customer material. Their syntheticFixture flag identifies that origin in hosted examples. Production URLs, parser outputs and source content are treated as data, never as instructions to execute code or request unrelated resources.

The actor uses the platform's existing dataset, key-value store, API, schedule and webhook capabilities. It does not contact people, submit forms, bypass a login, create external documents or modify the input source. Those actions, if required by a customer workflow, remain separate authorized steps owned by that workflow.

Engine references: Tesseract documentation, Tesseract command-line usage and TSV, and Poppler utilities. Tesseract uses Apache2.0 licensing; Poppler components use their applicable open-source licenses. Preserve installed-package notices and review redistribution requirements for any derivative image you distribute.

The Docker base and package evidence is retained in SPEC and the build log. The base image's Alpine release was read from the published registry layer, and exact package versions were read from the matching distribution's APKINDEX. This proves the planned package combination is grounded in published artifacts, while an actual container build and platform run remain required acceptance steps.

Original raster fixtures are created with Pillow using local fonts; ReportLab places those images on PDF pages without a text layer. The manifest covers all hosted fixture candidates, including the extra exact pixel-boundary negative. Claude uploads these binaries with image/png or application/pdf and checks exact SHA. The actor build does not upload them, contact document owners or acquire rights on the buyer's behalf.

Related-tool links below point only to published actors of the same author. The output examples above are accepted platform rows, not local fixture output.

Related tools for adjacent workflows in data pipelines for AI applications.

ActorWhat it does
RAG Dataset BuilderPair it in the data pipelines for AI applications workflow: Turn buyer-authorized public website sitemaps into bounded, source-linked text chunks for RAG, search,...
Structured Data ExtractorPair it in the data pipelines for AI applications workflow: Extract title, meta, JSON-LD, headings, links, emails, and price observations from up to 100 authorized...
Live Price OraclePair it in the data pipelines for AI applications workflow: Get timestamped DexScreener market observations for up to 100 token contracts or bounded ticker searches
URL to Markdown ConverterPair it in the data pipelines for AI applications workflow: Convert up to 100 authorized public HTML pages into clean Markdown for RAG, AI agents, SEO research, and...