PDF & DOCX to Markdown Converter for AI Agents
Pricing
from $1.00 / 1,000 page converteds
PDF & DOCX to Markdown Converter for AI Agents
Convert PDF, DOCX, HTML and text documents from URLs into clean Markdown with headings, lists, tables, links and metadata, plus optional heading-aware RAG chunks and OCR for scanned pages. No browser, no external API. Pay per page converted ($0.001).
Pricing
from $1.00 / 1,000 page converteds
Rating
0.0
(0)
Developer
Owlabee
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
What it does
Point this Actor at document URLs and get back clean, LLM-ready Markdown: headings with the right levels, bullet and numbered lists, tables as GFM tables, links, page markers and document metadata (title, author, producer, creation date, page count). It reads PDF (text layout reconstructed from the PDF's own text layer — no browser, no external API), DOCX, HTML, Markdown and plain text, so agents and RAG pipelines can send it anything they find and always get the same shape back.
Optional extras: heading-aware chunking (recordType: chunk records with page range, heading path and a token estimate, ready to embed), OCR for scanned PDF pages (bundled English tesseract model, runs inside the Actor, no data leaves Apify), and writing every document's Markdown as a .md file into the run's key-value store.
One dataset record per document; results stream in as each file finishes and are available as JSON, CSV, Excel, via the API, webhooks or the Apify MCP server.
How to use
- Enter Document URLs — public
https://links to PDF/DOCX/HTML/text files,kvs://<storeId>/<key>references to files you uploaded to an Apify key-value store (kvs://default/<key>for the run's own store), ordata:URLs with inline content. - Optionally turn on Create RAG chunks (set chunk size and overlap), OCR scanned pages, or Save Markdown files to the key-value store.
- Click Start. Each document appears in the dataset as soon as it is converted; open the
markdownfield or download the.mdfiles.
Input
| Field | Type | Required | Description |
|---|---|---|---|
urls | string[] | yes | Documents to convert: http(s)://, kvs://<storeId>/<key> or data: URLs, one per entry |
chunk | boolean | no | Also emit heading-aware chunk records (default false) |
chunkTokens | integer | no | Target chunk size in estimated tokens (default 800, 100–8000) |
chunkOverlapTokens | integer | no | Overlap repeated from the previous chunk (default 80, capped at half the chunk size) |
ocr | boolean | no | Run OCR on PDF pages without extractable text (default false) |
saveToKeyValueStore | boolean | no | Write <slug>.md into the default key-value store and record kvsKey (default false) |
pageBreaks | boolean | no | Keep <!-- page N --> markers between PDF pages (default true) |
maxFileSizeMb | integer | no | Reject larger files with a TOO_LARGE error item (default 25, max 50) |
downloadTimeoutSecs | integer | no | Per-file download timeout (default 20, 5–120) |
webhookUrl | string | no | POST target for the run summary |
Output example
Document record (recordType: "document"), one per input URL:
{"recordType": "document","url": "https://arxiv.org/pdf/1706.03762v7","filename": "1706.03762v7.pdf","mimeType": "application/pdf","bytes": 2215244,"pages": 15,"pagesProcessed": 15,"title": null,"author": null,"producer": "pdfTeX-1.40.25","creationDate": "2024-04-10T21:11:43.000Z","markdown": "<!-- page 1 -->\n\n# Attention Is All You Need\n\n| Ashish Vaswani∗ | Noam Shazeer∗ | ... |\n\n## Abstract\n\nThe dominant sequence transduction models are based on complex recurrent or convolutional neural networks ...\n\n<!-- page 2 -->\n\n## 1 Introduction\n\nRecurrent neural networks, long short-term memory [13] and gated recurrent [7] neural networks ...","characters": 39412,"words": 6004,"headings": [{ "level": 1, "text": "Attention Is All You Need" },{ "level": 2, "text": "Abstract" },{ "level": 2, "text": "1 Introduction" },{ "level": 3, "text": "3.1 Encoder and Decoder Stacks" }],"tables": 12,"links": [{ "url": "https://github.com/tensorflow/tensor2tensor", "page": 10, "text": "https://github.com/" }],"needsOcrPages": [],"ocrPages": [],"warnings": ["283 rotated text item(s) skipped (watermarks or sideways labels)"],"kvsKey": null,"processingMs": 2766,"fetchedAt": "2026-10-16T13:20:00.000Z"}
Chunk record (recordType: "chunk"), only when chunk is on:
{"recordType": "chunk","url": "https://arxiv.org/pdf/1706.03762v7","filename": "1706.03762v7.pdf","chunkIndex": 4,"chunkCount": 17,"startPage": 3,"endPage": 4,"headingPath": ["Attention Is All You Need", "3 Model Architecture", "3.2 Attention"],"markdown": "### 3.2 Attention\n\nAn attention function can be described as mapping a query and a set of key-value pairs to an output ...","tokensEstimate": 572,"characters": 2287,"fetchedAt": "2026-10-16T13:20:00.000Z"}
Error items look like { "recordType": "document", "url": "...", "error": "NOT_FOUND", "errorMessage": "HTTP 404 for ..." } with codes INVALID_URL, DOWNLOAD_FAILED, TIMEOUT, TOO_LARGE, NOT_FOUND, UNSUPPORTED_TYPE, CORRUPT_FILE, PASSWORD_PROTECTED or PROCESSING_FAILED. They are charged as one page, because the work to discover the problem was done.
Pricing
Pay per event. You only pay for what the Actor produces; set a maximum cost per run in the run options to cap spend.
| Event | Price | Notes |
|---|---|---|
| Page converted | $0.001 | Per page of every document record (PDF pages; DOCX declared page count; HTML/text ≈ 1 page per 3,000 characters). Error items count as 1 page |
| OCR page | $0.005 | Per scanned page recognised, only with ocr: true, on top of the page price |
| Chunk created | $0.0002 | Per chunk record, only with chunk: true |
| Actor start | $0.00005 | Apify platform event |
Examples: a 30-page PDF ≈ $0.03; 1,000 pages ≈ $1.00; chunking those 1,000 pages into ~1,200 chunks adds ≈ $0.24; OCR on a 100-page scan adds $0.50.
Limits and fair use
- Files up to 25 MB by default (
maxFileSizeMb, max 50 MB); 20 s download timeout by default; 10 minutes of processing per file, after which the pages converted so far are returned with aPROCESSING_TIMEOUTwarning. - Two documents are processed concurrently; a text-based PDF converts at roughly 50–200 pages per second, OCR at 2–5 seconds per page.
- Memory is set to 512–2048 MB (higher than our usual 256–1024 MB default) because pdf.js keeps page content and fonts in memory and OCR renders pages to bitmaps; 50 MB scans with
ocr: trueshould run with 2048 MB. - Layout reconstruction is heuristic: headings come from font-size and bold clusters, tables from column alignment, two-column pages are read column by column, running headers/footers and page numbers are stripped. Complex forms, rotated text, equations and multi-line table cells are best effort. Images are not extracted.
- OCR is English only and ignores the
needsOcrPageslist unlessocris on, so scanned documents cost nothing extra until you ask. - Only publicly reachable URLs and your own key-value stores are accessed. No proxies, no login, no third-party APIs. The Actor contacts only the URLs you give it and the optional webhook.
Related Actors
Other pay-per-event Actors from the same account, all limited-permission and agent-friendly:
- Website Change Monitor — Sitemap & Page Content Diff — find new or changed pages on a site, then convert the documents they link to.
- Podcast RSS Feed Scraper — Episodes & Transcripts — episode metadata and transcript text from podcast feeds, ready for the same RAG pipeline.
- US Government Grants & Contract Opportunities Feed — grant and contract opportunities whose attached PDFs this Actor can turn into Markdown.
FAQ
Does this need proxies, a browser or an API key? No. It downloads files with plain HTTPS and converts them in-process with pdf.js, mammoth, turndown and tesseract.js. Nothing is sent to an external conversion service.
How is cost controlled? Every page is charged as it is converted and every chunk as it is saved; the Actor stops cleanly when the run's maximum total charge is reached. maxFileSizeMb and the 10-minute per-file cap bound the work a single URL can cause. Scanned pages are only OCR'd (and billed at $0.005) when ocr is on.
What happens with scanned PDFs? Pages with no extractable text are listed in needsOcrPages and marked <!-- page N: no extractable text --> in the Markdown. Turn on ocr to have them recognised; the result is marked <!-- page N: ocr --> and the pages appear in ocrPages.
Can an AI agent use it? Yes — it is pay-per-event, uses limited permissions and returns one predictable record per document, so it is discoverable and callable through the Apify MCP server. Prompts like "convert this PDF to Markdown and give me its headings" or "chunk these three reports into 800-token pieces for my vector store" map directly to the input.
How do chunks reference pages? Each chunk carries startPage/endPage (from the <!-- page N --> markers) and headingPath, the heading hierarchy the chunk's content lives under, so citations and filters work without re-parsing the document.
Why is a DOCX or HTML file charged as N pages? DOCX files declare their last-saved page count (docProps/app.xml); when that is missing, and for HTML/Markdown/text, pages are estimated at one per ~3,000 characters (pagesEstimated: true).
What if the URL is not a document? You get an error item (UNSUPPORTED_TYPE, NOT_FOUND, ...) instead of a failed run, charged as a single page.
Legal
Only convert documents you are allowed to access and process. Use the output in compliance with the source's terms and applicable law. This Actor is not a consumer reporting agency and its output must not be used for employment, credit, insurance, or tenant screening decisions.