# PDF to Markdown API & Converter: PDF to Text for AI Agents, RAG (`plainrows/pdf-to-markdown`) Actor

PDF to markdown converter and MCP tool for AI agents and RAG: give PDF URLs, get clean Markdown with headings, page texts, title, author and word count. Text-layer PDFs only, no OCR. Pay $0.003 per PDF converted (up to 30 pages), $0.0001 per extra page, plus a small start fee per run.

- **URL**: https://apify.com/plainrows/pdf-to-markdown.md
- **Developed by:** [PlainRows](https://apify.com/plainrows) (community)
- **Categories:** AI, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 pdf converteds

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

## PDF to Markdown API & Converter: PDF to Text for AI Agents, RAG

Turn **PDF URLs into clean Markdown** that LLMs, AI agents and RAG pipelines can read: headings, paragraphs, page markers, plus the title, author, page count and word count of each file. Paste a list of PDF links, get **one row per PDF**.

The text comes from the PDF's own **text layer** (pdf.js, no browser, no proxy). **Text-layer PDFs only, no OCR**: scanned PDFs made of images are reported as such, for free, instead of returning invented text.

### Typical uses

- **RAG and knowledge bases**: feed research papers, manuals, reports and documentation into a vector store as Markdown, page by page.
- **AI agents (MCP)**: let an agent read a PDF it found on the web in one tool call.
- **Summaries and extraction**: give an LLM the Markdown of contracts, filings, datasheets or whitepapers.
- **Search and archiving**: index the full text of public PDFs with their page count and word count.

### What you get for each PDF

| Field | Description |
|---|---|
| `url`, `finalUrl` | The PDF address you gave, and the address after redirects |
| `found` | `true` when the PDF was converted (billed row); `false` rows are free and say why in `error` |
| `title`, `author` | From the PDF metadata (`null` when the file has none: nothing is guessed) |
| `pageCount`, `pagesConverted` | Pages in the file, and pages converted (at most `maxPagesPerPdf`) |
| `markdown` | Markdown of the converted pages, with a `<!-- page N -->` marker before each page |
| `pages` | With `includePageTexts`: plain text of each page, `[{ "page": 1, "text": "..." }]` |
| `wordCount`, `charCount` | Words in the text and characters in the Markdown (useful to size LLM context) |
| `error`, `errorCode` | Why a PDF was not converted (`NOT_A_PDF`, `TOO_LARGE`, `HTTP_ERROR`, `NO_TEXT_LAYER`, `UNREADABLE_PDF`, `ENCRYPTED_PDF`, `TIMEOUT`...), or a note when only part of it was converted |
| `convertedAt` | When the PDF was processed (UTC) |

Headings are **approximated from font size** (a line clearly larger than the body text becomes `#`, `##` or `###`). Tables, images and multi-column layouts come out as plain text in reading order as stored in the PDF; words split by a hyphen at a line end are joined.

### Input

```json
{
  "urls": ["https://arxiv.org/pdf/1706.03762", "https://www.irs.gov/pub/irs-pdf/fw9.pdf"],
  "maxPagesPerPdf": 30,
  "includePageTexts": false
}
```

- `urls`: public PDF addresses, up to 5,000 per run (duplicates removed). Files up to 50 MB.
- `maxPagesPerPdf` (default 30, max 300): only the first pages up to this number are converted.
- `includePageTexts` (default false): also return the text of each page.

### Output example

```json
{
  "url": "https://arxiv.org/pdf/1706.03762",
  "found": true,
  "title": null,
  "author": null,
  "pageCount": 15,
  "pagesConverted": 15,
  "markdown": "<!-- page 1 -->\n\nProvided proper attribution is provided, Google hereby grants permission...\n\n## Attention Is All You Need\n\nAshish Vaswani∗ Google Brain avaswani@google.com\n\n...\n\n### Abstract\n\nThe dominant sequence transduction models are based on complex recurrent or convolutional neural networks...",
  "pages": null,
  "wordCount": 6135,
  "charCount": 40118,
  "error": null,
  "errorCode": null,
  "finalUrl": "https://arxiv.org/pdf/1706.03762",
  "convertedAt": "2026-10-23T14:00:00.000Z",
  "schemaVersion": "1.0"
}
```

(Excerpt; this arXiv file has no title in its metadata, so `title` is `null`.)

### Pricing

Pay per PDF converted, no subscription:

- **$0.003 per PDF converted** (`pdf-converted`), up to 30 pages included;
- **$0.0001 per extra page** (`extra-page`) beyond 30, only if you raise `maxPagesPerPdf` and the PDF is longer;
- a small start fee per run (`apify-actor-start`, $0.002 per GB of memory).

**Free rows**: PDFs without a text layer (scans), unreadable or password-protected files, files over 50 MB, non-PDF URLs (HTML pages, images), and URLs that fail (404, timeout, invalid or private address). The run never spends more than the maximum cost you set; if a run keeps hitting free failures, it stops early and says so.

**Free Apify plan:** each run converts up to 10 PDFs, so you can check the output. A paid Apify plan removes this limit.

### Use it from code, automations or AI agents

Call it from the Apify API, the Apify MCP server (as a tool for Claude, ChatGPT or any MCP client), Make, Zapier, n8n or LangChain. Results are in the run's dataset (JSON, CSV, Excel); the run summary is in the `OUTPUT` record of its key-value store.

### FAQ

**Does it do OCR?** No. It reads the text layer that most digital PDFs contain (exported from Word, LaTeX, browsers...). A scanned PDF without text returns `found: false`, `errorCode: NO_TEXT_LAYER`, free.

**Are the headings exact?** They are an approximation from font size; the text itself is exactly what the PDF contains.

**What about very long PDFs?** Set `maxPagesPerPdf` up to 300. Each PDF also has a time limit; if it is reached, the pages already converted are returned and only those are charged.

**Which PDFs can it fetch?** Public `http(s)` URLs that return a PDF file. Private network addresses are refused. The Actor identifies itself with a PlainRows user agent.

### More PlainRows tools

Same pay-per-result pricing, same clean JSON, built to chain together in n8n, Make, Zapier or AI agents.

- **SEO and keywords:** [Keyword Search Volume, CPC & Difficulty](https://apify.com/plainrows/keyword-search-volume) · [Keyword Planner Alternative (Bulk Search Volume & CPC)](https://apify.com/plainrows/keyword-planner-alternative) · [Google Keyword Planner API (Google Ads Search Volume & CPC)](https://apify.com/plainrows/google-keyword-planner-api) · [Bing Keyword Search Volume & CPC](https://apify.com/plainrows/bing-keyword-search-volume) · [Keyword Ideas Generator](https://apify.com/plainrows/keyword-ideas-generator) · [Google Autocomplete & People Also Ask](https://apify.com/plainrows/google-autocomplete-questions) · [Google Trends Explorer](https://apify.com/plainrows/google-trends-explorer) · [Google Trends Keyword Discovery (Rising & Related)](https://apify.com/plainrows/google-trends-keyword-discovery) · [Website Organic Traffic & Top Keywords](https://apify.com/plainrows/domain-seo-overview) · [Competitor Keywords API (Ranked Keywords)](https://apify.com/plainrows/competitor-keywords-api) · [Bulk Website Traffic Checker](https://apify.com/plainrows/website-traffic-checker) · [SEO Competitors & Keyword Gap Finder](https://apify.com/plainrows/seo-competitors-keyword-gap) · [PPC Competitor Keywords (SpyFu Alternative)](https://apify.com/plainrows/ppc-competitor-keywords) · [Bulk Domain Authority Checker](https://apify.com/plainrows/domain-authority-checker) · [Backlink Checker](https://apify.com/plainrows/backlink-checker) · [Backlink API (Referring Domains & Backlinks Data)](https://apify.com/plainrows/backlink-api) · [Broken Link Checker](https://apify.com/plainrows/broken-link-checker) · [SEO Audit API (On-Page SEO Checker)](https://apify.com/plainrows/seo-audit-api) · [AI Search Visibility Tracker (ChatGPT, Gemini, AI Mode)](https://apify.com/plainrows/ai-search-brand-visibility) · [AI Overview Tracker (Google AI Overview Citations)](https://apify.com/plainrows/ai-overview-tracker) · [Perplexity Search API (Answers & Citations)](https://apify.com/plainrows/perplexity-search-api) · [ChatGPT Search Scraper (Answers & Citations)](https://apify.com/plainrows/chatgpt-search-scraper) · [AI Citations Finder (LLM Mentions in ChatGPT & AI Overviews)](https://apify.com/plainrows/ai-citations-finder) · [Keyword Rank Checker (Google SERP Position)](https://apify.com/plainrows/keyword-rank-checker) · [Google Search API (SERP Scraper & Web Results)](https://apify.com/plainrows/google-search-api) · [Bing Search API (Bing SERP & Web Results)](https://apify.com/plainrows/bing-search-api) · [Google Maps Rank Tracker (Geo-Grid Local SEO)](https://apify.com/plainrows/google-maps-rank-tracker)
- **Leads and companies:** [Google Maps Scraper](https://apify.com/plainrows/google-maps-businesses) · [Google Maps Email Extractor](https://apify.com/plainrows/google-maps-email-extractor) · [Google Maps Businesses Without Website](https://apify.com/plainrows/google-maps-no-website-leads) · [Yellow Pages Australia Scraper](https://apify.com/plainrows/yellowpages-au-scraper) · [Website Technology Checker](https://apify.com/plainrows/website-tech-stack) · [Website Email Extractor](https://apify.com/plainrows/website-email-extractor) · [Contact Details Scraper (Emails, Phones, Socials)](https://apify.com/plainrows/contact-details-scraper) · [ATS Jobs Scraper (Workday, Greenhouse, Lever, Ashby)](https://apify.com/plainrows/ats-job-postings) · [Workday Jobs Scraper](https://apify.com/plainrows/workday-jobs-scraper) · [Greenhouse Jobs Scraper](https://apify.com/plainrows/greenhouse-jobs-scraper) · [Lever Jobs Scraper](https://apify.com/plainrows/lever-jobs-scraper) · [Ashby Jobs Scraper](https://apify.com/plainrows/ashby-jobs-scraper) · [Google Jobs Scraper](https://apify.com/plainrows/google-jobs-scraper) · [Reed.co.uk Jobs Scraper (UK)](https://apify.com/plainrows/reed-jobs-scraper) · [jobs.ch & jobup.ch Jobs Scraper (Switzerland)](https://apify.com/plainrows/jobs-ch-scraper) · [Arbeitsagentur Jobs Scraper (Germany)](https://apify.com/plainrows/arbeitsagentur-jobs-scraper) · [Gupy Jobs Scraper (Brazil)](https://apify.com/plainrows/gupy-jobs-scraper) · [Catho Jobs Scraper (Brazil)](https://apify.com/plainrows/catho-jobs-scraper) · [Vagas.com.br Jobs Scraper (Brazil)](https://apify.com/plainrows/vagas-jobs-scraper) · [Jobs.cz Scraper (Czech Republic)](https://apify.com/plainrows/jobs-cz-scraper) · [Remote Jobs Scraper (Himalayas, RemoteOK, Jobicy)](https://apify.com/plainrows/remote-jobs-aggregator) · [Google Ads Scraper (Transparency Center)](https://apify.com/plainrows/google-ads-transparency) · [Company Registry Lookup (SIRENE, LEI, Brreg)](https://apify.com/plainrows/company-registry-lookup) · [Public Tenders Search (EU TED & UK)](https://apify.com/plainrows/public-tenders-search)
- **E-commerce and travel:** [Amazon Product Search Scraper](https://apify.com/plainrows/amazon-product-search) · [Amazon Keyword Research (Search Volume & Reverse ASIN)](https://apify.com/plainrows/amazon-keyword-research) · [Google Shopping Prices Scraper](https://apify.com/plainrows/google-shopping-prices) · [Google Hotels Prices Scraper](https://apify.com/plainrows/google-hotels-prices) · [Google Hotels Scraper](https://apify.com/plainrows/google-hotels-scraper) · [Tripadvisor Reviews Scraper](https://apify.com/plainrows/tripadvisor-reviews) · [Trustpilot Reviews Scraper](https://apify.com/plainrows/trustpilot-reviews)
- **Marketplaces and classifieds:** [AliExpress Scraper](https://apify.com/plainrows/aliexpress-scraper) · [Kleinanzeigen Scraper (Germany)](https://apify.com/plainrows/kleinanzeigen-scraper) · [AutoScout24 Scraper (Cars, Europe)](https://apify.com/plainrows/autoscout24-scraper) · [Kijiji Scraper (Canada)](https://apify.com/plainrows/kijiji-scraper) · [Marktplaats Scraper (Netherlands)](https://apify.com/plainrows/marktplaats-scraper) · [Property Finder Scraper (UAE)](https://apify.com/plainrows/propertyfinder-scraper) · [Redfin Scraper (US Homes for Sale)](https://apify.com/plainrows/redfin-scraper) · [Otomoto Scraper (Polish Car Listings)](https://apify.com/plainrows/otomoto-scraper) · [Otodom Scraper (Poland Property)](https://apify.com/plainrows/otodom-scraper) · [Imovirtual Scraper (Portugal Property)](https://apify.com/plainrows/imovirtual-scraper) · [Standvirtual Scraper (Portugal Cars)](https://apify.com/plainrows/standvirtual-scraper) · [Immoweb Scraper (Belgium Property)](https://apify.com/plainrows/immoweb-scraper) · [Blocket Scraper (Sweden)](https://apify.com/plainrows/blocket-scraper) · [FINN.no Scraper (Norway)](https://apify.com/plainrows/finn-scraper) · [coches.net Scraper (Spain Cars)](https://apify.com/plainrows/coches-net-scraper) · [2dehands Scraper (Belgium)](https://apify.com/plainrows/2dehands-scraper) · [Storia Scraper (Romania Property)](https://apify.com/plainrows/storia-scraper) · [Autovit Scraper (Romania Cars)](https://apify.com/plainrows/autovit-scraper) · [FINN.no Car Scraper (Norway Cars)](https://apify.com/plainrows/finn-cars-scraper) · [DBA Scraper (Denmark)](https://apify.com/plainrows/dba-scraper) · [Tori.fi Scraper (Finland)](https://apify.com/plainrows/tori-scraper)
- **Content and media:** [Google News Scraper](https://apify.com/plainrows/google-news-scraper) · [YouTube Search Scraper](https://apify.com/plainrows/youtube-search-scraper) · [YouTube Search API (JSON)](https://apify.com/plainrows/youtube-search-api) · [YouTube Comments Scraper](https://apify.com/plainrows/youtube-comments-scraper) · [Google Images Scraper](https://apify.com/plainrows/google-images-scraper) · [Website Screenshot API](https://apify.com/plainrows/website-screenshot) · [Google Maps Reviews Scraper](https://apify.com/plainrows/google-maps-reviews) · [Google Reviews Scraper](https://apify.com/plainrows/google-reviews-scraper) · [App Store & Google Play Reviews Scraper](https://apify.com/plainrows/app-reviews-scraper) · [App Store & Google Play App Details Scraper](https://apify.com/plainrows/app-details-scraper) · [Google Play Reviews Scraper](https://apify.com/plainrows/google-play-reviews-scraper) · [App Store Reviews Scraper](https://apify.com/plainrows/app-store-reviews-scraper)

# Actor input Schema

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

Public addresses of PDF files, one per line (e.g. "https://arxiv.org/pdf/1706.03762"). Up to 5,000 per run; duplicates are removed. Files up to 50 MB; text-layer PDFs only (no OCR).

## `maxPagesPerPdf` (type: `integer`):

Only the first pages up to this number are converted. Up to 30 pages are included in the price of a PDF; each converted page beyond 30 costs $0.0001.

## `includePageTexts` (type: `boolean`):

Also return the plain text of each page in "pages" (page number + text), next to the full Markdown. It does not change the price.

## Actor input object example

```json
{
  "urls": [
    "https://arxiv.org/pdf/1706.03762",
    "https://www.irs.gov/pub/irs-pdf/fw9.pdf"
  ],
  "maxPagesPerPdf": 30,
  "includePageTexts": false
}
```

# Actor output Schema

## `results` (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://arxiv.org/pdf/1706.03762",
        "https://www.irs.gov/pub/irs-pdf/fw9.pdf"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainrows/pdf-to-markdown").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://arxiv.org/pdf/1706.03762",
        "https://www.irs.gov/pub/irs-pdf/fw9.pdf",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("plainrows/pdf-to-markdown").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://arxiv.org/pdf/1706.03762",
    "https://www.irs.gov/pub/irs-pdf/fw9.pdf"
  ]
}' |
apify call plainrows/pdf-to-markdown --silent --output-dataset

```

## MCP server setup

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

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/hoO2DrZGezMctRV5n/builds/qISkQUqYEmRN9NUup/openapi.json
