# Image to Text & PDF OCR: Searchable PDF, 100+ Languages (`tamatama/image-pdf-ocr`) Actor

Image to text and PDF OCR for screenshots (dark mode too), photos, receipts and scanned PDFs. No OCR API key, built-in Tesseract. Bulk OCR from URLs, base64, an Apify dataset, CSV, Excel or Google Sheet. 100+ languages, RAG chunks, searchable PDF. From $1.20/1,000 OCR pages ($2 on the Free plan).

- **URL**: https://apify.com/tamatama/image-pdf-ocr.md
- **Developed by:** [Otama Labs](https://apify.com/tamatama) (community)
- **Categories:** AI, Developer tools, Agents
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 ocr pages

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

## Image to Text & PDF OCR: Searchable PDF, 100+ Languages

**Image to text OCR** and **bulk OCR** for **screenshots** (dark mode too), photos, receipts and scanned PDFs (**PDF OCR** with an optional **searchable PDF**), for developers building RAG and AI-agent pipelines and for anyone who has to dig text out of screens and scans. **No OCR API key is needed**: Tesseract runs inside the Actor. Send **images or scanned PDFs** (PNG, JPEG, TIFF incl. multi-page, WebP, GIF, BMP, PDF) one at a time or in bulk, as **links, a column of a spreadsheet or Google Sheet, an Apify dataset, or base64**, in **100+ languages** (Arabic, Hindi, Thai, Cyrillic and more; Japanese, Chinese and Korean also in vertical writing). You get the **text of every page**, **RAG-ready chunks with page numbers**, optional **word boxes with confidence**, and an optional **searchable PDF** (grayscale page images with an invisible text layer).

**From $1.20 per 1,000 OCR pages** ($2 on the Free plan, less on paid plans). PDF pages that **already have text are read without OCR for $0.30 per 1,000**, and **blank pages and failures are free**. Your files are not sent to a third-party OCR API.

### What you can use it for

- **Screenshot to text**: app screens, chat windows, dashboards and error messages become text. Dark mode works as is: in our tests, a dark web page with white text was read at a mean confidence of about 93 (also at half size, because images under 1,200 px on the long side are enlarged before OCR), and a full-HD dark screen with small letters at about 91.
- **RAG and AI agents**: scanned contracts, letters, receipts and old reports become text with page numbers, ready for a vector database. Agents can send a file they hold as base64.
- **A sheet full of links**: a CSV, Excel file or Google Sheet with a column of receipt, invoice or product-label image links is read row by row, and each result keeps the row's own columns (`sourceRow`) so you can join it back by ID or SKU.
- **After another Actor**: point the Actor at the dataset of a scraper run that collected image or PDF URLs, or let it start automatically after each successful run through an integration (see the FAQ). When a field holds a list of links, such as all the images of a carousel post or a product gallery, set **URL column** to that field: every image is read and comes back with its row and its position (`urlIndex`).
- **Searchable archives**: turn a folder of scans into searchable PDFs that open in any PDF viewer.
- **Mixed PDFs**: a PDF where only some pages are scans is handled in one run; text pages are copied exactly and charged at the lower price.
- **Data entry**: word boxes (position and confidence) let you pick out fields such as totals and dates.

### Output example

The prefilled example (`phototest.tif` from the Tesseract test set), **Output format = Text** (one row per file):

```json
{
  "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif",
  "fileName": "phototest.tif",
  "fileType": "tiff",
  "pageCount": 1,
  "pagesProcessed": 1,
  "pagesOcr": 1,
  "pagesTextLayer": 0,
  "pagesBlank": [],
  "pagesFailed": [],
  "languages": "eng",
  "meanConfidence": 96.4,
  "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. ...",
  "charCount": 285,
  "pages": [
    { "page": 1, "method": "ocr", "confidence": 96.4, "rotation": 0, "text": "This is a lot of 12 point text to test the\n..." }
  ],
  "searchablePdfUrl": null,
  "error": null,
  "processedAt": "2026-10-21T03:49:28.376303+00:00"
}
```

The same page turned sideways (`phototest-rotated-L.png`) comes back with the same text and `"rotation": 90`. A two-page PDF that already has text comes back with `"method": "text-layer"` on both pages and is charged as two `text-page` events.

With **Include word boxes**, each page also has `words`, e.g. `{ "text": "quick", "confidence": 95.9, "left": 102, "top": 194, "width": 75, "height": 30, "block": 1, "line": 1 }`. Positions are in pixels of the original image (for PDF pages: pixels at 300 DPI), measured on the page after its orientation was fixed.

### How to use

1. Give the Actor the files in one of these ways (you can combine them in one run):
   - **Image or PDF URLs**: public links, pre-signed S3 or Cloud Storage URLs, direct Dropbox links, Apify key-value store records.
   - **Bulk**: an **Apify dataset**, or the link of a **CSV, Excel or JSON file or a Google Sheet** shared as "Anyone with the link", with one file link per row (in a dataset or JSON file, also a field with a list of links). The column with the links is found automatically, or name it in **URL column**.
   - **Files as base64**: `[{"name": "receipt.jpg", "data": "<base64>"}]`, for agents and scripts that hold the file itself.
2. Pick the **Languages** of the text (English by default, up to 3 at once).
3. Optionally turn on **Create a searchable PDF** or **Include word boxes**, or choose **RAG chunks** as the output format.
4. Press **Start** and wait for the run to finish (seconds for a few images). Each file is one row in the run's dataset, which you can export in several formats or fetch over the API.

The prefilled example reads `phototest.tif`, a test image from the Tesseract project, and finishes in under a minute.

### Input

| Field | What it does |
|---|---|
| **Image or PDF URLs** | Links to images (PNG, JPEG, TIFF, WebP, GIF, BMP) or PDFs. The type is detected from the file content. Up to 50 MB per file. You can also link a text file that lists URLs (up to 1,000). |
| Languages | Up to 3 at once, English by default. 100+ languages (123 language models, counting vertical and historic variants), e.g. `eng`, `deu`, `fra`, `spa`, `por`, `ita`, `rus`, `ukr`, `ara`, `heb`, `hin`, `ben`, `tha`, `vie`, `ind`, `jpn`, `jpn_vert`, `chi_sim`, `chi_tra`, `kor`; the full list is in the input form. |
| Output format | `text` (one row per file with a `pages` list) or `chunks` (one row per RAG chunk with `pageStart` / `pageEnd`). |
| Create a searchable PDF | Saves one PDF per file in the run's key-value store; the link is in `searchablePdfUrl`. No extra charge. |
| Include word boxes | Adds every word with its confidence (0-100) and pixel position to each page. |
| Apify dataset with file links | A dataset ID, e.g. from a scraper run. Up to 5,000 items, one file per item or every link of a list field. |
| Spreadsheet URL | A public CSV, Excel (.xlsx, first sheet), JSON or JSON Lines file, or a Google Sheets link. Up to 5,000 rows. |
| URL column | The column or field with the links (dots for nested fields, e.g. `receipt.url`). A field with a list of links (e.g. `images`) gives one result per link, up to 50 per row. Empty = the column with the most links. |
| Files as base64 | A list of `{"name", "data"}` objects; `data` is base64 or a `data:` URL. The whole input must stay under about 9 MB. |
| Fix page orientation | On by default: pages that are sideways or upside down are turned before OCR. |
| OCR pages that already have text | Off by default. Turn on if a PDF's existing text layer is wrong. |
| Max pages per file | 0 = all, up to 500. |
| Chunk size / Chunk overlap | For RAG chunks: maximum characters per chunk (default 2,000) and characters repeated from the previous chunk (default 200). |

With bulk input, every result row also has `rowNumber` (1 = first data row; empty rows are not counted) and `sourceRow` (the row's own columns, up to 30, values cut at 500 characters). A CSV that is just a list of links, without a header row, works too. Rows without a link are skipped; a cell that is not exactly one http(s) link gives a free error row. In a dataset or JSON file, a field that holds a list (of links, or of objects with a link) gives one result per link with `urlIndex`, its position in the list (1 = first). In a list of objects, the link that looks like an image or PDF is taken, or name the field inside, e.g. `childPosts.displayUrl`. Single-link columns are preferred when the column is guessed, so name a list field in **URL column**. Up to 50 links per row and 5,000 files per dataset or sheet are read (the rest is reported in the run log and `SUMMARY`). The same link in several rows is read and charged once. Rows after the first 5,000 are not read (the run log and `SUMMARY` say so). If you leave the form's example link in **Image or PDF URLs** next to bulk or base64 input, it is skipped.

### How it works

1. Each file is downloaded (at most one request per second to the same host; busy servers are retried twice).
2. PDF pages with a usable text layer are read directly. Other pages are rendered at 300 DPI; images are converted to grayscale, and images under 1,200 px on the long side (small screenshots, thumbnails) are enlarged so small letters can be read.
3. Tesseract detects the orientation, then recognizes the text (LSTM engine). A page that comes back empty is read once more as sparse text (not with the vertical variants), which catches a label, a screenshot or a single word that the page layout analysis misses; that second reading counts only when Tesseract is fairly sure (mean confidence 60 or more, with at least one sure word of 3 or more letters), so specks and noise stay blank. Each page gets a `method`: `ocr`, `text-layer`, `blank` or `failed`.
4. With a searchable PDF, OCR'd pages are rebuilt as image + invisible text and other pages are copied as they are, in the original order.

### Pricing

Pay per event:

| Event | Free plan | Bronze | Silver | Gold and above |
|---|---|---|---|---|
| `ocr-page`: a page read by OCR that has text | $0.002 | $0.0018 | $0.0015 | $0.0012 |
| `text-page`: a PDF page read from its own text layer | $0.0003 | $0.0003 | $0.0003 | $0.0003 |

Plus Apify's tiny start fee of $0.00005 per GB of memory per run (the default 2 GB counts as two). Platform usage is included.

Examples on the Free plan: a 10-page scanned PDF costs $0.02. A 30-page PDF where 3 pages are scans costs 3 × $0.002 + 27 × $0.0003 = $0.0141. 1,000 receipts photographed with a phone cost $2.

Blank pages, pages OCR cannot process and files that cannot be downloaded are reported and **not charged**. If you give the run a spending limit, the Actor reads only as many pages as the limit covers and skips the remaining files.

### Limits

- OCR quality depends on the scan: clear printed text at 200-300 DPI works best. **Handwriting is not supported.** Low-contrast photos, decorative fonts and very small text give lower confidence (see `meanConfidence` and the per-word confidence).
- Phone photos of receipts: in a test, a receipt photographed with a phone was read at mean confidence 76, with the shop name, address and date right and a few errors in the item lines. Check the items before you rely on them.
- Layout is returned as text lines and paragraphs; tables come out as text lines, not Markdown tables.
- Up to 50 MB per file, 500 pages per file and about 100 megapixels per image (larger images are reported as an error). For very long documents the row keeps the full text and the per-page methods; the per-page texts are dropped (`pageTextsOmitted`) so the row fits the 9 MB dataset limit. OCR takes roughly a few seconds per page with the default 2 GB of memory; give the run more memory (4 GB = one full CPU core, 8 GB = two) to process pages in parallel.
- Password-protected PDFs are not supported.
- For vertical Japanese, Chinese or Korean text, pick the vertical variant (`jpn_vert`, `chi_sim_vert`, `chi_tra_vert`, `kor_vert`): the page is then read as top-to-bottom columns from right to left, and the orientation check is skipped. A page that mixes vertical and horizontal text reads best in two runs, one with each variant. On a clean three-column sample of printed vertical Japanese, `jpn_vert` read every character (mean confidence 90). For Japanese and Chinese, the spaces Tesseract puts between words are removed from the text (word boxes are unchanged).
- Base64 files travel inside the run input, which Apify limits to about 9 MB; send bigger files as links.
- The searchable PDF is built from grayscale page images, so colors are not kept. Keep the original if you need it.
- A PDF page that has only a short text layer (under 200 characters) on top of a picture, such as a scan with a watermark, is OCR'd rather than trusted.

### Data and privacy

OCR happens in the Actor's own container with Tesseract; no file, page image or text leaves your run for an outside OCR service. Nothing is fetched besides the links you list, and the text, word boxes and searchable PDFs are written only to your run's storage. Please OCR only files you are allowed to process.

### FAQ

**Why is a page empty?** OCR found no text on it (a blank or photo-only page). It is listed in `pagesBlank` and not charged.

**What does `meanConfidence` mean?** The average confidence Tesseract gives the words on the OCR pages (0-100). Values above 85 usually mean clean text; below 60, check the scan.

**How do I OCR a list of image links in a Google Sheet?** Share the sheet as "Anyone with the link", paste its link into **Spreadsheet URL**, and run. Each row's other columns come back in `sourceRow`; export the dataset as CSV or Excel to get a sheet back.

**How do I call it from code, an agent or a no-code tool?** Start a run through the Apify API with `{"urls": [...], "outputFormat": "chunks"}` (or `base64Files`, `datasetId`, `fileUrl`) and read the dataset; `run-sync-get-dataset-items` does both in one request for small batches. LangChain and LlamaIndex have Apify loaders that take the dataset rows directly. Make, n8n and Zapier have Apify modules, and AI agents can find and run the Actor through the Apify MCP server.

**How do I run OCR automatically after another Actor (a scraper, an image downloader)?** Open that Actor's **Integrations** tab, choose **Add integration** and pick this Actor. In the integration's Actor input, set **Apify dataset with file links** (`datasetId`) to `{{resource.defaultDatasetId}}` and **URL column** (`urlField`) to the field with the links. If the form does not let you type the variable into the dataset field, enter the input as JSON: `{"datasetId": "{{resource.defaultDatasetId}}", "urlField": "imageUrl"}` (with your field name). Each time the other Actor's run succeeds, this Actor reads that run's dataset. We tested this setup as an integration created through the Apify API, after an image downloader Actor (`"urlField": "sourceUrl"`): the image of the previous run was read. The dataset has to be given in that field: this Actor runs with limited permissions and cannot read the dataset from the integration's payload alone, so without it the run stops with a hint (and does not read the form's example link).

**Why did I get a `wordsUrl` instead of words in the row?** A dataset row is limited to about 9 MB. When a long document with word boxes would exceed that, the words are saved as a JSON record in the run's key-value store and the row links to it.

**Which OCR engine is used?** [Tesseract](https://github.com/tesseract-ocr/tesseract) (Apache-2.0) with the language data packaged by Debian (the fast LSTM models).

**Can it read handwriting?** No. Tesseract is trained on printed text.

### Related Actors by the same author

| Actor | What it does |
|---|---|
| [PDF to Markdown](https://apify.com/tamatama/doc-to-markdown) | Digital documents to Markdown and RAG chunks with headings and tables. Use it for PDFs that have text; use this Actor for scans. |
| [Website Change Monitor](https://apify.com/tamatama/website-change-monitor) | See what changed on a list of web pages since the last run. |
| [ATS Jobs](https://apify.com/tamatama/ats-jobs) | Every open job of chosen companies from their Greenhouse, Lever, Ashby and other job boards. |
| [RemoteOK & Jobicy Remote Jobs API](https://apify.com/tamatama/remote-jobs) | Remote jobs from two official APIs, with salary and source credit. |

### For AI Agents

An agent that meets a scan, a photo of a receipt or a PDF without a text layer can hand it to this Actor and get text back. There is no login and no API key of a third-party OCR service; the run is paid per page through Apify (pay per event) and uses limited permissions.

**Connect through the Apify MCP server** and expose just this Actor:

```json
{
  "mcpServers": {
    "pdf-ocr": {
      "url": "https://mcp.apify.com?tools=tamatama/image-pdf-ocr"
    }
  }
}
```

Sign in with OAuth when the client asks, or add the header `Authorization: Bearer <APIFY_TOKEN>`. The Actor then shows up as its own tool, `tamatama--image-pdf-ocr`, and the server adds `get-dataset-items` for paging through long results. Input an agent usually sends:

```json
{ "urls": [{ "url": "https://example.com/scan.pdf" }], "languages": ["eng", "deu"], "outputFormat": "text" }
```

When the agent holds the file itself (an upload, an e-mail attachment), it can send it as base64 instead of a link:

```json
{ "base64Files": [{ "name": "receipt.jpg", "data": "/9j/4AAQSkZJRgABAQ..." }], "languages": ["eng"] }
```

Tips for agents: in the default text format each file row has `meanConfidence` (check it before trusting the text) and `pagesFailed` / `error` (read them when a row looks empty). Chunk rows (`outputFormat: "chunks"`) carry only the text and page range; page counts and `pagesFailed` per file are then in the `SUMMARY` record of the run's key-value store (`meanConfidence` is only in text rows). Set `searchablePdf: true` when the user wants a file back; the row then has a `searchablePdfUrl`.

**OpenAPI** for tool importers: `https://api.apify.com/v2/acts/tamatama~image-pdf-ocr/builds/default/openapi.json`. **One-request REST call**: `POST https://api.apify.com/v2/acts/tamatama~image-pdf-ocr/run-sync-get-dataset-items` with the JSON input.

# Actor input Schema

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

Links to images (PNG, JPEG, TIFF incl. multi-page, WebP, GIF, BMP) or PDF files (scanned or mixed). The type is detected from the content, so links without an extension work. Up to 50 MB per file. You can also link a text file that lists URLs (up to 1,000), e.g. https://example.com/scans.txt. For a spreadsheet or a dataset of links, use the bulk fields below.

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

Languages of the text, up to 3 (more languages make OCR slower). 100+ languages (123 language models, counting vertical Japanese, Chinese and Korean and historic variants). English is used if empty.

## `outputFormat` (type: `string`):

Text: one dataset row per file with the full text and a list of pages (method, confidence, text). RAG chunks: one row per chunk with page numbers, ready for a vector database.

## `searchablePdf` (type: `boolean`):

Save one PDF per file with an invisible text layer over the page images (select and search the text in any PDF viewer). The link is in searchablePdfUrl. No extra charge.

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

Add every recognized word with its confidence (0-100) and position (left, top, width, height in pixels of the original image; for PDF pages, pixels at 300 DPI; measured after the page orientation is fixed) to each page. Makes the output much larger. Text format only.

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

OCR the files linked in an Apify dataset, e.g. the output of a scraper run with image or PDF URLs. One file per item, or every link of a list field (see URL column); the item's own fields come back in sourceRow so you can join the results. Up to 5,000 items and 5,000 files. In an integration that starts this Actor after another Actor's run, set it to {{resource.defaultDatasetId}}.

## `fileUrl` (type: `string`):

A public link to a CSV, Excel (.xlsx, first sheet), JSON or JSON Lines file with one file link per row, up to 5,000 rows. A Google Sheets link works when the sheet is shared as "Anyone with the link" (the first tab, or the tab in the link).

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

The column (or dataset field) that holds the image or PDF link, e.g. imageUrl or receipt.url. A field that holds a list of links, e.g. images (all photos of a carousel post or a product) or childPosts.displayUrl, gives one result per link with urlIndex (its position in the list, 1 = first), up to 50 per row. Leave empty to use the column that holds the most http(s) links; list fields are guessed only when no column holds single links, so name a list field here.

## `base64Files` (type: `array`):

Send files inside the input instead of links, e.g. from an AI agent or a script: \[{"name": "receipt.jpg", "data": "<base64>"}]. A data: URL works as data too. The whole input must stay under about 9 MB (about 6 MB of files); use links for bigger files.

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

Detect pages that are upside down or sideways and turn them before OCR.

## `ocrAllPages` (type: `boolean`):

By default, PDF pages that already have a text layer are read directly (cheaper and exact). Turn on to OCR every page anyway, e.g. when the existing text layer is garbage.

## `maxPagesPerDocument` (type: `integer`):

Process only the first N pages of each PDF or multi-page TIFF. 0 = all (up to 500).

## `chunkSize` (type: `integer`):

Maximum characters per chunk (RAG chunks only). Chunks break at paragraphs first, then lines and sentences.

## `chunkOverlap` (type: `integer`):

Characters repeated from the end of the previous chunk (RAG chunks only). At most half of the chunk size.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif"
    }
  ],
  "languages": [
    "eng"
  ],
  "outputFormat": "text",
  "searchablePdf": false,
  "includeWords": false,
  "autoRotate": true,
  "ocrAllPages": false,
  "maxPagesPerDocument": 0,
  "chunkSize": 2000,
  "chunkOverlap": 200
}
```

# Actor output Schema

## `documents` (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": [
        {
            "url": "https://raw.githubusercontent.com/tesseract-ocr/test/main/testing/phototest.tif"
        }
    ],
    "languages": [
        "eng"
    ]
};

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tamatama/image-pdf-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/IYJQkEivcRKxq0idn/builds/q7aULmBRrg6g9Smid/openapi.json
