# Image to Text OCR (`cyber1nj3ct0r/image-to-text-ocr`) Actor

Read the text in images from their web addresses with the Tesseract OCR engine. For each image you get the text, a confidence score, line and word counts and, if you want, every word with its position. 35 languages. Receipts, screenshots, scans and labels.

- **URL**: https://apify.com/cyber1nj3ct0r/image-to-text-ocr.md
- **Developed by:** [Sanira Botheju](https://apify.com/cyber1nj3ct0r) (community)
- **Categories:** AI, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.75 / 1,000 images

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Image to Text OCR do?

Image to Text OCR reads the text in pictures. Give it the web addresses of your images and you get, for each one, the **text**, a **confidence score**, the **number of lines and words** and, if you ask for it, **every word with its position** in the image. Results are ready to export to Excel, CSV or JSON, or to send on to another app.

It uses Tesseract, a well-known open-source OCR engine, and runs it inside the tool, so nothing is sent to a third-party OCR service.

- Reads PNG, JPEG, GIF, BMP, TIFF, WebP and PBM/PGM/PPM images
- 35 languages, and more than one at a time for mixed text (for example English and German)
- Four page layouts: automatic, one block of text, one line, or scattered text
- Turns phone photos upright using the orientation stored in the JPEG file
- Many images per run, read in parallel when you give the run more memory
- Every image gets a row, and a problem (broken link, unsupported file, too large) is reported in that row instead of stopping the run

### What data do you get?

| Field | Example |
|---|---|
| Image address | `https://www.example.com/receipt.jpg` |
| Text | `CORNER MARKET LTD\nMilk 1L 1.20\nTOTAL 14.55` |
| Confidence | `95.1` (average over the words, 0 to 100) |
| Lines and words | `8` lines, `58` words |
| Languages | `["eng"]` |
| Image size | `1486` x `668` pixels, format `png` |
| Words (optional) | `{"text": "TOTAL", "confidence": 96.8, "bbox": {"x0": 36, "y0": 92, "x1": 96, "y1": 116}}` |
| Error | `null`, or a code such as `HTTP_ERROR` with a message |

### How to extract text from images

1. Under **Image addresses**, paste your list with **Bulk edit**, add addresses one by one, or link a text file (a Google Sheet published as CSV works too).
2. Pick the **Languages** of the text. English is the default.
3. Press **Start**.
4. Open the **Text from images** table, sort it by confidence or place in list, and export it.

### How much does it cost to extract text from images?

You pay for results, not for time: **$2.50 per 1,000 images**. Apify subscribers on the Silver plan pay $2.10 and on the Gold plan $1.75 per 1,000 images. Each run also has a start fee of $0.00005 per GB of memory; a run with the default 2 GB pays $0.0001.

| Images read | Cost |
|---|---|
| 100 | $0.25 |
| 1,000 | $2.50 |
| 10,000 | $25.00 |
| 100,000 | $250.00 |

Every address in your list gets one row, and each row is one result, including a row that reports an error (a broken link, a file that is not an image). Duplicate addresses are read and paid once. Apify's free plan includes $5 of credit each month, which covers about 2,000 images. Set a maximum cost for the run in Apify Console, or **Maximum number of images** in the input, and the tool stops there and keeps what it has read.

### Input

The only required field is **Image addresses**. The other options:

- **Languages**: pick up to 5. English is built in; any other language is downloaded at the start of the run, which takes a few seconds each. Pick only the languages that really occur in your images: in a test with five languages at once the reading took about 30% longer and a few results changed.
- **Page layout**: *Automatic* for pages, columns and screenshots; *One block of text* for a paragraph or a label; *One line of text* for a cropped line; *Scattered text* for photos, packaging and diagrams where text is spread around.
- **Include words with confidence and position**: adds a `words` list to each result. It makes the results larger.
- **Maximum number of images**: the first images of your list up to this number are read, the rest are skipped and not charged.
- **Maximum image file size** (default 20 MB, up to 50 MB), **Time limit per download** and **User-Agent** under More options. Pictures with more than 50 megapixels are never read, whatever their file size.

### Output example

```json
{
    "url": "https://tesseract.projectnaptha.com/img/eng_bw.png",
    "position": 1,
    "finalUrl": null,
    "httpStatus": 200,
    "text": "Mild Splendour of the various-vested Night!\nMother of wildly-working visions! hail!\nI watch thy gliding, while with watery light\nThy weak eye glimmers through a fleecy veil;\nAnd when thou lovest thy pale orb to shroud\nBehind the gather’d blackness lost on high;\nAnd when thou dartest from the wind-rent cloud\nThy placid lightning o’er the awaken’d sky.",
    "meanConfidence": 95.1,
    "lineCount": 8,
    "wordCount": 58,
    "languages": ["eng"],
    "imageFormat": "png",
    "imageWidth": 1486,
    "imageHeight": 668,
    "imageBytes": 26854,
    "ocrTimeMs": 276,
    "processedAt": "2026-10-16T07:28:35.501Z",
    "error": null
}
```

An image without any text is a normal result: `text` is empty, `wordCount` is `0` and `meanConfidence` is `null`. When an image cannot be read, `text` is `null` and `error` holds a code and a message:

- `HTTP_ERROR`: the server answered with an error such as 404 or 403.
- `UNSUPPORTED_FORMAT`: the file is not a format the tool reads, for example a PDF, an SVG, an AVIF or HEIC photo, an animated WebP, or a web page.
- `IMAGE_UNREADABLE`: the file is empty, cut off or damaged.
- `FILE_TOO_LARGE`: the file is larger than **Maximum image file size**.
- `IMAGE_TOO_LARGE`: the picture has more than 50 megapixels.
- `OCR_TIMEOUT`: reading the picture took longer than two minutes.
- `DNS_NOT_FOUND`, `TIMEOUT`, `CONNECTION_REFUSED`, `TLS_CERTIFICATE_EXPIRED` and other network errors: the image could not be downloaded.
- `BLOCKED_ADDRESS`: the address points to a private or local network, which the tool never fetches.
- `INVALID_INPUT`: the entry is not a web address.

### What can you use it for?

- **Receipts and invoices**: turn photos or scans into text you can search, or feed into bookkeeping and expense tools
- **Screenshots**: pull error messages, chat text, tables and UI labels out of screenshots
- **Scanned pages**: make scans of letters, forms and printed documents searchable
- **Product labels and packaging**: read ingredient lists, weights, dates and batch codes from product photos
- **Archives and catalogues**: add text to large image collections so they can be searched
- **Highlighting and checks**: use the word boxes to mark text in an image or to flag words the reader is unsure about

### Use it from the API

```bash
curl -X POST "https://api.apify.com/v2/acts/cyber1nj3ct0r~image-to-text-ocr/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"imageUrls": [{"url": "https://www.example.com/receipt.jpg"}], "languages": ["eng"], "includeWords": false}'
```

The same works from Python, JavaScript, Make, Zapier and n8n through Apify's integrations.

### FAQ

#### How accurate is it?

It depends on the image, and the tool makes no promise of a percentage. Tesseract works best on clean, upright, printed text with good contrast and letters at least about 20 pixels high. It reads poorly or not at all on handwriting, very small or blurry text, low-resolution images, text on busy backgrounds, decorative fonts and strongly curved or skewed text. The **confidence** is the engine's own estimate for each word: use it to find results that deserve a second look, not as proof that a text is right.

#### Does it read handwriting?

No. Tesseract is built for printed text. Handwriting usually comes out wrong.

#### What if my image is rotated?

The tool does not detect the direction of the text. Photos from phones and cameras are turned upright using the orientation stored in the JPEG file, but a scan saved sideways or upside down is read as it is, and the result is usually garbage with a low confidence. Rotate such images before you send them.

#### Which images does it read?

PNG, JPEG, GIF (the first frame), BMP, TIFF (uncompressed, LZW, PackBits or CCITT; the first page), WebP (not animated) and PBM/PGM/PPM. It does not read PDF, SVG, AVIF, HEIC, JPEG 2000, ICO or TIFF files compressed with ZIP or JPEG; those results carry an `UNSUPPORTED_FORMAT` error. For PDFs, convert the pages to PNG or JPEG first.

#### How long does it take?

Small images such as labels, receipts and screenshots take from a fraction of a second to a couple of seconds each; a full page of dense text can take several seconds. A run reads about one image at a time for every 4 GB of memory, so for long lists give the run more memory (up to 16 GB) to read several images at once. The cost per image stays the same.

#### How are the languages loaded?

English is part of the tool. For any other language the tool downloads the language file from the Tesseract project's public files (the "tessdata_fast" set on GitHub, through the jsDelivr network) when the run starts. That takes a few seconds per language. If a language file cannot be downloaded, the run stops with a message before reading anything, and nothing is charged.

#### Does it read robots.txt?

It downloads only the image addresses you give it, once each, and follows no links, so it does not crawl and does not read `robots.txt`.

#### A site blocks the tool. What can I do?

The tool identifies itself honestly in its User-Agent, downloads straight from Apify's servers and does not use proxies or try to get round blocks. If the images are on your own site, allow the User-Agent in your firewall, or set your own under **More options**. Otherwise download the images yourself and host them where the tool can reach them.

#### Can I use it to solve CAPTCHAs?

No. The tool is not built or tuned for CAPTCHAs, and using it to get round a site's protections is not allowed.

#### Is it allowed to read images?

The tool makes one request per address, like a visitor opening the image. It does not crawl or scrape: it fetches only the image files you list. You are responsible for having the right to download and process those images, and for what you do with the text, including any personal data in it. Do not use it to collect personal data, for example from ID cards, passports or photos of people, without a legal basis for doing so.

#### Something does not work

Open an issue on the **Issues** tab with an image address that shows the problem. Every report is read and answered.

# Actor input Schema

## `imageUrls` (type: `array`):

The addresses of the images to read, for example <code>https://www.example.com/receipt.jpg</code>. Add them one by one, paste many at once with <b>Bulk edit</b>, or link a text file (or a Google Sheet published as CSV) that holds them. PNG, JPEG, GIF, BMP, TIFF, WebP and PBM/PGM/PPM images work. Only these addresses are downloaded. Duplicates are read once.

## `languages` (type: `array`):

The language or languages of the text in your images. English is built in; every other language is downloaded at the start of the run, which takes a few seconds each. Pick only the languages that really occur: each extra one slows the reading down and can change the result. Up to 5.

## `pageLayout` (type: `string`):

How the text is laid out in your images. <b>Automatic</b> suits pages with paragraphs and columns, and screenshots. <b>One block</b> suits a single paragraph, a label or a sign. <b>One line</b> suits a cropped line such as a number plate or a caption. <b>Scattered text</b> finds as much loose text as possible, for example on photos, product packaging or diagrams.

## `includeWords` (type: `boolean`):

Add a list of every word to each result: the word, how sure the reader is about it (0 to 100) and its box in the image in pixels. Useful for highlighting text, filtering doubtful words or building searchable documents. Makes the results larger.

## `maxImages` (type: `integer`):

Read at most this many images, in the order of your list; the rest are skipped and not charged. Use it to cap the cost of a run.

## `maxImageSizeMb` (type: `integer`):

Images whose file is larger than this are not read; their result holds the error <code>FILE_TOO_LARGE</code>. Pictures with more than 50 megapixels are never read, whatever the file size.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for one image to download before giving up on it.

## `userAgent` (type: `string`):

The name the tool sends with each download. Leave empty to use the tool's own name, which tells site owners what is visiting. Set your own only for sites you run or have permission to use.

## Actor input object example

```json
{
  "imageUrls": [
    {
      "url": "https://tesseract.projectnaptha.com/img/eng_bw.png"
    },
    {
      "url": "https://raw.githubusercontent.com/naptha/tesseract.js/a1ca80d9e31c34512d0ded75ff8821ddcf3f2f91/tests/assets/images/testocr.png"
    }
  ],
  "languages": [
    "eng"
  ],
  "pageLayout": "AUTO",
  "includeWords": false,
  "maxImages": 1000,
  "maxImageSizeMb": 20,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

## `texts` (type: `string`):

One record per image with the text found in it, the reader's confidence, line and word counts, and an error when the image could not be read.

## `summary` (type: `string`):

Counts for the run: images given, read, with and without text, failed, the errors by kind, and the memory used.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrls": [
        {
            "url": "https://tesseract.projectnaptha.com/img/eng_bw.png"
        },
        {
            "url": "https://raw.githubusercontent.com/naptha/tesseract.js/a1ca80d9e31c34512d0ded75ff8821ddcf3f2f91/tests/assets/images/testocr.png"
        }
    ],
    "languages": [
        "eng"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cyber1nj3ct0r/image-to-text-ocr").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "imageUrls": [
        { "url": "https://tesseract.projectnaptha.com/img/eng_bw.png" },
        { "url": "https://raw.githubusercontent.com/naptha/tesseract.js/a1ca80d9e31c34512d0ded75ff8821ddcf3f2f91/tests/assets/images/testocr.png" },
    ],
    "languages": ["eng"],
}

# Run the Actor and wait for it to finish
run = client.actor("cyber1nj3ct0r/image-to-text-ocr").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrls": [
    {
      "url": "https://tesseract.projectnaptha.com/img/eng_bw.png"
    },
    {
      "url": "https://raw.githubusercontent.com/naptha/tesseract.js/a1ca80d9e31c34512d0ded75ff8821ddcf3f2f91/tests/assets/images/testocr.png"
    }
  ],
  "languages": [
    "eng"
  ]
}' |
apify call cyber1nj3ct0r/image-to-text-ocr --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cyber1nj3ct0r/image-to-text-ocr"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/hTlLNHBzwChewWZd0/builds/BfxAV9rlz2L8eidMj/openapi.json
