What it does
Document intake is rarely tidy. One supplier emails a scanned PDF, another sends a phone photo of the same invoice, the fax gateway produces TIFFs and a support form uploads screenshots. Building a separate path for each format is busywork. The OCR to Text actor takes all of them in one urls list and returns text in a consistent row format.
It accepts PDF, PNG, JPEG, TIFF, WebP, GIF, BMP and JPEG 2000. Each image counts as one page; each PDF is read page by page, with pages that already have a text layer read directly at a tenth of the OCR price. By default you get one row per file with all its text, which keeps downstream code simple whatever the input type.
Under the hood it runs Tesseract 5 with LSTM models in 29 languages, up to 4 per run. That makes it a good fit for automation work: back-office pipelines, AI agents that need a reliable OCR tool, and scheduled batch jobs where a run budget cap matters. Failed downloads, unreadable files and blank pages are never charged.
How it works
- You submit a list of file links in
urls, mixing PDFs and image formats freely, and optionally cap the batch withmaxFiles. - The actor detects each file's type; images go straight to OCR, PDFs are split into pages and text-layer pages are read without OCR in
automode. - Tesseract 5 recognises the image pages in your chosen
languages, dropping low-confidence words if you setminWordConfidence. - Each file becomes one dataset row by default (
outputModedocument), or one row per PDF page if you switch topages. - Charges are per page read, and the run stops cleanly when it reaches the maximum total charge you set.
Input example
A typical run input (JSON). Every field is also available as a form in the Apify console.
{
"urls": [
"https://raw.githubusercontent.com/ocrmypdf/OCRmyPDF/main/tests/resources/linn.pdf",
"https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif",
"https://github.com/tesseract-ocr/tessdoc/raw/main/images/eurotext.png"
],
"languages": [
"eng",
"fra"
],
"pdfMode": "auto",
"outputMode": "document",
"minWordConfidence": 40,
"maxFiles": 5000
}All input fields
| Field | Type | Required | Default | What it does |
|---|---|---|---|---|
urls | array | yes | Links to scanned PDFs or images (PNG, JPEG, TIFF, WebP, GIF, BMP, JPEG 2000). Each image is one page. | |
languages | array | no | ["eng"] | Languages in the documents (up to 4). Picking only the languages you need is faster and more accurate. |
pdfMode | string | no | "auto" | Auto: pages that already contain text are read directly (exact, and charged at the cheaper text-layer price); only scanned pages are OCR'd. OCR all: OCR every page, e.g. when a PDF's hidden text layer is poor. |
outputMode | string | no | "document" | For PDFs: one row per PDF with all pages, or one row per page. Images are always one row each. |
includeWords | boolean | no | false | Add every recognised word with its confidence and pixel box (left, top, width, height), e.g. for redaction, highlighting or form extraction. |
minWordConfidence | integer | no | 0 | Drop words Tesseract is less sure of than this (0–100). 0 keeps everything; 40–60 removes most noise from stains and stamps. |
pageSegmentation | string | no | "auto" | How Tesseract finds text. Auto suits most pages; Single column for uniform text; Single block for receipts and snippets; Sparse for scattered text like forms and screenshots. |
dpi | integer | no | 300 | Resolution scanned PDF pages are rendered at before OCR. 300 is the accuracy sweet spot; 200 is faster for large print. |
maxPagesPerPdf | integer | no | 200 | Process at most this many pages of each PDF (from the start). Longer PDFs are marked truncated. |
maxFiles | integer | no | 1000 | Stop after this many files. |
password | string | no | For password-protected PDFs you are entitled to open. Used for every PDF in the run. |
Output example
The sample shows a scanned PDF, a TIFF test image and a digital PDF processed in the same run, each as one row with its file type and page counts.
| url | fileType | pagesOcr | confidence | wordCount | text | pagesTextLayer |
|---|---|---|---|---|---|---|
| https://raw.githubusercontent.com/ocrmypdf/OCRmyPDF/main/tests/resources/linn.pdf | 1 | 95.5 | 728 | The LinnSequencer\n32 Track MIDI Sequence Recorder\n\nThe LinnSequencer is a state-of-the-art composition and performance tool… | ||
| https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif | tiff | 1 | 96.3 | 60 | This is a lot of 12 point text to test the\nocr code and see if it works on all types\nof file format. | |
| https://arxiv.org/pdf/1706.03762 | 0 | 6457 | Provided proper attribution is provided, Google hereby grants permission to reproduce the tables and figures… | 15 |
Pricing
Pay per event: you are charged only for the results you receive, with no subscription. Set a maximum total charge on any run and it stops cleanly at the cap.
| Charged for | When | Price | Per 1,000 | Worked example |
|---|---|---|---|---|
| Page ocr | Charged per image or scanned PDF page read by OCR | $0.003 | $3 | A 10-page scanned PDF = $0.03; 1,000 receipts = $3.00 |
| Page text | Charged per PDF page that already has a text layer (read directly, no OCR) | $0.0003 | $0.30 | A 100-page digital PDF = $0.03 |
| Actor Start (platform start fee) | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.00005 | — | One run at 4 GB = $0.0002 |
Prices are read from the live Apify Store listing when this page is built. The listing is always authoritative.
Try OCR on Apify. Pay only for the results you get.
Run on Apify →Use cases
Back-office document intake
Route every incoming attachment, whatever its format, to one OCR call and store the text next to the file. Because each file comes back as one row with fileType, pagesOcr and confidence, the same parser handles invoices, letters and forms.
OCR tool for AI agents
Give an agent one tool that turns any document link into text instead of separate image and PDF tools. The confidence score lets the agent decide when to ask a human to check a result.
Migrating a document store
When moving years of scans out of an old document management system, export file links in batches of up to 10,000 per run with maxFiles and keep the returned text for search in the new system.
Scheduled nightly OCR jobs
Run the actor on a schedule against the day's new uploads and set a maximum total charge. If a batch is unexpectedly large the run stops at the cap rather than overrunning your budget.
How it compares
| ActorForge OCR to Text | Separate image and PDF tools | Self-hosted OCR service | |
|---|---|---|---|
| PDFs and images in the same request | Yes | No, one tool per format | Yes, if you build it |
| Formats | PDF, PNG, JPEG, TIFF, WebP, GIF, BMP, JPEG 2000 | Depends on each tool | Whatever you install |
| Text-layer PDF pages skipped from OCR | Yes, at $0.30 per 1,000 pages | Varies | Only if you script it |
| Run budget cap | Yes, stops cleanly at the cap | Varies | Your responsibility |
| Maintenance | None | Several integrations to maintain | Servers, updates, scaling |
| HEIC/AVIF photos and SVG | No, convert to JPEG first | Some tools support them | Depends on your stack |
If you only ever process one kind of file, a dedicated tool such as PDF OCR or Image to Text OCR gives you the same engine with defaults tuned for that input. Teams with strict data residency needs may still prefer a self-hosted OCR service.
Limits and honest notes
- Tesseract reads printed and typed text very well (95%+ confidence on clean scans); handwriting, low-resolution photos, heavy stamps and decorative fonts come out poorly. The confidence score tells you which pages to check.
- Output is plain text in reading order with line and paragraph breaks. Tables come out as lines of text, not structured tables. Images and charts have no text to extract.
- Pages rotated by 90° or 180° are not auto-rotated; slightly skewed scans are fine.
- Up to 4 languages per run; picking only the languages your documents use is faster and more accurate. Modern Greek is not available.
- HEIC/AVIF photos and SVG are not supported (convert photos to JPEG). Files up to 100 MB; PDFs up to 2,000 pages each (200 by default).
- Password-protected PDFs need the password input. Links that return a web page instead of a file are reported and not charged.
- Respects your run budget: set a maximum total charge and processing stops cleanly at the cap, with no page charged twice.
FAQ
Can I send PDFs and images to the same OCR API call?
Yes. Put any mix of PDF, PNG, JPEG, TIFF, WebP, GIF, BMP and JPEG 2000 links in urls. Images are always one row each; PDFs are one row per file by default or one row per page with outputMode set to pages.
Which OCR languages are supported and how many can I use at once?
29 languages, including English, German, French, Spanish, Arabic, Hebrew, Hindi, Russian, Chinese (simplified and traditional), Japanese, Korean and Thai. You can select up to 4 per run. Modern Greek is not available.
How many files can one run handle?
maxFiles defaults to 1,000 and can be raised to 10,000 per run. Individual files can be up to 100 MB, and PDFs up to 2,000 pages each (200 by default via maxPagesPerPdf).
Am I charged for files that fail?
No. Failed downloads, unreadable files, blank pages and links that return a web page instead of a file are reported in the dataset and not charged. You pay $0.003 per OCR'd page and $0.0003 per PDF page read from its text layer.
How do I cut noise from stamps and stains?
Set minWordConfidence to drop words Tesseract is unsure about. The README suggests 40 to 60 removes most noise from stains and stamps; 0 keeps everything.
Use it from code
Run the actor through the Apify API with the input above.
cURL
curl -X POST "https://api.apify.com/v2/acts/actor-forge~ocr-to-text/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls": ["https://raw.githubusercontent.com/ocrmypdf/OCRmyPDF/main/tests/resources/linn.pdf", "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif", "https://github.com/tesseract-ocr/tessdoc/raw/main/images/eurotext.png"], "languages": ["eng", "fra"], "pdfMode": "auto", "outputMode": "document", "minWordConfidence": 40, "maxFiles": 5000}'JavaScript (Node.js)
// Node.js 18+ (built-in fetch). Set APIFY_TOKEN in your environment.
const input = {
"urls": [
"https://raw.githubusercontent.com/ocrmypdf/OCRmyPDF/main/tests/resources/linn.pdf",
"https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif",
"https://github.com/tesseract-ocr/tessdoc/raw/main/images/eurotext.png"
],
"languages": [
"eng",
"fra"
],
"pdfMode": "auto",
"outputMode": "document",
"minWordConfidence": 40,
"maxFiles": 5000
};
const res = await fetch(
"https://api.apify.com/v2/acts/actor-forge~ocr-to-text/run-sync-get-dataset-items",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify(input),
}
);
const items = await res.json();
console.log(items.length, items[0]);Python
# pip install apify-client (set APIFY_TOKEN in your environment)
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
"urls": [
"https://raw.githubusercontent.com/ocrmypdf/OCRmyPDF/main/tests/resources/linn.pdf",
"https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif",
"https://github.com/tesseract-ocr/tessdoc/raw/main/images/eurotext.png"
],
"languages": [
"eng",
"fra"
],
"pdfMode": "auto",
"outputMode": "document",
"minWordConfidence": 40,
"maxFiles": 5000
}
run = client.actor("actor-forge/ocr-to-text").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)The run-sync-get-dataset-items endpoint waits for the run (up to 5 minutes) and returns the dataset rows directly. For longer runs, start the run asynchronously and read the dataset when it finishes, as the Python example does. Replace APIFY_TOKEN with your own token from the Apify console.
Step-by-step guides
How to Extract Text from Images and Screenshots in Bulk
Send image URLs to the Image to Text OCR actor, use the sparse segmentation mode for screenshots, and read the text and confidence per image. It…
How to OCR Scanned PDFs to Text with an API
Send scanned PDF links to the PDF OCR actor, get text back one row per page with a confidence score, and use that score to flag pages for review.…
Related actors
PDF OCR — Scanned PDF to Searchable Text (29 Languages)
OCR scanned PDFs to text page by page with Tesseract 5 in 29 languages. Pages that already have a text layer are read directly at a tenth of the…
$3 per 1,000 · page ocrImage to Text OCR — Extract Text from Photos & Screenshots
Extract text from images (PNG, JPEG, TIFF, WebP, GIF, BMP) with Tesseract 5 OCR in 29 languages: screenshots, photos of documents, receipts, scans…
$3 per 1,000 · page ocrAny URL to Markdown — Web Pages, PDF, Word, Excel & OCR
Turn any URL into clean, LLM-ready Markdown: web pages, PDFs, Word, Excel, PowerPoint, EPUB, CSV and JSON, plus OCR for images and scanned PDFs. One…
$1 per 1,000 · page resultTry OCR on Apify. Pay only for the results you get.
Run on Apify →