# Image to Text OCR: Images & Scanned PDFs to Text (Tesseract) (`best_apis/image-to-text-ocr`) Actor

OCR text from images, screenshots and scanned PDFs by URL or from a dataset: full text, lines and words with confidence and position, 17 built-in languages plus 100+ on demand. Blank pages and failed files are free. $1.50 per 1,000 pages.

- **URL**: https://apify.com/best_apis/image-to-text-ocr.md
- **Developed by:** [A Q](https://apify.com/best_apis) (community)
- **Categories:** AI, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Image to Text OCR: Images & Scanned PDFs to Text (Tesseract)

Extract **text from images, screenshots, photos and scanned PDFs** by URL, in bulk, with no API key and no outside service. The open-source **Tesseract 5 OCR engine** runs inside the Actor, so your files are never sent to Google, Microsoft or an AI API.

- **Images**: PNG, JPG/JPEG, WebP, GIF, TIFF, BMP, AVIF and SVG, auto-rotated by EXIF, upscaled when small, contrast-normalised
- **Scanned PDFs**: every page rendered and OCR'd, one row per page. In **Auto** mode pages that already have a text layer are copied exactly from the PDF instead (more accurate and 15x cheaper), so mixed PDFs just work
- **Full text** with paragraphs and line breaks preserved, plus **lines with confidence and bounding boxes** (x, y, width, height in pixels) and optional **word-level boxes**
- **Confidence score** per page, line and word, and a **minimum confidence** filter to drop noise from photos
- **17 built-in languages** (English, German, French, Spanish, Italian, Portuguese, Dutch, Polish, Russian, Ukrainian, Turkish, Arabic, Hindi, Chinese Simplified, Japanese, Korean, Vietnamese) and **100+ more on demand** (Czech, Swedish, Hebrew, Thai, Greek, Chinese Traditional...), combinable for mixed documents
- **Layout modes**: automatic, single column (receipts, lists), single block, sparse text (screenshots, signs, product labels), single line
- **Bulk input from a dataset**: point it at the output of any other scraper (product images, document links) and every URL is OCR'd, with the original item kept in `sourceItem`
- **Blank images and failed downloads are free**, and every failure is listed with its reason

### Pricing: $1.50 per 1,000 pages

| | This Actor | Other Tesseract OCR Actors on Apify |
|---|---|---|
| Image or scanned PDF page with text | **$0.0015** ($1.50 per 1,000) | $0.002 to $0.005 per image |
| Digital PDF page (text layer, Auto mode) | **$0.0001** ($0.10 per 1,000) | charged as a full OCR page |
| Images with no text, failed URLs | **free** | often charged |
| Actor start | $0.0005 per GB of memory | up to $0.005 per run |

1,000 screenshots cost **$1.50**. A 20-page scanned contract costs $0.03. Set **Max files** and your Apify maximum cost per run to cap spending; the run stops cleanly at the limit.

### Use cases

- **Document digitisation**: scanned contracts, invoices, letters, archives, old reports and forms to searchable text
- **AI and RAG pipelines**: make scanned PDFs and images readable for ChatGPT, Claude, LangChain or a vector database
- **E-commerce**: read text on product images, labels, packaging and banners scraped by other Actors (use the dataset input)
- **Screenshot to text**: UI text, error messages, charts, slides, social cards and memes
- **Compliance and monitoring**: detect phrases in ad creatives, banners and screenshots; keep word boxes as evidence
- **Research**: OCR historical documents and public records in many languages

### Input

| Field | What it does |
|---|---|
| `urls` | Image or PDF links. Empty = demo on two Tesseract test images |
| `datasetId` + `urlField` | Read URLs from an Apify dataset (dotted paths like `images.0` work; arrays of URLs are expanded) |
| `languages` | Tesseract codes, e.g. `["eng"]`, `["eng","deu"]`, `["chi_sim"]` |
| `pdfMode` | `auto` (text layer when present, OCR otherwise) or `ocr` (OCR every page) |
| `maxPdfPages`, `dpi` | Pages per PDF (default 100) and render resolution for scanned pages (default 200, 300 for small print) |
| `pageSegmentation` | Layout mode: 3 automatic, 4 single column, 6 single block, 11 sparse text, 7 single line |
| `includeLines`, `includeWords` | Add line and/or word arrays with confidence and bounding boxes |
| `minConfidence` | Drop words below this confidence (0-99) |
| `enhance` | Grayscale, upscale and normalise images before OCR (on by default) |
| `maxFiles`, `maxFileSizeMb`, `proxyConfiguration` | Limits and optional proxy |

Example:

```json
{
  "urls": ["https://www.irs.gov/pub/irs-prior/f1040--1913.pdf", "https://raw.githubusercontent.com/tesseract-ocr/tessdoc/main/images/eurotext.png"],
  "languages": ["eng", "deu", "fra"],
  "pdfMode": "ocr",
  "maxPdfPages": 1
}
```

### Output

One row per image or PDF page:

```json
{
  "url": "https://raw.githubusercontent.com/tesseract-ocr/test/master/testing/phototest.tif",
  "type": "image",
  "page": 1,
  "pages": 1,
  "width": 640,
  "height": 480,
  "format": "tiff",
  "method": "ocr",
  "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. ...",
  "confidence": 95.3,
  "wordCount": 60,
  "lineCount": 10,
  "languages": ["eng"],
  "lines": [{ "text": "This is a lot of 12 point text to test the", "confidence": 95.9, "bbox": { "x": 36, "y": 92, "width": 544, "height": 30 } }],
  "durationMs": 1033,
  "error": null
}
```

- `method` is `ocr` or `text-layer` (digital PDF page read directly; confidence 100)
- Failed files get a row with `error` (for example `HTTP 404`, `Not an image or PDF`, `PDF is password-protected`) and are not charged
- The `SUMMARY` record in the key-value store has counts of images, PDFs, OCR pages, text-layer pages, blank pages and failures

### Tips

- Use only the languages you need: each extra language slows OCR and can lower accuracy.
- For screenshots and photos with scattered text, try layout mode **Sparse text** and **Minimum word confidence** 50.
- For small print in scans, set **DPI** to 300.
- Speed: about 1-3 seconds per image and 3-10 seconds per dense A4 page at the default 2 GB. More memory = more parallel OCR workers.
- Need text from digital PDFs only (Markdown, chunks, metadata)? Use our [PDF Text Extractor](https://apify.com/best_apis/pdf-text-extractor) at $1 per 1,000 PDFs.

### FAQ

**Is OCR done by an external API?** No. Tesseract runs inside the Actor container, so files stay on Apify and there are no third-party API costs or keys.

**Does it read handwriting?** Tesseract is built for printed text. Neat block handwriting sometimes works; cursive usually does not.

**Can I OCR files that are not on the web?** Upload them to an Apify key-value store or any storage with a public link, then pass the URLs.

**Is it legal?** The Actor only processes files whose URLs you supply. Make sure you have the right to process them.

**Integrations**: use it from the Apify API, Python and JavaScript clients, Make, Zapier, n8n, LangChain, or as an MCP tool for AI agents.

# Actor input Schema

## `urls` (type: `array`):

Direct links to images (PNG, JPG, WebP, GIF, TIFF, BMP, AVIF, SVG) or PDFs (scanned or digital). Leave empty (and no dataset) for a demo on two public test images.

## `datasetId` (type: `string`):

ID or name of an Apify dataset (for example the output of another scraper). Every item's URL field (see URL field) is OCR'd and the item itself is kept in sourceItem. The Actor gets read-only access to this dataset only.

## `urlField` (type: `string`):

Field holding the image or PDF URL in each dataset item. Dotted paths like images.0 or image.url work.

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

Tesseract language codes, combined for mixed documents. Built in: eng, deu, fra, spa, ita, por, nld, pol, rus, ukr, tur, ara, hin, chi_sim, jpn, kor, vie. Any other code from the official tessdata list (e.g. ces, swe, heb, tha, chi_tra, ell) is downloaded on demand. Fewer languages = faster and more accurate.

## `pdfMode` (type: `string`):

Auto reads digital pages exactly from the PDF's own text (much cheaper, $0.10 per 1,000) and OCRs only scanned pages.

## `maxPdfPages` (type: `integer`):

Only the first N pages of each PDF are processed.

## `dpi` (type: `integer`):

Resolution used to render scanned PDF pages for OCR. 200 suits normal text; use 300 for small print.

## `pageSegmentation` (type: `string`):

Tesseract page segmentation mode. Automatic works for most pages; Sparse text finds scattered words in screenshots and photos.

## `includeLines` (type: `boolean`):

Add a lines array: text, confidence and bounding box (x, y, width, height in pixels) for every text line.

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

Add a words array with every word's confidence and bounding box. Large output on dense pages.

## `minConfidence` (type: `integer`):

Drop words recognised with lower confidence (0-99) from text and lines. 0 keeps everything; 40-60 removes noise from photos.

## `enhance` (type: `boolean`):

Auto-rotate by EXIF, convert to grayscale, upscale small images and normalise contrast. Usually improves accuracy on screenshots and photos.

## `maxFiles` (type: `integer`):

Hard cap on files per run, so cost stays predictable.

## `maxFileSizeMb` (type: `integer`):

Larger files are skipped and not charged.

## `proxyConfiguration` (type: `object`):

Optional. Only needed if a site blocks direct downloads.

## Actor input object example

```json
{
  "urls": [
    "https://raw.githubusercontent.com/tesseract-ocr/test/master/testing/phototest.tif",
    "https://raw.githubusercontent.com/tesseract-ocr/tessdoc/main/images/eurotext.png"
  ],
  "urlField": "url",
  "languages": [
    "eng",
    "deu"
  ],
  "pdfMode": "auto",
  "maxPdfPages": 100,
  "dpi": 200,
  "pageSegmentation": "3",
  "includeLines": true,
  "includeWords": false,
  "minConfidence": 0,
  "enhance": true,
  "maxFiles": 1000,
  "maxFileSizeMb": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `full` (type: `string`):

No description

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

No description

# 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 = {
    "urls": [
        "https://raw.githubusercontent.com/tesseract-ocr/test/master/testing/phototest.tif",
        "https://raw.githubusercontent.com/tesseract-ocr/tessdoc/main/images/eurotext.png"
    ],
    "languages": [
        "eng",
        "deu"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("best_apis/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 = {
    "urls": [
        "https://raw.githubusercontent.com/tesseract-ocr/test/master/testing/phototest.tif",
        "https://raw.githubusercontent.com/tesseract-ocr/tessdoc/main/images/eurotext.png",
    ],
    "languages": [
        "eng",
        "deu",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("best_apis/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 '{
  "urls": [
    "https://raw.githubusercontent.com/tesseract-ocr/test/master/testing/phototest.tif",
    "https://raw.githubusercontent.com/tesseract-ocr/tessdoc/main/images/eurotext.png"
  ],
  "languages": [
    "eng",
    "deu"
  ]
}' |
apify call best_apis/image-to-text-ocr --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,best_apis/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/kPFKeSkUb6wdjGvOF/builds/86zTAJpz55AB42llA/openapi.json
