PDF to Text & OCR: Scanned PDF, DOCX to Markdown
Pricing
from $3.20 / 1,000 documents
PDF to Text & OCR: Scanned PDF, DOCX to Markdown
PDF, scanned PDF, images, DOCX, XLSX and PPTX to clean Markdown and text. OCR only on pages without a text layer, tables kept, failed files are free.
Pricing
from $3.20 / 1,000 documents
Rating
0.0
(0)
Developer
khalil ben ali
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 days ago
Last modified
Categories
Share
What does PDF to Text & OCR do?
PDF to Text & OCR converts the files people send you into clean Markdown and plain text, in one Actor:
- PDF, with a text layer or scanned, including mixed files where only some pages are scans;
- images: PNG, JPEG, TIFF (first page), BMP, GIF and WebP;
- Word DOCX, spreadsheets XLSX, XLS, ODS and CSV, and PowerPoint PPTX.
Every file becomes one dataset item with the same shape: Markdown with <!-- page N -->, <!-- sheet: Name --> and <!-- slide N --> markers, plain text, the tables as rows, metadata, page counts and a billing receipt. You can send a whole batch of mixed links or base64 files in one run instead of one Actor per format.
OCR only where it is needed, billed per page you can see
- Pages with a real text layer are read directly: fast, exact and not billed as OCR.
- Pages without one are OCRed: scans, stamped scans (an image page with a short text stamp) and old scans whose hidden OCR layer is junk, which are re-OCRed with the warning
TEXT_LAYER_REPLACED_BY_OCR. - Every row shows
textPages,ocrPagesand achargedreceipt, so you can check each charge against the pages that caused it. Failed files are free. - OCR costs $8 per 1,000 pages; the most used PDF OCR Actor (memo23) lists $15 per 1,000.
Tables stay tables, and chunks cite their pages
- Detected tables are GFM Markdown tables inside the Markdown, and also come as a
tablesarray withrows(arrays of cell strings) for spreadsheets and databases. - Optional RAG chunks carry
pageStart,pageEndandheadingPath, so an answer built from a chunk can cite the page it came from.
How much does it cost to convert PDF to text?
$4 per 1,000 documents (up to 20 pages each), $0.20 per 1,000 extra pages, $8 per 1,000 OCR pages, $0.003 per run.
The Actor uses pay-per-event pricing. You pay only for files that were converted with text; errors are free.
| Event | What triggers it | Free / Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|
| Run start | Each run, once per GB of memory (the default 1 GB counts as one) | $0.003 | $0.003 | $0.003 | $0.003 | $0.003 |
document | A PDF, DOCX, spreadsheet or PPTX converted with text (status ok or partial), including its first 20 text pages | $0.004 | $0.0036 | $0.0032 | $0.0032 | $0.0032 |
extra-page | Each text page, slide or sheet beyond the first 20 of one document (DOCX: estimated pages of 3,000 characters) | $0.0002 | $0.00018 | $0.00016 | $0.00016 | $0.00016 |
ocr-page | Each page or image read by OCR that produced text | $0.008 | $0.0072 | $0.0064 | $0.0064 | $0.0064 |
Standalone images pay only ocr-page, not document. OCR pages never count as extra pages, so no page is billed twice. Prices may change; the Pricing tab of this page is authoritative.
Worked examples (plus the $0.003 run start):
| Run | How it adds up | Cost |
|---|---|---|
| 1,000 ten-page PDFs with a text layer | 1,000 x $0.004 | $4.00 |
| 100 scanned ten-page PDFs | 100 x $0.004 + 1,000 OCR pages x $0.008 | $8.40 |
| 500 photos or images of documents | 500 OCR pages x $0.008 | $4.00 |
How does it compare?
Prices as listed on each Actor's Store page on 2026-10-13, for the same two jobs. Run starts are left out.
| Actor | Listed price | 1,000 ten-page text PDFs | 100 scanned ten-page PDFs |
|---|---|---|---|
| This Actor | $0.004 per document (20 pages), $0.008 per OCR page | $4.00 | $8.40 |
| memo23 (PDF only) | $0.005 per PDF, $0.015 per OCR page | $5.00 | $15.50 |
| lergassy (Document Text Extractor) | $0.0035 per document, $0.00015 per page, $0.01 per OCR page | $5.00 | $10.50 |
| automation-lab (PDF text, no OCR) | $0.00345 per PDF | $3.45 | no OCR |
| nerolabs (no Markdown, no Office files) | $0.001 per text page, $0.005 per OCR page | $10.00 | $5.00 |
| zenomastro (bills every PDF page as an image) | $0.005 per page or image | $50.00 | $5.00 |
Use cases
- RAG ingestion: turn PDFs, slides and spreadsheets into Markdown and page-cited chunks for a vector database.
- n8n, Make and Zapier document pipelines: one HTTP call per batch of files, one JSON row per file.
- AI agents reading PDFs: an agent passes a link or a base64 file and gets Markdown back.
- Digitising archives: scanned letters, reports and forms become searchable text.
- Spreadsheet to JSON: every sheet with two or more columns becomes a table with
rows, with dates in ISO format.
Input
Add document links, base64 files, or both. Everything else has a sensible default.
{"urls": ["https://raw.githubusercontent.com/mozilla/pdf.js/v5.4.296/test/pdfs/tracemonkey.pdf","https://raw.githubusercontent.com/naptha/tesseract.js/v5.1.1/tests/assets/images/testocr.png","https://raw.githubusercontent.com/apache/poi/REL_5_4_1/test-data/document/heading123.docx"],"ocrMode": "auto","ocrLanguages": ["eng"]}
The main options:
- OCR mode (
ocrMode):auto(default),force(OCR every page) oroff. - OCR languages (
ocrLanguages): one or two of 21 languages, see the FAQ. - Max OCR pages per document (
maxOcrPagesPerDocument, default 50) and Max pages per document (maxPagesPerDocument, default 200). - Page range (
pageRange), for example1-5, 8, 12-, for PDF pages, slides and sheets. - PDF password (
pdfPassword), used for every encrypted PDF of the run. - Output:
includeText(default on),includePages,extractTables(default on), andchunkingwithchunkSizeandchunkOverlap. - Max file size (
maxFileSizeMb, default 50 MB, at most 100 MB).
A run that converts only pages 1 to 8 of a PDF with forced OCR, and splits the result into chunks:
{"urls": ["https://raw.githubusercontent.com/mozilla/pdf.js/v5.4.296/test/pdfs/tracemonkey.pdf"],"ocrMode": "force","pageRange": "1-8","chunking": true,"chunkSize": 2000}
Output
One dataset item per input document, in input order. This is the first item of the default run above, with markdown and text shortened, and tables cut to the start of the 10-column results table on page 12:
{"source": "https://raw.githubusercontent.com/mozilla/pdf.js/v5.4.296/test/pdfs/tracemonkey.pdf","sourceType": "url","fileName": "tracemonkey.pdf","format": "pdf","contentType": "application/octet-stream","fileSizeBytes": 1016315,"status": "ok","errorCode": null,"errorMessage": null,"warnings": [],"unit": "page","pageCount": 14,"pagesProcessed": 14,"textPages": 14,"ocrPages": 0,"blankPages": 0,"ocrLanguages": [],"ocrConfidence": null,"title": "Trace-based Just-in-Time Type Specialization for Dynamic Languages","metadata": {"author": null,"subject": null,"keywords": null,"creator": "TeX","producer": "pdfeTeX-1.21a","createdAt": "2009-04-01T23:39:25.000Z","modifiedAt": null},"wordCount": 13127,"charCount": 83585,"markdown": "<!-- page 1 -->\n\n# Trace-based Just-in-Time Type Specialization for Dynamic Languages\n\nAndreas Gal, Brendan Eich, Mike Shaver, David Anderson, David Mandelin, Mohammad R. Haghighat, Blake Kaplan, Graydon Hoare, Boris Zbarsky, Jason Orendorff, Jesse Ruderman, Edwin Smith, Rick Reitmaier, Michael Bebenita, Mason Chang, Michael Franz\n\n…","text": "Trace-based Just-in-Time Type Specialization for Dynamic Languages\n\nAndreas Gal, Brendan Eich, Mike Shaver, David Anderson, David Mandelin, Mohammad R. Haghighat, Blake Kaplan, Graydon Hoare, Boris Zbarsky, Jason Orendorff, Jesse Ruderman, Edwin Smith, Rick Reitmaier, Michael Bebenita, Mason Chang, Michael Franz\n\n…","tables": [{"page": 12,"index": 2,"rows": [["","Loops","Trees","Traces","Aborts","Flushes","Trees/Loop","Traces/Tree","Traces/Loop","Speedup"],["3d-cube", "25", "27", "29", "3", "0", "1.1", "1.1", "1.2", "2.20x"],["3d-morph", "5", "8", "8", "2", "0", "1.6", "1.0", "1.6", "2.86x"]],"markdown": "| | Loops | Trees | Traces | Aborts | Flushes | Trees/Loop | Traces/Tree | Traces/Loop | Speedup |\n| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n| 3d-cube | 25 | 27 | 29 | 3 | 0 | 1.1 | 1.1 | 1.2 | 2.20x |\n…"}],"markdownUrl": "https://api.apify.com/v2/key-value-stores/<STORE_ID>/records/markdown-0001-tracemonkey.md","fullResultUrl": null,"charged": {"document": 1,"extraPages": 0,"ocrPages": 0},"processingMs": 1384,"processedAt": "2026-10-13T09:00:31.417Z"}
statusisok,partial(some pages failed or were cut by the time limit, the maximum charge or an abort, but there is text) orerror(nothing usable, never charged).markdownalways has the markers:<!-- page N -->before each PDF page or image,<!-- sheet: Name -->and## Namefor each sheet,<!-- slide N -->and## titlefor each slide. Skipped pages keep a marker such as<!-- page 7: OCR skipped (limit) -->.textis plain text with pages, sheets and slides separated by a form feed (\f).titleis the document's own title, else its first level-1 heading.- The Output tab also has a Content view with the Markdown and a Billing receipt view.
Where are the Markdown files?
Every converted document is also saved in the run's default key-value store as markdown-0001-<name>.md (0001 is its position in the input). markdownUrl in the dataset item links to it. A result too large for a dataset item (over about 8 MB) is saved whole as result-0001-<name>.json and linked as fullResultUrl, and the dataset item keeps the first 100,000 characters of the Markdown, with the warning OUTPUT_MOVED_TO_KVS. If the key-value store refuses a file, the row is still saved, without that link and with the warning STORAGE_WRITE_FAILED.
Use it from the API and AI agents
Call the Actor and get the rows back in one request with the run-sync-get-dataset-items endpoint:
curl -X POST "https://api.apify.com/v2/acts/khalilbenali~pdf-to-text-ocr-markdown/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-H "Content-Type: application/json" \-d '{"urls": ["https://raw.githubusercontent.com/mozilla/pdf.js/v5.4.296/test/pdfs/tracemonkey.pdf"]}'
That endpoint waits at most 300 seconds. For more than about 10 scanned pages, start the run asynchronously and read the dataset when it finishes, or give the run more memory.
- No public link? Pass the file itself in
base64Files: a base64 string, adata:URI or{"fileName": "report.pdf", "data": "<base64>"}. Keep the total under about 5 MB per run. - AI agents: the Actor works as a tool through Apify's MCP server (mcp.apify.com), for example in Claude or Cursor: the agent passes links or base64 files and reads the Markdown.
- Limited permissions: the Actor runs with limited permissions. It reads only the links and files you give it and writes only to its own run's dataset and key-value store, so it is safe to call from agents and automations.
How OCR routing works
In auto mode each PDF page is checked before anything is OCRed:
- No text: a page with fewer than 25 characters in its text layer is OCRed.
- Stamped scan: a page with fewer than 200 characters whose images cover at least half of it is OCRed (a scan with a typed stamp or header).
- Junk layer: a page whose text layer has at least 20 words of which 30% or more are garbage (
Nouem&r 16, 1989 C'ONGRESS ~NI~ STAms), or at least 10% unreadable characters, is OCRed again, with the warningTEXT_LAYER_REPLACED_BY_OCR. - Every other page is read from its text layer and never OCRed.
force OCRs every page (a page with a usable text layer falls back to it if OCR finds nothing); off never OCRs, so a scan returns the error NO_TEXT. Pages are rendered at 200 DPI, at most 3,500 pixels on the long side, with tesseract's LSTM engine and the bundled fast models; nothing is downloaded at run time. A blank page (under 0.2% dark pixels) is skipped and free. Images are always OCRed unless OCR is off.
Limits
- No machine-learning layout model: complex scientific or LaTeX tables and headers that span columns come out worse than with tools such as docling, and labels inside figures and diagrams can come out as a small table.
- Headings are found from font size; a heading that is only bold, in the body font size, stays a paragraph.
- OCR output has no table structure: tables on scanned pages come out as lines of text.
- Handwriting and photos of documents (angles, shadows) read poorly; check
ocrConfidence. - Small print under about 6 pt is OCRed less accurately.
- A multi-page TIFF is read from its first page only (warning
FIRST_TIFF_PAGE_ONLY). TIFFs are read when uncompressed or LZW, PackBits or CCITT (fax) compressed; a JPEG- or ZIP-compressed TIFF returnsUNSUPPORTED_FORMAT(save it as PNG or PDF). - Images inside DOCX and PPTX files are not read (warning
EMBEDDED_IMAGES_NOT_READ); only their alt text is kept. Chart data is not extracted. - DOCX files have no pages, so their pages are estimated at 3,000 characters each.
- Legacy .doc and .ppt files, ODT, EPUB and RTF are not supported (
UNSUPPORTED_FORMAT); a web page instead of a file returnsNOT_A_DOCUMENT. - Office files (DOCX, XLSX, PPTX, ODS) are unpacked by the Actor itself, part by part and with caps, and the readers get a fresh copy, never the original archive. Images, embedded files and fonts (the
media,embeddingsandfontsfolders, ODSPictures), and XLSX pivot caches, pivot tables and printer settings, are not unpacked at all: the readers get an empty part in their place. More than 10,000 parts, more than 250 MB declared or unpacked in all (or over 100 times the file size, for files over 1 MB), a part that unpacks past the size the file declares for it, or one part bigger than the readers can take at the run's memory givesARCHIVE_TOO_LARGE. That per-part limit is, per GB of memory, 16 MB or 500,000<characters for a DOCX or PPTX part, and 112 MB for an XLSX part (shared strings, styles) or the ODS content. An XLSX sheet of any length is read: only its first 5,001 rows are ever read (5,000 are kept), so the rows after them are dropped before the reader gets the sheet, and the 112 MB per GB applies to the rows that are read (a sheet laid out in a way this cannot follow exactly is held to it as a whole). An archive that could be read in two different ways (two parts with one name, more directory entries than it declares, a directory that is not where the archive says, a part whose two headers disagree, parts that overlap) givesCORRUPT_FILE. ZIP64 archives are read. - DOCX, PPTX and spreadsheets (XLSX, XLS, ODS, CSV) are read in a separate process. The run works on one document per 4 GB of memory at once (1 to 4 parallel lanes), and each lane gets the run's memory divided by the lanes. The reader's JavaScript memory is capped at 35% of its lane's memory, and all its memory at what is left of its lane's memory once the main process's own memory (when the file starts) and 160 MB are taken off, at most 75% and at least 192 MB of the lane's memory. A file that needs more ends with
ARCHIVE_TOO_LARGEand the run goes on with the next file. At the default 1 GB that is, for example, a Word file with more than roughly 5 to 10 MB of text and markup, or a spreadsheet with a few million distinct text cells; run those with more memory. - PDFs are checked before they are opened: every stream compressed with Flate, LZW, RunLength, Brotli or ASCII85 (alone or chained, also behind ASCIIHex) is unpacked with a cap, and every different filter chain a stream could have is unpacked and counted. More than 64 MB from one stream, an image (up to 100 megapixels) past its declared size (at most 400 MB), or more than 300 MB (or 20 times the file size, if larger) from all streams other than images gives
CORRUPT_FILE. Images do not count towards that total, so a long scan is a normal file. The check itself unpacks at most 2.5 GB and runs at most 30 seconds: images are unpacked only within the first 2 GB and 20 seconds, and the rest are left to the reader's own limit, but a file whose other streams still need checking after that givesCORRUPT_FILE(split such a file). Attachments (embedded files) are skipped, as they are never read. For every stream, a limit added to the PDF reader also stops any stream decoded by Flate, LZW, RunLength, ASCII85, ASCIIHex, CCITT fax, Brotli or decryption at 128 MB while the PDF is read (an image at the size the reader needs for it, up to the larger of 128 MB and 140 MB per GB of memory, at most 400 MB), and the document usually ends withCORRUPT_FILE. - Images inside a PDF are decoded in full when their page is OCRed (normally once per page), which takes about 6 to 12 bytes of memory per pixel. So the reader decodes no image whose PDF dictionary declares more than 35 megapixels per GB of the memory of its lane (see above), image masks included, and never more than 100 megapixels; nor a JPEG image whose own header is larger than that, whatever the dictionary says. A JPEG 2000 image is first reduced by the PDF reader to at most 2,048 pixels a side (see below), so it is decoded at that size and not left out. A black-and-white (1-bit) image takes far less and may have up to 100 megapixels at any memory; a JBIG2 image whose own headers ask for a larger page, region or pattern table is not decoded either. At the default 1 GB that allows a Letter or A4 page scanned in colour at 600 dpi, and an A3 page scanned in black and white at 600 dpi. A larger image is left out of its page before it is decoded: the page gets the warning
IMAGE_SKIPPED_MEMORYand counts as incomplete (the document ispartial, orIMAGE_TOO_LARGEwhen nothing else could be read). Run the Actor with more memory to read it. - A PDF page is read from its text layer up to 200,000 text pieces (pdf.js text items), and a document up to 1,000,000 in all; a real page has a few hundred, rarely more than a few thousand. A page with more is written from its first 200,000, gets the warning
TEXT_ITEMS_LIMITand counts as incomplete (partial), and is never sent to OCR; pages after the document's 1,000,000 are not read at all, are not charged, and get the same warning. In local runs at the default 1 GB, a document that reached 1,000,000 pieces peaked at about 420 MB of memory with one-letter pieces, and about 610 MB with pieces of 26 characters. - A site whose robots.txt asks for more than 60 seconds between requests (Crawl-delay) is not downloaded from (
ROBOTS_UNAVAILABLE). - Per run: at most 5,000 links and 50 base64 files. Per file: at most 100 MB, 2,000 pages, 500 OCR pages, 5,000 rows per sheet and 1,000,000 cells. An image file (PNG, JPEG, TIFF and the others) may have at most 50 megapixels; images inside a PDF have the memory limit above.
What the safety limits do not cover
- Encrypted PDFs, images placed inline in page content, and streams stored inside object streams are not checked before the PDF is opened. Only the reader's own limit of 128 MB per stream holds them, not the 300 MB total.
- The text-piece limits count pieces, not characters. A PDF whose text layer holds tens of millions of characters (for example 200,000 pieces of 50 to 100 characters on each of several pages; a real page has a few thousand characters) can use up the memory of a 1 GB run, which then fails: in local runs at 1 GB, 40 to 44 million characters peaked at 770 to 810 MB, and 87 million ran out of memory.
- The number of drawing operations on a PDF page is not limited. A page with no text that is made of millions of them (for example a very detailed map or CAD drawing) is rendered for OCR and can use up the memory of a 1 GB run, which then fails: in local runs at 1 GB, 1 million operations on a page peaked at about 0.5 GB, 3 million at about 0.75 to 0.9 GB, and 7.5 million ran out of memory. With
ocrModeset to off such a page needs little memory. - The image limits apply to each image, not to a page: a page with several large images can need more memory together (for example four 30-megapixel colour images, about 0.7 GB at 1 GB).
- JBIG2 symbol dictionaries give their sizes inside the compressed data, so they are not checked before decoding. The JBIG2 decoder's own memory can grow up to 2 GB until the document is closed.
- The PDF reader decodes JPEG 2000 images at no more than 2,048 pixels a side (it reduces larger ones), so a scan stored as JPEG 2000 is OCRed at a lower resolution than the same scan stored as JPEG.
- PDF images and pages are decoded on the run's main thread. A long decode (for example a large progressive JPEG within the limits) cannot be interrupted: the time budget and an abort take effect when it ends. A JPEG with more than 1,000 scans is not decoded.
- The check before a PDF is opened can take up to 30 seconds per file before the PDF is refused or read.
- The Office reader's memory is checked every 50 ms, so a very fast spike can pass its budget by some tens of MB before the reader is stopped. The Markdown it returns has no size limit of its own; only the reader's memory bounds it.
FAQ
Why did my Google Drive, Dropbox or GitHub link fail?
The Actor respects robots.txt and does not bypass bot protection. Google Drive viewer links, Dropbox shared links and github.com /raw/ links are disallowed for bots, so they end with ROBOTS_DISALLOWED (free). Download the file and pass it in base64Files, or use a direct link from a host that allows it (for example raw.githubusercontent.com). A link that returns a web page instead of a file (a viewer or login page) ends with NOT_A_DOCUMENT.
Can it read password-protected PDFs?
Yes: put the password in PDF password (pdfPassword). It is stored as a secret input, used for every encrypted PDF of the run and never logged. Without it an encrypted PDF ends with PASSWORD_REQUIRED, and with a wrong one with PASSWORD_INCORRECT. Password-protected Office files are not supported.
Which languages can OCR read?
English, German, French, Spanish, Italian, Portuguese, Dutch, Polish, Turkish, Russian, Ukrainian, Czech, Romanian, Swedish, Danish, Vietnamese, Arabic, Hindi, Chinese (Simplified), Japanese and Korean. Pick one or two in OCR languages; two are slower. The language matters only for OCR pages: with the English model, a German scan loses its umlauts.
What are the size and page limits?
Files up to maxFileSizeMb (default 50 MB, at most 100 MB); larger files end with FILE_TOO_LARGE and are not downloaded or charged. maxPagesPerDocument (default 200) and maxOcrPagesPerDocument (default 50) cap the pages of one file; pages over the limits are skipped with the warnings PAGE_LIMIT and OCR_LIMIT and are not charged. Some limits grow with the run's memory: scanned PDF pages with very large colour or grey images (over 35 megapixels per GB) and very large Word, PowerPoint or spreadsheet files need more than the default 1 GB; the Limits section lists them.
What does each status and error code mean?
| Code | Meaning |
|---|---|
INVALID_URL | Not an http or https link, or a link with a user name or password |
BLOCKED_ADDRESS | The link points to a private, local or cloud-metadata address |
ROBOTS_DISALLOWED | The site's robots.txt does not allow bots to fetch this path |
ROBOTS_UNAVAILABLE | The site's robots.txt could not be read (server error) or asks for more than 60 s between requests, so nothing was fetched |
BLOCKED_BY_HOST | The site refused the download (HTTP 401, 403 or 451) |
HTTP_ERROR | Another HTTP error, for example 404, after retries for 429 and 5xx |
DOWNLOAD_FAILED | Network error or timeout (120 s) |
FILE_TOO_LARGE | Over the maximum file size |
NOT_A_DOCUMENT | A web page (viewer, login or error page) instead of a file |
UNSUPPORTED_FORMAT | A file type the Actor does not read, such as .doc, .ppt, ZIP or JSON, or a JPEG- or ZIP-compressed TIFF |
PASSWORD_REQUIRED | An encrypted PDF without a password, or a protected Office file |
PASSWORD_INCORRECT | The PDF password is wrong |
CORRUPT_FILE | The file is damaged, the base64 data is not valid, an Office archive could be read in two ways, or a PDF fails the decompression check (see Limits) |
ARCHIVE_TOO_LARGE | An Office file with more than 10,000 parts, that unpacks past 250 MB or past its declared sizes, or too big for the run's memory (see Limits) |
IMAGE_TOO_LARGE | An image file over 50 megapixels, or a PDF whose page images are too large for the run's memory, with no other text (see Limits) |
NO_TEXT | No text: blank pages, a scan with OCR off, or a page range that selects no page |
OCR_FAILED | OCR failed on every page that needed it |
CHARGE_LIMIT_REACHED | The run's maximum cost was reached before this file |
RUN_TIME_BUDGET | The run was about to time out, or was aborted, before this file produced text |
INTERNAL_ERROR | An unexpected error; please report the file in the Issues tab |
Every error row is free. A partial row lists in warnings which pages were cut and why.
What is charged and what is free?
Charged: a document for each converted PDF, DOCX, spreadsheet or PPTX with text; an extra-page for each text page beyond its first 20; an ocr-page for each page or image that OCR read. Free: every error row, blank pages, skipped pages (page, OCR and text-piece limits), pages where OCR failed, and pages cut by the time limit or the maximum cost. Charges are made only after the row is saved. The run stops starting new files once the next document fee or OCR page would exceed your maximum cost per run: the rest are listed as free CHARGE_LIMIT_REACHED rows. Each row's charged receipt lists the charges requested for it right after it was saved; they normally match what Apify charged, the run's own charge record on Apify is authoritative, and any difference is logged.
How fast is it?
Text PDFs and Office files take a few seconds per document; very long ones take longer. On Apify at the default 1 GB, a 117-page text PDF took 3 seconds and five Office files took 3 seconds in all. OCR is the slow part: at the default 1 GB, typical scanned pages took about 7 seconds each, and pages packed with small print up to 30 seconds each. On Apify, more memory also gives a run more CPU, so big scan batches finish sooner with more memory, and from 8 GB documents are converted in parallel. The run start is charged once per GB.
Is my data private?
Document content is never logged; the log shows only host names, paths without query strings, sizes, counts and codes. Your documents and results stay in your own Apify storage. The Actor is not designed for or marketed for IDs, bank statements, medical records or other personal-data documents.
Changelog
1.0 (2026-10-13)
First release: PDF text layers with per-page OCR routing, images, DOCX, XLSX, XLS, ODS, CSV and PPTX (with speaker notes), tables, page ranges, PDF passwords, 21 OCR languages, RAG chunks with page citations, and per-row billing receipts.
If the Actor helps you, a review on this page helps others find it. Found a file it reads badly? Report it in the Issues tab.