# OCR: Image & Scanned PDF to Text (Tesseract, 40 languages) (`timeout/ocr-image-pdf-to-text`) Actor

Bulk OCR for images and scanned PDFs: image to text and scanned PDF to text in 40 languages with Tesseract 5. Per-page text, confidence score, optional word bounding boxes and hOCR. Auto-rotation, smart PDF text-layer mode. Blank pages and errors are free.

- **URL**: https://apify.com/timeout/ocr-image-pdf-to-text.md
- **Developed by:** [Cesar Rodriguez](https://apify.com/timeout) (community)
- **Categories:** AI, Automation, Developer tools
- **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

## OCR: Image & Scanned PDF to Text (Tesseract, 40 languages)

Extract text from **images and scanned PDFs** in bulk. Give it a list of URLs (PNG, JPEG, TIFF, WEBP, GIF, BMP or PDF) and get back **one clean result per page**: the recognised text, a **confidence score**, and optionally **every word with its bounding box** or the page as **hOCR**.

Image to text, scanned PDF to text, photo to text, multi-page TIFF to text – runs on the open-source **Tesseract 5 OCR engine** inside your Apify run. No third-party AI API is called, and no API key is needed.

### Why use it

- **Low price per page** and **blank pages, failed downloads and unreadable files are free** (see *Pricing*).
- **Smart PDF mode**: pages that already contain selectable text are extracted directly (exact and cheaper); only real scans are OCR'd.
- **40 languages**, mixable in one run: English, Spanish, German, French, Italian, Portuguese, Dutch, Polish, Czech, Slovak, Romanian, Hungarian, Turkish, Swedish, Danish, Norwegian, Finnish, Catalan, Galician, Basque, Greek, Russian, Ukrainian, Bulgarian, Croatian, Serbian (Latin), Slovenian, Lithuanian, Latvian, Estonian, Arabic, Hebrew, Hindi, Vietnamese, Indonesian, Thai, Chinese (Simplified and Traditional), Japanese and Korean.
- **Quality signals you can act on**: `meanConfidence` per page and `lowConfidenceWords` so you know which pages need a human look.
- **Auto-rotation** of pages scanned sideways or upside down, and automatic upscaling of small images (screenshots, thumbnails).
- **Clear per-file errors** (404, not an image/PDF, too large, password-protected) – one bad link never breaks the run.
- **Limits you control**: max files, max pages per file, max pages per run, max file size.

### Typical uses

Digitising archives and old documents · scanned invoices, contracts and letters to text · feeding scanned documents into search, RAG and LLM pipelines · extracting text from screenshots and product images · checking which documents in a batch are scans.

### Input

```json
{
  "sources": [
    { "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif" },
    { "url": "https://github.com/ocrmypdf/OCRmyPDF/raw/main/tests/resources/linn.pdf" }
  ],
  "languages": ["eng"],
  "pdfMode": "auto",
  "includeWords": false,
  "includeHocr": false,
  "maxPagesPerFile": 50
}
```

- `languages` – put the main language first and only add languages that really appear: each extra language is slower and can reduce accuracy. Example for a Spanish document with English terms: `["spa", "eng"]`.
- `pdfMode` – `auto` (default) uses the existing text layer when a PDF page has one; `ocr` forces OCR on every page.
- `pageSegmentation` – `auto` for documents, `sparse-text` for photos, receipts and screenshots, `single-line` for one-line crops.
- `keyValueStoreKeys` + `keyValueStoreId` – OCR files saved in an Apify key-value store (e.g. by another Actor) instead of URLs.

### Output (one dataset item per page, shortened)

```json
{
  "fileName": "linn.pdf",
  "fileType": "pdf",
  "page": 1,
  "pageCount": 1,
  "status": "ok",
  "method": "ocr",
  "languages": "eng",
  "text": "The LinnSequencer\n32 Track MIDI Sequence Recorder\n\nThe LinnSequencer is a state-of-the-art composition and performance tool ...",
  "meanConfidence": 95.5,
  "wordCount": 728,
  "lowConfidenceWords": 2,
  "rotationApplied": 0,
  "words": [{ "text": "The", "confidence": 93.1, "bbox": [882, 132, 1036, 202], "block": 1, "line": 1 }]
}
```

`status` is `ok` (charged), `empty` (no text on the page – not charged) or `error` (with a readable `error` message – not charged). Download the dataset as JSON, CSV, Excel or HTML from the run page or the API, or join `text` by `fileName` to get whole documents.

### Pricing

Pay per event (see the *Pricing* tab): a small fee per run start, a fee **per OCR'd page**, and a lower fee **per PDF page that already had a text layer**. Blank pages, failed downloads, unsupported files and pages over your limits are **not charged**. Set *Max total charge* on your run to cap spending.

**Speed tip:** OCR is CPU-bound. The default 2 GB memory handles typical batches; give the run 4–8 GB for large batches (more CPU = more pages processed in parallel).

### Accuracy and honest limits

- Tesseract is excellent on printed text (books, letters, reports, forms, screenshots) – typically 90+ mean confidence on clean scans at 300 DPI. It is **not built for handwriting** and struggles with heavy decorative fonts, very low-resolution photos and complex layouts.
- Tables are returned as text lines, not as structured tables. For digital PDFs with tables, see our [PDF Table Extractor](https://apify.com/timeout/pdf-tables-extractor).
- Only public `http(s)` URLs (or files in your key-value store). You are responsible for having the right to process the documents you submit.

### Use with AI agents / MCP

Works through the [Apify MCP server](https://mcp.apify.com): an agent passes image or PDF URLs and reads back page text with confidence scores, ready for summarisation, extraction or RAG.

### FAQ

**Are my files sent to a third party?** No. Files are downloaded inside your Apify run and processed with Tesseract (Apache-2.0) and PDFium. Results stay in your run storages.

**Why is a page `empty`?** No text was found (blank page, photo without text). It is not charged. If you expected text, try `pageSegmentation: "sparse-text"`, a higher `pdfDpi`, or check the language selection.

**Can I get searchable PDFs?** Not yet – use `includeHocr` to get text with coordinates. Missing a feature? Open an issue in the *Issues* tab.

# Actor input Schema

## `sources` (type: `array`):

Public http(s) links to images (PNG, JPEG, TIFF incl. multi-page, WEBP, GIF, BMP) or PDFs (scanned or digital). One dataset item is returned per page.

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

Languages of the text. Put the main language first; pick only the languages that actually appear (each extra language makes OCR slower and can lower accuracy).

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

auto: pages that already have a text layer are extracted directly (cheaper, exact), other pages are OCR'd. ocr: always render and OCR every page.

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

Add words\[] with text, confidence (0-100), bbox \[x0,y0,x1,y1] in pixels of the OCR'd image, block and line number.

## `includeHocr` (type: `boolean`):

Add the hOCR (HTML with layout and coordinates) of each OCR'd page.

## `autoRotate` (type: `boolean`):

Detect pages scanned sideways or upside down (90/180/270 degrees) and rotate them before OCR.

## `upscaleSmallImages` (type: `boolean`):

Images under 1000 px are enlarged before OCR (improves small text such as screenshots and thumbnails).

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

How Tesseract splits the page. 'auto' fits documents; 'sparse-text' fits photos, receipts and screenshots with scattered text; 'single-line' fits one-line crops.

## `pdfDpi` (type: `integer`):

Resolution used to render scanned PDF pages for OCR. 300 is the standard; use 400 for very small print.

## `pdfPassword` (type: `string`):

Password for protected PDFs (applied to all PDFs in the run).

## `keyValueStoreKeys` (type: `array`):

Process files stored as records in an Apify key-value store (for example saved by another Actor or via the API) instead of, or in addition to, URLs.

## `keyValueStoreId` (type: `string`):

Key-value store that holds the keys above (pick it, or paste its ID). Empty = this run's default key-value store.

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

Safety cap on the number of files processed in one run.

## `maxPagesPerFile` (type: `integer`):

Only the first N pages of each PDF / multi-page TIFF are processed.

## `maxTotalPages` (type: `integer`):

Safety cap on the total pages (and therefore cost) of one run.

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

Larger files are skipped with an error item (not charged).

## Actor input object example

```json
{
  "sources": [
    {
      "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif"
    },
    {
      "url": "https://github.com/ocrmypdf/OCRmyPDF/raw/main/tests/resources/linn.pdf"
    }
  ],
  "languages": [
    "eng"
  ],
  "pdfMode": "auto",
  "includeWords": false,
  "includeHocr": false,
  "autoRotate": true,
  "upscaleSmallImages": true,
  "pageSegmentation": "auto",
  "pdfDpi": 300,
  "maxFiles": 100,
  "maxPagesPerFile": 50,
  "maxTotalPages": 500,
  "maxFileSizeMb": 25
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items (JSON, CSV, Excel via the API format parameter).

# 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 = {
    "sources": [
        {
            "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif"
        },
        {
            "url": "https://github.com/ocrmypdf/OCRmyPDF/raw/main/tests/resources/linn.pdf"
        }
    ],
    "languages": [
        "eng"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("timeout/ocr-image-pdf-to-text").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 = {
    "sources": [
        { "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif" },
        { "url": "https://github.com/ocrmypdf/OCRmyPDF/raw/main/tests/resources/linn.pdf" },
    ],
    "languages": ["eng"],
}

# Run the Actor and wait for it to finish
run = client.actor("timeout/ocr-image-pdf-to-text").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 '{
  "sources": [
    {
      "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif"
    },
    {
      "url": "https://github.com/ocrmypdf/OCRmyPDF/raw/main/tests/resources/linn.pdf"
    }
  ],
  "languages": [
    "eng"
  ]
}' |
apify call timeout/ocr-image-pdf-to-text --silent --output-dataset

```

## MCP server setup

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

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/6a3pWYCptQgBPk2dd/builds/lzz4XVJuCIfeJXjlH/openapi.json
