# Document Text Extractor (`lergassy/document-text-extractor`) Actor

Extract text, Markdown, tables and metadata from PDF, Word, Excel, PowerPoint, EPUB, HTML and CSV files. Reads scanned pages with OCR in 19 languages and splits documents into RAG-ready chunks. Export data, run via API, schedule runs, or integrate with other tools or AI workflows.

- **URL**: https://apify.com/lergassy/document-text-extractor.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Developer tools, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.45 / 1,000 document processeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Turn any document into clean text, Markdown, tables and metadata. **Document Text Extractor** reads PDF, Word, Excel, PowerPoint, EPUB, HTML, CSV and plain text files, restores the heading structure, pulls out tables, reads scanned pages with OCR, and can split everything into retrieval chunks that keep their section context. No login, no API key and no official API needed.

### What is Document Text Extractor?

Document Text Extractor is a document parsing API that converts files into **LLM-ready Markdown** and plain text. Give it a list of document URLs, upload a file, or pass base64 data from your own code, and every document comes back as one row with the full text, the Markdown, a page-by-page breakdown, detected tables and the file's own metadata.

It exists because most document extraction tools stop at PDF and hand back a wall of unformatted text. This Actor keeps **headings, lists and tables**, so a language model can tell a section title from a sentence, and a retrieval system can cite the section a passage came from.

| What you give it | What you get back |
| --- | --- |
| A PDF, Word, Excel, PowerPoint, EPUB, HTML or CSV file | Markdown, plain text, tables, chunks, metadata |
| A scanned PDF with no text layer | OCR text in 19 languages |
| A folder of mixed formats | One consistent row per document, same fields for every format |

#### Which file formats are supported?

| Format | Extensions | What is extracted |
| --- | --- | --- |
| PDF | `.pdf` | Text per page, headings by font size, tables, metadata, OCR for scans |
| Word | `.docx` | Real heading levels, lists, tables, core properties |
| Excel | `.xlsx`, `.xlsm` | Every sheet as a Markdown table, sheet names |
| PowerPoint | `.pptx` | One section per slide, slide titles, tables, speaker notes |
| EPUB | `.epub` | One section per chapter, book title and author |
| HTML | `.html`, `.htm` | Article Markdown, page title, meta description |
| CSV | `.csv`, `.tsv` | Markdown table, delimiter detected automatically |
| Text | `.txt`, `.md`, `.json` | Content as-is |

Password-protected PDFs are supported: pass the password in the input.

### What data can Document Text Extractor extract?

Every row in the dataset describes one document.

| Field | Type | Example |
| --- | --- | --- |
| `source` | string | `https://example.com/report.pdf` |
| `sourceType` | string | `url`, `upload` or `base64` |
| `fileName` | string | `report.pdf` |
| `format` | string | `pdf` |
| `fileSizeBytes` | integer | `3471` |
| `pageCount` | integer | `2` |
| `pagesProcessed` | integer | `2` |
| `title` | string | `Annual Operations Report 2026` |
| `author` | string | `Malina Data` |
| `subject` | string | `Sample document` |
| `creator` | string | `Microsoft Word` |
| `producer` | string | `ReportLab PDF Library` |
| `documentCreatedAt` | string | `D:20260904T120000Z` |
| `documentModifiedAt` | string | `2026-09-04T12:00:00` |
| `markdown` | string | `# Annual Operations Report 2026\n\n## Revenue…` |
| `text` | string | `Annual Operations Report 2026 Revenue grew…` |
| `wordCount` | integer | `198` |
| `charCount` | integer | `1284` |
| `pages` | array | `[{"number": 1, "text": "…", "markdown": "…", "ocr": false}]` |
| `tables` | array | `[{"page": 1, "markdown": "\| Region \| Q1 \|…", "rows": [["Region","Q1"]]}]` |
| `tableCount` | integer | `1` |
| `chunks` | array | `[{"index": 0, "heading": "Revenue", "headingPath": ["Report","Revenue"], "text": "…", "charCount": 812}]` |
| `chunkCount` | integer | `4` |
| `sheetNames` | array | `["Sales", "Notes"]` |
| `ocrPageCount` | integer | `0` |
| `status` | string | `ok` or `error` |
| `errorCode` | string | `null`, or `http-error`, `no-text-content`, `too-large`, … |
| `errorMessage` | string | Plain-English reason a file could not be read |
| `warnings` | array | `["3 page(s) have no text layer and look scanned."]` |
| `extractedAt` | string | `2026-09-04T16:20:11+00:00` |

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

The Actor uses **pay-per-event** pricing, so the bill follows the work done, not the minutes the container was alive.

| Event | Price | When it is charged |
| --- | --- | --- |
| Document processed | $0.0035 | Once per document that produced text |
| Page parsed | $0.00015 | Per page, sheet, slide or chapter that was read |
| OCR page | $0.010 | Only when OCR is on and the page has no text layer |

**Nothing is charged for a document that failed.** A dead link, a file above the size limit, a corrupt PDF or a scan with no readable text comes back as an `error` row at no cost. That includes the case where a scanned PDF is submitted with OCR switched off: you get a row telling you to switch OCR on, and you pay nothing for it.

Worked examples:

| Job | Cost |
| --- | --- |
| 100 born-digital PDFs, 10 pages each | $0.50 |
| 1,000 Word contracts, 3 pages each | $3.95 |
| 500 web pages to Markdown | $1.83 |
| 50 scanned PDFs, 5 pages each, OCR on | $2.71 |

The Apify Free plan comes with $5 of monthly usage, which is about **1,000 ten-page PDFs** before you pay anything. Apify plans above the free tier get automatic discounts of 10% to 30% on every event above.

#### How the price compares

Comparable document Actors in Apify Store charge between $2.79 and $20 per 1,000 documents, and the two that offer OCR charge $12 and $15 per 1,000 scanned pages. This Actor is built to sit below the middle of that range while doing more per document:

| For 1,000 documents | This Actor | Typical PDF-only Actor | Cheapest PDF-only Actor |
| --- | --- | --- | --- |
| 3 pages each | $3.95 | $5.00 | $3.00 |
| 10 pages each | $5.00 | $5.00 | $3.00 |
| 1,000 scanned pages, OCR | $10.00 | $15.00 | OCR not offered |
| Formats handled | 8 | 1 (PDF) | 1 (PDF) |
| Markdown, tables, RAG chunks | all three | some | text only |

The split between a document fee and a per-page fee is deliberate: a one-page invoice should not cost the same as a 300-page manual. If your documents are unusually long, the per-page part is what you are paying, and `pageRange` keeps it down when you only need the first pages.

There are no proxy costs: the Actor fetches files over plain HTTPS and parses them in memory, so almost none of the price is infrastructure.

### How to extract text from a PDF or Word file

1. Click **Try for free** and sign in to Apify.
2. Paste one or more document links into **Document URLs**, or use **Upload a file** to send a file from your computer.
3. Leave **Markdown output** on if the text is going to an LLM; switch on **Split into RAG chunks** if it is going into a vector database.
4. Press **Start** and wait a few seconds.
5. Open the **Output** tab, or export the dataset as JSON, CSV or Excel.

For scanned documents, switch on **OCR scanned pages** and pick the language of the scan.

### ⬇️ Input

![Document Text Extractor input form: PDF, Word and Excel URLs, Markdown output, RAG chunks and OCR options](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/document-text-extractor-input-form.png)

Only one thing is required: at least one document, given as a URL, an upload or base64 data.

```json
{
  "urls": [
    "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/sample-report.pdf",
    "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/sample-contract.docx"
  ],
  "includeMarkdown": true,
  "includeFullText": true,
  "extractTables": true,
  "chunkForRag": false
}
```

#### Reading documents from URLs

Put direct file links in `urls`. The link has to point at the file itself, not at a viewer page: a Google Drive or Dropbox preview page returns HTML, not the document. Use the direct-download form of those links.

#### Uploading a file from your computer

Use the **Upload a file** field to send a single document without hosting it anywhere. This is the fastest way to test the Actor on a real file.

#### Passing base64 data from code or an AI agent

When your document only exists in memory, send it in `base64Files`. Each entry is either a plain base64 string or an object with a file name:

```json
{
  "base64Files": [
    { "fileName": "invoice.pdf", "data": "JVBERi0xLjQKJeLjz9M…" },
    "data:application/pdf;base64,JVBERi0xLjQK…"
  ]
}
```

#### Reading only some pages

`pageRange` accepts `1-5`, `8` or `12-` (page 12 to the end). It applies to PDFs and keeps the bill down when you only need the first pages of long documents.

#### Splitting documents into RAG chunks

Switch on `chunkForRag` to get retrieval-ready chunks. Chunks break on headings and paragraphs rather than on a raw character count, tables are split by rows so every part keeps its header row, and each chunk carries the `headingPath` it belongs to:

```json
{
  "index": 2,
  "heading": "Revenue by region",
  "headingPath": ["Annual Operations Report 2026", "Executive summary", "Revenue by region"],
  "text": "Revenue grew across all three regions during the year…",
  "charCount": 812
}
```

That path is what lets a retrieval answer say *where* in the document it came from, instead of returning a paragraph with no context.

#### Reading scanned documents with OCR

A page with no text layer is detected automatically. With `ocrScannedPages` off, the Actor tells you the pages are scanned and charges nothing. With it on, those pages are read by the OCR engine in the language given in `ocrLanguage`: English, German, French, Spanish, Portuguese, Italian, Dutch, Polish, Russian, Ukrainian, Turkish, Indonesian, Vietnamese, Arabic, Hindi, Chinese (simplified and traditional), Japanese or Korean. `ocrMaxPagesPerDocument` caps how many scanned pages are read per file so a 400-page scan cannot surprise you.

### ⬆️ Output

![Document Text Extractor output table: one row per document with format, title, pages, words, tables, chunks and Markdown](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/document-text-extractor-output-table.png)

One row per document. Fields that were switched off in the input are simply absent.

```json
{
  "source": "https://…/sample-report.pdf",
  "sourceType": "url",
  "fileName": "sample-report.pdf",
  "format": "pdf",
  "fileSizeBytes": 3471,
  "pageCount": 2,
  "pagesProcessed": 2,
  "title": "Annual Operations Report 2026",
  "author": "Malina Data",
  "markdown": "# Annual Operations Report 2026\n\n# Executive summary\n\nThis sample document…\n\n## Revenue by region\n\n| Region | Q1 | Q2 | Q3 | Q4 |\n| --- | --- | --- | --- | --- |\n| Europe | 120 | 140 | 155 | 162 |",
  "text": "Annual Operations Report 2026 Executive summary…",
  "wordCount": 198,
  "charCount": 1284,
  "tableCount": 1,
  "tables": [
    {
      "page": 1,
      "markdown": "| Region | Q1 | Q2 | Q3 | Q4 |\n| --- | --- | --- | --- | --- |\n| Europe | 120 | 140 | 155 | 162 |",
      "rows": [["Region", "Q1", "Q2", "Q3", "Q4"], ["Europe", "120", "140", "155", "162"]]
    }
  ],
  "ocrPageCount": 0,
  "status": "ok",
  "errorCode": null,
  "errorMessage": null,
  "warnings": [],
  "extractedAt": "2026-09-04T16:20:11+00:00"
}
```

#### Markdown that keeps the document's shape

In Word, PowerPoint and EPUB files the heading levels are already in the file, so they are used directly. PDFs carry no heading information at all, so headings are inferred from font size relative to the body text of the document, with page furniture, rotated stamps and glued-together tokens filtered out.

The same pass fixes a problem that affects academic and LaTeX-produced PDFs: when a file sets word spacing very narrow, the usual extraction returns `Attentionisallyouneed` instead of readable words. The Actor measures how often that happens on each page and re-reads the page with tighter word spacing when it does, so the text arrives as words rather than as one long string.

#### Tables

Every detected table is returned twice: as `rows` for code that wants arrays, and as a Markdown table for text that goes to an LLM. Columns that are empty in every row are dropped. Table detection in PDFs depends on how the table was drawn, so treat PDF tables as very good but not perfect; tables in Word, Excel, PowerPoint and CSV files are exact.

#### Error rows

A document that could not be read still produces a row, so a batch never silently loses a file:

| `errorCode` | Meaning |
| --- | --- |
| `http-error` | The server refused the download or the file is gone |
| `network-error` | The host could not be reached |
| `timeout` | The download took longer than the timeout |
| `too-large` | The file is above `maxFileSizeMb` |
| `unsupported-format` | The file is not one of the supported formats |
| `password-required` | The PDF needs a password |
| `corrupt-file` | The file is damaged or is not what its extension claims |
| `no-text-content` | Nothing could be read, usually a scan with OCR switched off |
| `invalid-base64` | The base64 entry could not be decoded |

### Use cases for document data

#### Feeding a RAG pipeline or a knowledge base

Convert a document library into Markdown with chunks that keep their heading path, then embed the chunks. Because the heading path travels with the chunk, retrieved passages can be cited by section instead of by page number.

#### Contract and report review

Pull the text out of hundreds of PDFs and Word files and run a language model over the result to find dates, parties, amounts or clauses. Metadata fields tell you who produced each file and when.

#### Migrating a document archive

Move a folder of mixed PDF, Word and Excel files into a wiki, a CMS or a static site. Every format comes back with the same field names, so one importer handles all of them.

#### Reading scanned paperwork

Invoices, permits and old records that arrive as scans become searchable text with the OCR option, in nineteen languages.

#### Spreadsheets and data files as text

Excel and CSV files come back as Markdown tables, which is the form language models read most reliably.

### Integrations

Run the Actor from the Apify Console, or connect it to the tools you already use.

- **API**: start a run with `POST https://api.apify.com/v2/acts/lergassy~document-text-extractor/runs` and read the dataset when it finishes.
- **Python**: `ApifyClient(token).actor('lergassy/document-text-extractor').call(run_input={'urls': [...]})`
- **JavaScript**: `await client.actor('lergassy/document-text-extractor').call({ urls: [...] })`
- **n8n**: use the Apify node, pick this Actor, and set a **max total charge** so a run can never exceed a budget you chose.
- **Make and Zapier**: run the Actor and map the dataset straight into Sheets, Airtable or Notion.
- **Google Sheets**: export the dataset as CSV or push it with the Sheets integration.
- **MCP**: the Actor is available through the Apify MCP server, so Claude, Cursor and other MCP clients can call it as a tool.
- **Webhooks**: trigger a webhook when a run succeeds and pass the dataset to your own service.

### 🤖 For AI agents and LLM apps

Call the Actor with a single field and you already get useful output:

```json
{ "urls": ["https://example.com/report.pdf"] }
```

- One dataset row per document; `status` is `ok` or `error`, so a failed file is visible without parsing logs.
- `markdown` is the field to feed a model. `chunks` (with `chunkForRag: true`) is the field to embed.
- Every chunk carries `headingPath`, so an answer can name the section it used.
- Failed documents are never charged, which keeps agent retries cheap.
- Documents can be passed as base64 in `base64Files`, so an agent does not need to host a file to have it read.

### Troubleshooting

**The run returned `http-error` for a link that works in my browser.** The host is refusing requests from data-centre IP addresses, or the link points at a viewer page rather than the file. Download the file and use **Upload a file**, or host it somewhere that allows direct downloads.

**A PDF came back with no text.** It is a scan. Switch on **OCR scanned pages** and choose the language.

**The OCR text has mistakes.** Check the language setting first. Low-resolution scans, handwriting and stamps are the usual limits of OCR.

**My spreadsheet was cut off.** Sheets are read up to 5,000 rows each, and a warning says so in `warnings`.

**Headings are wrong in one PDF.** Some PDFs set every line at the same size, and then no heading structure exists to recover. The plain `text` field is unaffected.

### ❓ FAQ

#### Is it legal to extract text from documents with this Actor?

The Actor only reads files you point it at. Whether you may use a given document depends on who owns it and how you obtained it, so use it on your own files, on files you are licensed to process, and on publicly available documents. It is not a substitute for legal advice.

#### Do I need an API key or a login?

No. There is no account, key or cookie to configure. You need an Apify account to run any Actor, and nothing else.

#### How much does it cost to extract text from 1,000 PDFs?

For 1,000 PDFs of ten pages each, $3.50 for the documents plus $1.50 for the pages, so $5.00 in total. Scanned pages cost $0.01 each on top, and only when OCR is on.

#### Can I use it with the Apify API?

Yes. Start a run with the API, then read the dataset. The Actor is a normal Apify Actor with a standard input schema.

#### Can I use it through an MCP server?

Yes. It is exposed through the Apify MCP server, so an MCP client such as Claude or Cursor can call it directly as a tool.

#### Can I integrate it with other apps?

Yes: n8n, Make, Zapier, Google Sheets, Slack, Airtable and anything that can call an HTTP API or receive a webhook.

#### Does one row mean one document or one page?

One row is one document. Pages live inside that row in the `pages` array when **Per-page output** is on, and chunks live in `chunks`.

#### What is the largest file it can read?

The default limit is 50 MB per file, adjustable up to 200 MB. Files above the limit are reported as `too-large` and are not charged.

#### Can it read password-protected PDFs?

Yes, if you supply the password in the **PDF password** field.

#### Does it work with Google Docs links?

Not with a share link, because that returns a web page. Use the *Download as PDF or Word* form of the link, or upload the exported file.

### Your feedback

Found a document the Actor reads badly, or a format you need? Open an issue on the **Issues** tab or leave a review. Issues are answered quickly, and format requests are the main way this Actor grows.

### You might also like

| Actor | What it does |
| --- | --- |
| [Email & Phone Verifier](https://apify.com/lergassy/email-phone-verifier) | Validate e-mail addresses and phone numbers, find contacts on a website |
| [US Business Leads](https://apify.com/lergassy/us-business-filings) | New business registrations from US state and city registries |
| [Google Flights Scraper](https://apify.com/lergassy/google-flights-scraper) | Flight prices, airlines, layovers and booking links |
| [Agoda Reviews Scraper](https://apify.com/lergassy/agoda-reviews-scraper) | Hotel reviews and ratings from Agoda and Booking.com |

# Actor input Schema

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

Direct links to the files you want to read. PDF, DOCX, XLSX, PPTX, EPUB, HTML, CSV and TXT are supported. The link must point at the file itself, not at a viewer page.

## `documentFile` (type: `string`):

Upload one document from your computer instead of giving a URL.

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

Base64-encoded documents for API and agent calls. Each entry is a plain base64 string (a data-URI prefix is allowed) or an object <code>{"fileName": "report.pdf", "data": "…"}</code>.

## `includeMarkdown` (type: `boolean`):

Return clean Markdown with headings, lists and tables. This is the format to feed an LLM or a vector database.

## `includeFullText` (type: `boolean`):

Return the whole document as plain text.

## `extractTables` (type: `boolean`):

Detect tables and return each one as both a Markdown table and a row array.

## `chunkForRag` (type: `boolean`):

Split the document into retrieval chunks. Each chunk keeps the heading path it belongs to, so a search hit can be traced back to its section.

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

Target size of one chunk. Chunks break on headings and paragraphs, so real sizes vary a little.

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

How much text from the previous chunk to repeat at the start of the next one.

## `includePages` (type: `boolean`):

Add a page-by-page breakdown with the text and Markdown of every page.

## `pageRange` (type: `string`):

Read only these pages of a PDF, for example <code>1-5</code>, <code>8</code> or <code>12-</code> (page 12 to the end). Leave empty to read everything.

## `password` (type: `string`):

Password for protected PDF files.

## `ocrScannedPages` (type: `boolean`):

Read pages that have no text layer by running OCR on them. Charged per OCR page, so it stays off until you need it.

## `ocrLanguage` (type: `string`):

Language of the scanned pages, used by the OCR engine.

## `ocrMaxPagesPerDocument` (type: `integer`):

Safety cap on how many scanned pages are read per document, so a long scan cannot run up an unexpected bill.

## `maxConcurrency` (type: `integer`):

How many documents to process at the same time.

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

Files larger than this are skipped with an error row instead of being downloaded.

## `timeoutPerDocumentSecs` (type: `integer`):

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

## Actor input object example

```json
{
  "urls": [
    "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/sample-report.pdf",
    "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/sample-contract.docx"
  ],
  "includeMarkdown": true,
  "includeFullText": true,
  "extractTables": true,
  "chunkForRag": false,
  "chunkSize": 1200,
  "chunkOverlap": 120,
  "includePages": false,
  "ocrScannedPages": false,
  "ocrLanguage": "eng",
  "ocrMaxPagesPerDocument": 20,
  "maxConcurrency": 5,
  "maxFileSizeMb": 50,
  "timeoutPerDocumentSecs": 120
}
```

# Actor output Schema

## `documents` (type: `string`):

Dataset with one row per document, including Markdown, text, tables, chunks and file metadata.

## `documentsInConsole` (type: `string`):

Browse the extracted documents in the Apify Console.

# 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/lergassy/apify-actor-assets/main/document-text-extractor/sample-report.pdf",
        "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/sample-contract.docx"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/document-text-extractor").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/lergassy/apify-actor-assets/main/document-text-extractor/sample-report.pdf",
        "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/sample-contract.docx",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("lergassy/document-text-extractor").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/lergassy/apify-actor-assets/main/document-text-extractor/sample-report.pdf",
    "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/document-text-extractor/sample-contract.docx"
  ]
}' |
apify call lergassy/document-text-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/document-text-extractor"
        }
    }
}

```

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/2dNFljSs8OwqFZJgq/builds/ON3HKAgCTzkktnS2H/openapi.json
