Image to Text API avatar

Image to Text API

Pricing

from $1.60 / 1,000 image reads

Go to Apify Store
Image to Text API

Image to Text API

Image to text: OCR with line and word positions and confidence scores. $0.002 per image OCR result; start extra; usage included; failed results uncharged.

Pricing

from $1.60 / 1,000 image reads

Rating

0.0

(0)

Developer

Logan Parker

Logan Parker

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Image to text OCR extracts text from supported images with line and word positions and confidence scores, using Tesseract and the selected language. AI agents can call and pay through Apify MCP. List event rates are $0.002 per image OCR result; start is extra, usage is included and failed results are uncharged.

Example result

Example record for the minimal input under How to use it, as this Actor returned it in its deploy check on 2026-10-16:

{
"url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif",
"ok": true,
"text": "This is a lot of 12 point text to test the\nocr code and see if it works on all types\nof file format.\n\nThe quick brown dog jumped over the\nlazy fox. The quick brown dog jumped\nover the lazy fox. The quick brown dog\njumped over the lazy fox. The quick\nbrown dog jumped over the lazy fox.",
"lines": [
{"text": "This is a lot of 12 point text to test the", "confidence": 96.1, "box": {"x": 36, "y": 92, "w": 544, "h": 30}},
{"text": "ocr code and see if it works on all types", "confidence": 95.8, "box": {"x": 36, "y": 126, "w": 582, "h": 31}},
{"text": "of file format.", "confidence": 95.5, "box": {"x": 36, "y": 160, "w": 187, "h": 24}},
{"text": "The quick brown dog jumped over the", "confidence": 96.1, "box": {"x": 36, "y": 194, "w": 549, "h": 31}},
{"text": "lazy fox. The quick brown dog jumped", "confidence": 96.2, "box": {"x": 37, "y": 228, "w": 548, "h": 31}},
{"text": "over the lazy fox. The quick brown dog", "confidence": 96.1, "box": {"x": 36, "y": 262, "w": 561, "h": 31}},
{"text": "jumped over the lazy fox. The quick", "confidence": 96.3, "box": {"x": 43, "y": 296, "w": 518, "h": 31}},
{"text": "brown dog jumped over the lazy fox.", "confidence": 96.3, "box": {"x": 37, "y": 330, "w": 524, "h": 31}}
],
"width": 640,
"height": 480
}

How to use it

Start a run in Apify Console, by API or from an agent with an input like this one — it is the input Apify runs every day to test this Actor:

{"urls": ["https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif"]}

Start with the minimal JSON example above, then adjust the fields in the table below. Read the Example result and Output fields sections for the returned record, Errors for failure codes, and Events and prices for result events and the separate platform start.

FieldTypeRequiredDefaultMeaning
urlsarray of stringsyes—Image URLs (PNG, JPEG, WebP, TIFF, BMP, GIF), http or https, 1–1,000 per run, up to 20 MB, 50 megapixels and 32,767 pixels on a side each.
languagesarray of stringsno["eng"]One to three explicit Tesseract language/variant codes. 123 installed codes cover 100+ languages; full inventory below. Unknown codes return invalid_input, never silently English.
granularityenum text · lines · words · paragraphsnolinestext returns plain text only; lines adds each line with its confidence and box; words adds each word; paragraphs adds each paragraph.
minConfidenceintegerno0Drop words read with a confidence below this (0–100), and lines left with no word.
layoutenumnoautoSix layouts: auto (PSM 3), single_block (6), single_line (7), single_word (8), sparse_text (11), raw_line (13). Choose the layout that matches the image; raw_line passes one text line without Tesseract's line heuristics.
thresholdbooleannofalseApply a fixed grayscale threshold of 128 before OCR. Off keeps the existing grayscale/resize behavior. It does not deskew or retry the image.
normalizeBoxesbooleannofalseAdd boxNorm with x/y/w/h in 0–1 oriented-image coordinates beside each pixel box; applies to lines, words or paragraphs.
includeMarkdownbooleannofalseAdd literal escaped markdown, preserving lines and paragraphs without generated headings.
includeConfidencebooleannofalseAdd confidence, the mean confidence of kept words, or null when no words remain.

Every limit above is enforced by the input schema and again in code.

Events and prices

Pay per event; platform usage is included in the price, never passed through.

EventTitleCharged whenFREE / BRONZESILVERGOLD / PLATINUM / DIAMOND
image-ocrImage readOne image read by OCR.$0.002$0.0018$0.0016

Apify also charges its standard apify-actor-start event: $0.00005 per GB of run memory (1 event, $0.00005, at the default 1,024 MB). The minimum maximum-charge a caller can set is $0.01.

Worked example on the FREE tier: 10 images cost 10 × $0.002 = $0.02, plus $0.00005 for the start, $0.02005 in all. Nothing is charged for a failed image.

Call it from an agent

Through Apify's MCP server (https://mcp.apify.com), tool call-actor:

{"actor": "hermeskd/image-to-text", "input": {"urls": ["https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif"]}, "callOptions": {"maxTotalChargeUsd": 0.05, "timeout": 600}, "waitSecs": 30}

The call returns the run's status and its defaultDatasetId. Read the records with get-dataset-items:

{"datasetId": "<defaultDatasetId from the call>", "limit": 50}

As a dedicated tool, add https://mcp.apify.com?tools=hermeskd/image-to-text to your MCP client. One image finishes well inside the 30-second wait, so one call-actor plus one get-dataset-items is the whole exchange. maxTotalChargeUsd caps what the run can charge; when it is reached the remaining URLs come back as charge_limit_reached records and are not charged.

Output fields

One record per input URL.

FieldMeaning
urlThe input URL.
oktrue when the image was read; false with error.
textAll text read, in reading order: lines by a newline, paragraphs by a blank line. An image with no readable text gives ok: true and an empty string, and is charged — the read was done.
linesWith granularity: lines: each line as {text, confidence, box: {x, y, w, h}}, boxes in the image's own pixels.
wordsWith granularity: words: each word as {text, confidence, box: {x, y, w, h}}.
paragraphsWith granularity: paragraphs: each TSV paragraph with its text, mean kept-word confidence and pixel box.
markdownWith includeMarkdown: escaped source text.
confidenceWith includeConfidence: mean kept-word confidence (0–100), null for no words. This is the OCR engine's score, not a calibrated probability.
widthImage width in pixels, after EXIF orientation.
heightImage height in pixels, after EXIF orientation.
error{code, message} when ok is false.

Limits and run time

  • 1–1,000 direct image URLs accepted per run; images up to 20 MB, 50 megapixels and 32,767 pixels on a side (Tesseract's own limit — a very long screenshot is refused as too_large); TIFF reads its first page and GIF its first frame.
  • One image may take at most 120 seconds of OCR; an image that needs longer is answered too_large, uncharged.
  • Each request — its redirects and its whole body included — must finish within 30 seconds (the per-request timeout; a slower file is download_failed); at most 2 requests a second go to one host.
  • Images whose longer side is under 1,600 pixels are read at twice their size, which helps the small text of screenshots; boxes are always in the image's own pixels.
  • Default memory is 1,024 MB (one quarter of a CPU core), with a 600-second timeout. Runtime depends on image size, language count and CPU allocation. At the previous 4,096 MB allocation, a full 300-dpi page took about 3 seconds of OCR. Paid work stops after at most 540 seconds, or the platform deadline minus its shutdown margin if sooner, reserving time for the remaining timeout/charge-limit records. At most one image is decoded/OCR'd at a time; at most 100 failure rows are buffered for one dataset write. Input images are not retained between items. Identical fetched bytes with the same OCR settings can reuse successful result fields within the run; every URL is still fetched and each readable result is charged separately. The bounded result cache is discarded when the run ends. The platform enforces the run's configured memory limit (default 1,024 MB); select more memory for large images or three-language calls. Accepting 1,000 URLs does not promise all are processed in ten minutes. A longer caller timeout does not extend the Actor's 540-second work budget. Platform interruption or unavailable result storage can prevent the final records being written.

Errors

Errors are records with ok: false and error.code; none is charged.

error.codeMeaning
download_failedThe URL did not return the file (status or network error).
not_imageNot a supported image (PNG, JPEG, WebP, TIFF, BMP, GIF), or a damaged one that cannot be decoded.
too_largeOver 20 MB, 50 megapixels or 32,767 pixels on a side, or too dense to read within 120 seconds.
robots_disallowedrobots.txt forbids fetching the URL.
blocked_hostThe host is on the deny-list, or resolves to a private or local address.
timeoutThe image did not finish within the run's time budget.
internal_errorUnexpected failure; message carries the class.
charge_limit_reachedThe run reached its maximum total charge before this URL; it was not processed.
invalid_inputThe run input passed the input schema but cannot be used (for example no URL at all); the message names the field. One record per input given, or one with url: null when none was given; nothing is processed.

The run fails only when every input failed with an Actor-side code (internal_error, timeout), so a broken Actor is visible. Every other run succeeds — including one where nothing was read because of the caller's own inputs (bad URL, robots, deny-list, not an image, invalid input, the charge limit), or where those and Actor-side failures are mixed.

Sources and terms

The source is the caller's image. Process only images you have the right to process. Fetching follows the Hermes fetch policy: robots.txt is obeyed for the user-agent HermesBot (and *), and a disallowed URL is refused without a request; platforms whose terms forbid automated access, and people-search sites, are on a deny-list and refused without a request; private and local addresses are refused, after DNS and on every redirect; the user-agent is HermesBot/1.0 (+https://apify.com/hermeskd); no login, cookies, credentials, CAPTCHA solving, evasion or proxies are used. The text read is returned to the caller as it is; no person, face or speaker is identified.

Language data

The built image includes 123 explicitly supported language/variant codes covering 100+ languages. Vertical and historical variants are counted as model codes, not separate languages. Select at most three codes; models are baked in and are never downloaded during a run. There is no automatic language detection or fallback for unknown codes. The original sixteen distribution model files remain unchanged. Additional data are pinned to the tesseract-ocr/tessdata_fast tree 87416418657359cb625c412a48b6e1d6d41c29bd and verified by their Git blob hashes at build; language_inventory.json in the image records the installed SHA-256 values and source of every code.

Supported codes: afr, amh, ara, asm, aze, aze_cyrl, bel, ben, bod, bos, bre, bul, cat, ceb, ces, chi_sim, chi_sim_vert, chi_tra, chi_tra_vert, chr, cos, cym, dan, deu, deu_latf, div, dzo, ell, eng, enm, epo, est, eus, fao, fas, fil, fin, fra, frm, fry, gla, gle, glg, grc, guj, hat, heb, hin, hrv, hun, hye, iku, ind, isl, ita, ita_old, jav, jpn, jpn_vert, kan, kat, kat_old, kaz, khm, kir, kmr, kor, kor_vert, lao, lat, lav, lit, ltz, mal, mar, mkd, mlt, mon, mri, msa, mya, nep, nld, nor, oci, ori, pan, pol, por, pus, que, ron, rus, san, sin, slk, slv, snd, spa, spa_old, sqi, srp, srp_latn, sun, swa, swe, syr, tam, tat, tel, tgk, tha, tir, ton, tur, uig, ukr, urd, uzb, uzb_cyrl, vie, yid, yor.

Tesseract and tessdata_fast use Apache-2.0; Pillow uses MIT-CMU. Licence texts read on 2026-10-28 are shipped in licenses/tesseract-LICENSE.txt, licenses/tessdata_fast-LICENSE.txt and licenses/Pillow-LICENSE.txt. The additional models include their upstream attribution; the image retains distribution-package licences for the original sixteen. No competitor code or model, paid API or Google Lens endpoint is used. PDF, dataset, CSV, base64, SVG and HEIF input are not supported by this build; TIFF and GIF still use only the first page/frame.

Not affiliated

This Actor is not affiliated with Google or with the Tesseract project. Tesseract and Pillow are used under their open-source licences.

Changelog

  • 1.0 (2026-10-28) — image-only expansion: 100+ languages, up to three codes, six explicit layouts, optional thresholding, 1,000 bounded URLs, paragraph and normalized boxes, escaped Markdown and optional mean confidence. Existing default output, price and events retained.

  • 1.0 (2026-10-26) — store listing rewritten for the people and agents searching for this job: title, description, search-engine title and description, categories, and the README in the order a searcher reads it (what it does, a real result, how to use it, prices, the agent call).

  • 1.0 (2026-10-16) — images over 32,767 pixels on a side and images too dense to read in 120 s are refused as too_large; any image Pillow cannot decode is not_image.

  • 1.0 (2026-10-16) — first release: OCR of six image formats in sixteen languages, text, lines or words with confidence and boxes.