# PDF & Document to Markdown - PDF, DOCX & HTML for LLMs (`entranced_gelato/ai-document-reader`) Actor

Turn any PDF, DOCX, TXT, or HTML document into clean, LLM-ready text + Markdown with metadata (title, pages, word count) and an optional AI summary. The document counterpart to a web reader — built for RAG ingestion, document Q\&A, and AI agents (LangChain, LlamaIndex). Fast, structured, single-call.

- **URL**: https://apify.com/entranced\_gelato/ai-document-reader.md
- **Developed by:** [AIDevs](https://apify.com/entranced_gelato) (community)
- **Categories:** AI, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 document reads

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/platform/actors/running/actors-in-store#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

## AI Document Reader

[![PDF & Document to Markdown](https://apify.com/actor-badge?actor=entranced_gelato/ai-document-reader)](https://apify.com/entranced_gelato/ai-document-reader)

**Turn any PDF, DOCX, TXT, or HTML document into clean, LLM-ready text + Markdown — with metadata and an optional AI summary, in a single call.**

AI Document Reader is the document counterpart to a web-page reader. Point it at a document URL and it auto-detects the format, extracts the real content (not the binary noise), and returns structured text, Markdown, and metadata that you can feed straight into an LLM, a vector database, or a RAG pipeline.

***

### Why AI Document Reader

Most "read a document" steps in AI pipelines are a mess of format-specific parsers, broken encodings, and inconsistent output. This Actor gives you **one endpoint for the most common document formats** and a **single, predictable output shape** regardless of whether the source was a PDF, a Word file, a text file, or an HTML page.

- **One call, one record.** Each run returns exactly one structured `document` record.
- **LLM-ready by default.** You get both clean plain text and Markdown — no post-processing required.
- **Bring-your-own-key summaries.** Optional AI TL;DR + key points using your own OpenAI key, so model cost stays with you.

### When to use it

- Ingesting PDFs/DOCX into a **RAG pipeline** or vector database.
- Building a **document Q\&A** bot or research agent that needs clean text from a link.
- **No-code automations** (Make, Zapier, n8n) that receive a document URL and need its contents.
- Quickly turning a report, whitepaper, or contract into Markdown for an LLM prompt.

### When NOT to use it

- **Deep-crawling an entire website** — use a site crawler instead; this reads a single document/URL.
- **Scanned/image-only PDFs** — there is no OCR step, so image-only PDFs return little or no text.
- **Password-protected or login-gated files** — the Actor fetches the URL as an anonymous client.

### Built for

AI engineers, data teams, RAG/LLM developers, and automation builders who need a reliable "document → text" primitive.

***

### How it works

1. **Fetch.** The Actor downloads the document at `url` as raw bytes (with redirects followed).
2. **Detect.** It identifies the format from the content-type header, the URL extension, and the file's magic bytes (e.g. `%PDF`, `PK` for DOCX zips).
3. **Extract.**
   - **PDF** → parsed with `pdf-parse` (text + page count + embedded title/author).
   - **DOCX** → converted to HTML with `mammoth`, then to clean Markdown.
   - **HTML** → main content isolated (nav/header/footer/scripts removed) and converted to Markdown.
   - **TXT / Markdown** → returned as-is.
4. **(Optional) Summarize.** If `summarize` is on and an OpenAI key is supplied, it generates a TL;DR + key points.
5. **Output.** One record is pushed to the dataset; usage is billed per event.

### How to call it

#### From the Console

Open the Actor, paste a document URL into **Document URL**, optionally enable **Generate AI summary** with your OpenAI key, and click **Start**. Read the result in the **Output** tab.

#### From the API

Run it via the Apify API and read the dataset. Conceptually:

```
POST https://api.apify.com/v2/acts/entranced_gelato~ai-document-reader/runs?token=<APIFY_TOKEN>
{
  "url": "https://example.com/report.pdf",
  "summarize": true,
  "openaiApiKey": "sk-...",
  "model": "gpt-4o-mini"
}
```

The Actor is also callable over **MCP**, so AI agents can invoke it as a tool.

***

### Input reference

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `url` | string | **Yes** | — | Direct URL to the document (PDF, DOCX, TXT, or HTML). |
| `summarize` | boolean | No | `false` | Generate an AI TL;DR + key points (requires `openaiApiKey`). |
| `openaiApiKey` | string (secret) | No | — | Your OpenAI key; used only for the summary. |
| `model` | string | No | `gpt-4o-mini` | OpenAI model for the summary. |
| `maxChars` | integer | No | `0` | Cap the length of returned text/markdown (`0` = no limit). |

### Output reference

One dataset record per run:

| Field | Description |
|-------|-------------|
| `url` | The document URL that was read. |
| `fileType` | Detected format: `pdf`, `docx`, `html`, or `text`. |
| `title` | Document title (from PDF info or first heading), if available. |
| `author` | Author metadata, if present. |
| `pageCount` | Number of pages (PDF only). |
| `wordCount` | Word count of the extracted text. |
| `content` | Clean plain text. |
| `markdown` | LLM-ready Markdown version. |
| `summary` | AI TL;DR (only when summarization is enabled). |
| `keyPoints` | Array of key points (only when summarization is enabled). |
| `fetchedAt` | ISO timestamp of the run. |

***

### Pricing

**Pay per event** — you only pay for what you run:

- **Document read** — charged once per successful run (one document).
- **AI summary** — a small premium that applies **only when you enable summarization**. You supply your own OpenAI key, so the model's cost is billed by OpenAI separately and is never added to the Actor price.

Apify platform/compute usage is included in the per-event price. See the **Pricing** tab for current rates.

### Integrations

- **LangChain / LlamaIndex** — feed `content`/`markdown` into document loaders and vector stores.
- **Make / Zapier / n8n** — trigger on a document URL, store the structured output.
- **MCP** — expose the Actor as a tool for autonomous agents.

### 🔌 Integrations & code examples

#### Call it from the API

```bash
curl "https://api.apify.com/v2/acts/entranced_gelato~ai-document-reader/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/report.pdf" }'
```

#### Python (Apify client)

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("entranced_gelato/ai-document-reader").call(
    run_input={"url": "https://example.com/whitepaper.pdf"}
)
doc = next(client.dataset(run["defaultDatasetId"]).iterate_items())
print(doc["fileType"], doc["pageCount"], "pages,", doc["wordCount"], "words")
print(doc["markdown"][:500])
```

#### LangChain (ingest a document into a RAG chain)

```python
from langchain_community.utilities import ApifyWrapper
from langchain_core.documents import Document

apify = ApifyWrapper()
loader = apify.call_actor(
    actor_id="entranced_gelato/ai-document-reader",
    run_input={"url": "https://example.com/report.pdf"},
    dataset_mapping_function=lambda i: Document(
        page_content=i["markdown"] or i["content"] or "",
        metadata={"source": i["url"], "fileType": i.get("fileType")},
    ),
)
docs = loader.load()
```

#### MCP — add it to Claude, Cursor, or any agent

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server", "--actors", "entranced_gelato/ai-document-reader"],
      "env": { "APIFY_TOKEN": "<APIFY_TOKEN>" }
    }
  }
}
```

Also works with **LlamaIndex**, **Make**, **Zapier**, and **n8n** — trigger on a document URL, store the structured output.

#### Example output

```json
{
  "url": "https://example.com/report.pdf",
  "fileType": "pdf",
  "title": "Annual Report 2025",
  "author": "Example Corp",
  "pageCount": 42,
  "wordCount": 18734,
  "content": "Annual Report 2025\n\nLetter from the CEO\n\nThis year we...",
  "markdown": "# Annual Report 2025\n\n## Letter from the CEO\n\nThis year we...",
  "fetchedAt": "2026-07-02T07:20:00.000Z"
}
```

### FAQ

**Does it OCR scanned PDFs?** No. It extracts embedded text; image-only PDFs need an OCR step first.

**Which DOCX features are preserved?** Headings, paragraphs, lists, bold/italic, and links are converted to Markdown. Complex tables and embedded objects may be simplified.

**Can I cap output size?** Yes — set `maxChars` to truncate very long documents.

### Limitations

- No OCR (image-only PDFs).
- No authentication / cookies (public URLs only).
- One document per run (use a list-driven task or orchestrator for batches).

### See also

- [AI Web Page Reader](https://apify.com/entranced_gelato/ai-web-page-reader) - any URL to clean text + Markdown.
- [AI Competitive Brief Generator](https://apify.com/entranced_gelato/ai-competitive-brief-generator) - any company URL to a competitive, SEO, or sales brief.

# Actor input Schema

## `url` (type: `string`):

URL of the document to read (PDF, DOCX, TXT, or HTML).

## `summarize` (type: `boolean`):

Produce a TL;DR + key points. Requires an OpenAI API key below.

## `openaiApiKey` (type: `string`):

Your own OpenAI key. Only used when 'Generate AI summary' is on.

## `model` (type: `string`):

OpenAI model used for the summary.

## `maxChars` (type: `integer`):

Optionally cap the length of returned content/markdown.

## Actor input object example

```json
{
  "url": "https://example.com/report.pdf",
  "summarize": false,
  "model": "gpt-4o-mini",
  "maxChars": 0
}
```

# Actor output Schema

## `results` (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 = {
    "url": "https://arxiv.org/pdf/1706.03762"
};

// Run the Actor and wait for it to finish
const run = await client.actor("entranced_gelato/ai-document-reader").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 = { "url": "https://arxiv.org/pdf/1706.03762" }

# Run the Actor and wait for it to finish
run = client.actor("entranced_gelato/ai-document-reader").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "url": "https://arxiv.org/pdf/1706.03762"
}' |
apify call entranced_gelato/ai-document-reader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=entranced_gelato/ai-document-reader",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/DeODAOJWEsvWN86fN/builds/KLDe71cn27OkGQWEv/openapi.json
