PDF Text and Markdown Extractor turns public PDF links into clean text, pragmatic Markdown, page-level content, and document metadata. Use this PDF text extractor when you need a repeatable dataset for RAG, AI agents, search, research, or document automation.
Provide one or more direct public PDF URLs. Each URL becomes one dataset row, including an explicit failure row when a download or document cannot be read. That makes batch workflows easier to retry without losing successful documents.
What you get
Successful rows can contain:
- Full extracted text for indexing or analysis.
- LLM-ready Markdown for chunking and retrieval workflows.
- Selected page-level text, Markdown, OCR state, and warnings.
- PDF metadata such as title, author, subject, creator, producer, and dates.
- Character and word counts for quick filtering.
- Clear
success,partial, orfailedstatus with an error when applicable.
Who is it for?
Use this Actor if you work with public reports, research papers, manuals, invoices, policy documents, or document archives and need structured text without manually copying from a PDF viewer.
- AI and RAG teams: prepare PDF text and Markdown for retrieval pipelines.
- Researchers: batch extract papers and reports for search or analysis.
- Operations teams: turn public manuals or compliance documents into usable records.
- Developers: call a PDF to Markdown workflow from the Apify API or an MCP client.
Input recipes
Extract text and Markdown from one PDF
{
"pdfUrls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],
"includeMarkdown": true,
"includePages": true,
"maxPages": 20
}
Extract selected pages only
{
"pdfUrls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],
"pageRange": "1-3,5",
"includeMarkdown": true,
"includePages": true
}
Use OCR for a scanned PDF
{
"pdfUrls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],
"enableOcr": true,
"ocrLanguage": "eng",
"maxPages": 10
}
Example output
{
"sourceUrl": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"fileName": "dummy.pdf",
"status": "success",
"pageCount": 1,
"extractedPageCount": 1,
"metadata": { "title": null, "author": null },
"text": "…",
"markdown": "…",
"pages": [{ "page": 1, "text": "…", "markdown": "…", "ocrApplied": false, "warnings": [] }],
"ocr": { "enabled": false, "language": null, "pagesOcred": 0 },
"charCount": 123,
"wordCount": 20,
"warnings": []
}
Input settings
| Input | Description |
|---|---|
pdfUrls |
One to 50 direct, public HTTP(S) PDF URLs. |
pageRange |
Optional 1-indexed range such as 1-3,5,8-. |
includeMarkdown |
Creates a Markdown rendition from extracted text. |
includePages |
Includes selected per-page text, Markdown, and OCR state. |
enableOcr |
Attempts OCR for selected pages with no usable text layer. |
ocrLanguage |
Tesseract language code used when OCR is enabled. |
maxPages |
Per-document page limit; use a low value for a fast first run. |
maxConcurrency |
Number of PDF URLs handled in parallel (1–5). |
maxPdfSizeMb |
Rejects larger downloads before parsing. |
PDF to Markdown for AI workflows
PDF layouts do not reliably carry semantic structure, so Markdown is a practical text rendition rather than a visual reconstruction. Keep includePages on when an agent needs page context, and use pageRange to limit long documents before sending content to a model or vector store.
For scanned documents, enable OCR only when needed. This PDF OCR API option adds processing time but can recover readable text from pages without a native text layer.
API usage
Run the Actor with the Apify API and read the default dataset for one row per URL.
cURL
curl "https://api.apify.com/v2/acts/fetch_cat~pdf-text-markdown-extractor/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"pdfUrls":["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],"includeMarkdown":true}'
Node.js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/pdf-text-markdown-extractor').call({
pdfUrls: ['https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'],
includeMarkdown: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
Python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("fetch_cat/pdf-text-markdown-extractor").call(run_input={
"pdfUrls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],
"includeMarkdown": True,
})
print(client.dataset(run["defaultDatasetId"]).list_items().items)
MCP and agent use
Use the same input in an MCP-enabled agent through the Apify MCP server: open this Actor's tools. The result dataset provides text, Markdown, pages, and status fields for the next step in an automated workflow.
For Claude Code, add the scoped server with:
claude mcp add apify-pdf-text -- npx -y @apify/actors-mcp-server --tools fetch_cat/pdf-text-markdown-extractor
For a JSON MCP client configuration:
{
"mcpServers": {
"apify-pdf-text": {
"command": "npx",
"args": ["-y", "@apify/actors-mcp-server", "--tools", "fetch_cat/pdf-text-markdown-extractor"]
}
}
}
Example prompts: “Extract the first five pages from this public PDF as Markdown” and “Run the PDF text extractor, then summarize only rows where status is success.”
Tips
- Start with one direct URL and a low
maxPagesvalue to verify the output shape. - Use
pageRangefor large documents when only a chapter or appendix matters. - Preserve
sourceUrlandprocessedAtwhen loading results into a downstream dataset. - Filter on
statusbefore sending content into a production AI workflow.
Support
For a reproducible problem, include the public PDF URL, exact input JSON, and the returned error or status row when opening an issue on the Actor page. Do not share private documents or credentials.
Known-good reproduction: run mvWPeLgKrnLzXbTMF used this public URL and input:
{
"pdfUrls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],
"includeMarkdown": true,
"includePages": true,
"enableOcr": false,
"maxPages": 5
}
Expected: one success row with non-empty text, markdown, pages, and document metadata.
Actual: the linked run succeeded and returned one processed PDF row. If your result differs, include the run ID or run URL, your input JSON, the public PDF URL, and the relevant output row.