How to extract text from images in bulk with an image to text OCR API
Short answer
Run the images through an OCR engine after cleaning them up: fix rotation, remove transparency, raise contrast and upscale small screenshots. Inkscry on Apify does that with Tesseract in 100+ languages and returns text, confidence and line boxes at $0.0024 per image; images with no text are free.
- Collect the image URLs (PNG, JPEG, WebP, GIF, BMP or TIFF), up to 25 MB each by default.
- Pick the languages, for example ["English"] or ["German", "English"] for mixed scans.
- Leave enhance on; set layout to sparse for signs, labels and memes.
- Turn on includeWords for receipts and forms when you need each word's position, and use minConfidence to drop noise.
- Read text and confidence per image; rows with status no-text cost nothing.
Copy-paste code
Python (pip install apify-client): image URLs in, text out
import csv, os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("cybermax/image-to-text-ocr").call(run_input={
"imageUrls": ["https://tesseract.projectnaptha.com/img/eng_bw.png"],
"languages": ["English"],
"includeLines": True,
})
with open("ocr.csv", "w", newline="") as f:
w = csv.writer(f)
w.writerow(["image", "status", "confidence", "text"])
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
w.writerow([r["imageUrl"], r["status"], r.get("confidence"), r.get("text", "")])JavaScript / Node (npm i apify-client): receipts with word boxes
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('cybermax/image-to-text-ocr').call({
imageUrls: ['https://example.com/receipt.jpg'],
includeWords: true,
minConfidence: 60,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const r of items) console.log(r.imageUrl, r.confidence, (r.wordBoxes || []).length, 'words');No code: n8n, Make or Zapier
n8n: HTTP Request node (or the Apify node, action "Run an Actor and get dataset")
Method: POST
URL: https://api.apify.com/v2/acts/cybermax~image-to-text-ocr/run-sync-get-dataset-items
Auth: Header Auth -> Authorization: Bearer <your Apify token>
Body: JSON {"imageUrls": {{ $json.images }}, "languages": ["English"]}
Output: one n8n item per image (text, confidence, lines)
Make: Apify app -> "Run an Actor" (Actor: cybermax/image-to-text-ocr, wait for finish = yes)
-> Apify "Get Dataset Items" (dataset = the run's defaultDatasetId) -> your next module
Zapier: Apify app -> action "Run Actor" (cybermax/image-to-text-ocr, input JSON as above)
-> trigger "Finished Actor Run" -> "Fetch Dataset Items" -> your app
Runs longer than 5 minutes: start with POST /v2/acts/cybermax~image-to-text-ocr/runs and read the dataset when the run finishes.From an AI agent (MCP)
# Any MCP client (Claude Desktop, Claude Code, Cursor, VS Code): Apify's hosted MCP server
{
"mcpServers": {
"image-to-text-ocr": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.apify.com/?tools=cybermax/image-to-text-ocr",
"--header", "Authorization: Bearer ${APIFY_TOKEN}"],
"env": { "APIFY_TOKEN": "<your Apify token>" }
}
}
}
# The agent sees one tool, cybermax--image-to-text-ocr, with the Actor's input schema.| Image | Text (start) | Confidence | Words |
|---|---|---|---|
| Tesseract sample page (eng_bw.png) | Mild Splendour of the various-vested Night! | 93 | 64 |
| Example.jpg (a photo, no text) | no text found (not charged) | 0 | 0 |
Source: Inkscry (Apify Actor cybermax/image-to-text-ocr) README, real Apify run on 10 Nov 2026
Why clean the image before OCR
Phone photos come in rotated, screenshots are small and logos sit on transparent backgrounds. Fixing rotation, flattening transparency, raising contrast and upscaling small images before Tesseract reads them noticeably improves accuracy on real-world pictures.
Line and word boxes for receipts and forms
Each line, and optionally each word, comes with its bounding box in the original image's pixels, so you can pick a total, a date or a vendor name by position.
Every image on a page, then OCR
Picpail downloads every image from a web page at full size; pass those image URLs to Inkscry to read them all in one run.
Good to know
Price on Apify: $0.0024 per image ($2.40 per 1,000), no start fee. Images with no text, failed downloads and non-images are free. Apify's free plan includes $5 of usage each month.
Printed text in clear images usually reads at 90%+ confidence; handwriting and blurry photos are harder for any OCR engine. Use it on images you own or may process.
Picpail: Every image on a page, full size, one ZIP
$0.0008 per image, duplicates and skips freeNeed the images first? Picpail downloads every image on a page at full size, in one ZIP, at $0.0008 per image; duplicates and skips are free.
Runs on your own Apify account, pay per result; failed results are not charged.Questions
Which languages work?
Any Tesseract language (100+), several at once, for example German and English together, or Japanese.
Can it read PDFs?
PDFs with a text layer are faster and cheaper with Pageshuck (PDF to text). For scanned pages, export them as images and read them with Inkscry.
Is a photo with no text charged?
No. Rows with status no-text are free.
Can an AI agent use it?
Yes. Apify's MCP server exposes it as cybermax--image-to-text-ocr for Claude, Cursor and other MCP clients.
Free: the Free API Starter Kit
Copy-paste calls for 4 APIs with free daily tiers (CVE priority, VIN recalls, US duty rates, email checks), then 5 short emails on KEV/EPSS, MCP and free data.