PDF & DOCX to Markdown Converter for AI Agents avatar

PDF & DOCX to Markdown Converter for AI Agents

Pricing

from $1.00 / 1,000 page converteds

Go to Apify Store
PDF & DOCX to Markdown Converter for AI Agents

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

Owlabee

Maintained by Community

Actor 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

  1. 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), or data: URLs with inline content.
  2. Optionally turn on Create RAG chunks (set chunk size and overlap), OCR scanned pages, or Save Markdown files to the key-value store.
  3. Click Start. Each document appears in the dataset as soon as it is converted; open the markdown field or download the .md files.

Input

FieldTypeRequiredDescription
urlsstring[]yesDocuments to convert: http(s)://, kvs://<storeId>/<key> or data: URLs, one per entry
chunkbooleannoAlso emit heading-aware chunk records (default false)
chunkTokensintegernoTarget chunk size in estimated tokens (default 800, 100–8000)
chunkOverlapTokensintegernoOverlap repeated from the previous chunk (default 80, capped at half the chunk size)
ocrbooleannoRun OCR on PDF pages without extractable text (default false)
saveToKeyValueStorebooleannoWrite <slug>.md into the default key-value store and record kvsKey (default false)
pageBreaksbooleannoKeep <!-- page N --> markers between PDF pages (default true)
maxFileSizeMbintegernoReject larger files with a TOO_LARGE error item (default 25, max 50)
downloadTimeoutSecsintegernoPer-file download timeout (default 20, 5–120)
webhookUrlstringnoPOST 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.

EventPriceNotes
Page converted$0.001Per 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.005Per scanned page recognised, only with ocr: true, on top of the page price
Chunk created$0.0002Per chunk record, only with chunk: true
Actor start$0.00005Apify 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 a PROCESSING_TIMEOUT warning.
  • 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: true should 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 needsOcrPages list unless ocr is 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.

Other pay-per-event Actors from the same account, all limited-permission and agent-friendly:

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.

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.