PDF & Document to Markdown - PDF, DOCX & HTML for LLMs avatar

PDF & Document to Markdown - PDF, DOCX & HTML for LLMs

Pricing

from $2.80 / 1,000 document reads

Go to Apify Store
PDF & Document to Markdown - PDF, DOCX & HTML for LLMs

PDF & Document to Markdown - PDF, DOCX & HTML for LLMs

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.

Pricing

from $2.80 / 1,000 document reads

Rating

0.0

(0)

Developer

AIDevs

AIDevs

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

1

Monthly active users

4 days ago

Last modified

Share

PDF to Markdown & Text Extractor - OCR, Tables, DOCX

PDF to Markdown & Text Extractor

Convert any PDF, Word (DOCX), HTML or text document into clean, LLM-ready Markdown and plain text, with tables, per-page text, OCR for scanned pages and an optional AI summary. Built for AI engineers, RAG pipelines, document Q&A bots and no-code automations that need reliable "document to text".

Quick start

  1. Paste a document link into Document URL, or upload a file under Or upload a document. To read many documents in one run, list them under More document URLs (up to 100; one row and one charge per document read).
  2. Optionally set a Page range (for example 1-3,7), keep OCR for scanned pages on Auto, and switch on Generate AI summary if you want a TL;DR (no API key needed).
  3. Click Start, then open the Output tab or download JSON, CSV or Excel.

Sample output

{
"ok": true,
"url": "https://files.example.com/quarterly-report.pdf",
"fileName": "quarterly-report.pdf",
"fileType": "pdf",
"title": "Quarterly Report",
"author": "Example Corp",
"pageCount": 12,
"pagesProcessed": 3,
"pageRange": "1-3",
"wordCount": 1140,
"tableCount": 1,
"ocrPageCount": 1,
"needsOcr": false,
"content": "Quarterly Report\nRevenue grew by twelve percent...",
"markdown": "Quarterly Report\n\n| Product | Units | Revenue |\n| --- | --- | --- |\n| Widget | 120 | $1,200 |",
"pages": [
{ "pageNumber": 1, "method": "text", "needsOcr": false, "charCount": 2310, "text": "Quarterly Report..." },
{ "pageNumber": 2, "method": "ocr", "needsOcr": false, "charCount": 1875, "text": "Scanned appendix..." }
],
"tdmReserved": false,
"tdmPolicy": null,
"summary": null,
"aiGenerated": false,
"fetchedAt": "2026-10-10T09:00:00.000Z"
}

How much does it cost?

EventPrice
Document read$0.004 per document on the free plan, $0.0036 on Bronze, $0.0032 on Silver, $0.0028 on Gold and above
AI summary (optional)$0.02 per summary through Apify's AI gateway; no AI charge with your own OpenAI key
OCR page (scanned PDFs only)$0.003 per page read with OCR. This price starts after Apify's 14-day notice; the start date is shown in the Pricing tab; free until then. OCR itself starts on that date: until then, scanned pages come back with needsOcr: true.
  • 100 documents: $0.40 ($0.28 on Gold). With AI summaries: $2.40.
  • 1,000 documents: $4.00 ($2.80 on Gold). With AI summaries: $24.00.
  • A 10-page scanned PDF, once the OCR price has started: $0.004 + 10 x $0.003 = $0.034.

Platform usage is included in the price. You are charged only for documents that produced text. Failed downloads, blocked pages, documents that robots.txt doesn't allow, unsupported or password-protected files and documents without readable text are free. OCR is charged only for pages it actually read, and the AI summary only when it is produced. Max OCR pages and the run's maximum total charge cap your spend. On Apify's AI gateway, the AI model's usage may also be billed to your Apify account separately (see AI and your data).

Pricing update on 16 November 2026. The prices above take effect on 16 November 2026 at 14:41 UTC (Apify's 14-day notice). Until then the previous pricing applies: $0.004 for every row in the results (less on higher plans), including rows for documents that could not be read, and the AI summary at $0.02; OCR is not available yet. The Pricing tab always shows what applies today.

What it does

  • PDF: text per page, title and author metadata, page ranges, and best-effort tables: simple grid tables become Markdown tables.
  • Scanned PDFs: pages without a text layer are read with OCR (English) once the OCR price has started (see the cost table). OCR runs on Apify, offline; your file is not sent to any third-party service.
  • DOCX and HTML: headings, lists, links, emphasis and tables converted to clean Markdown; plain text keeps paragraph breaks and tab-separated table rows.
  • TXT / Markdown: returned as is.
  • File upload: drop a file into the input form instead of hosting it somewhere.
  • AI summary (optional): a TL;DR and key points, labelled as AI-generated.
  • Site rules: links are checked against the site's robots.txt before they are downloaded, and documents whose rightholder reserves text-and-data-mining rights are flagged (tdmReserved) and never sent to AI.

AI and your data

  • AI is off by default. When you switch on Generate AI summary, the document's title and first 14,000 characters go either to Apify's AI gateway (Apify's OpenRouter Actor, then OpenRouter, then the model provider; openai/gpt-4o-mini by default) or, with your own OpenAI key, straight to OpenAI.
  • Apify may bill the AI model's usage to your Apify account separately through its OpenRouter Actor, at OpenRouter's rates; free-plan accounts pay more and may be blocked. That model usage isn't part of the prices above.
  • Before the text is sent, email addresses and phone numbers in it are masked. Requests to the gateway ask OpenRouter to use only providers that don't collect your data, and only openai/... and anthropic/... models are used there (no :free or stealth variants; other model IDs fall back to openai/gpt-4o-mini). Documents that reserve text-and-data-mining rights are never sent to AI.
  • If you choose a model, you also accept that model provider's terms and acceptable-use policy.
  • Own OpenAI key: Use a dedicated OpenAI project key with a spending limit. It's used only inside your run, sent only to OpenAI, and never stored or logged. You're responsible for following OpenAI's terms. With your own key there is no AI charge.
  • EU AI Act: AIDevs is the provider of this AI feature; you're the deployer. AI fields are marked with aiGenerated, aiModel, aiGeneratedAt, aiDigitalSourceType and aiNotice. Keep the label if you publish AI text.

FAQ

Is it legal? Only process documents you have the right to process. Documents can contain personal data (e.g. names in a PDF's author field or text); you're the controller. You need a lawful basis (for example under the GDPR) for any personal data you keep or use, so keep only what you need. The Actor downloads only public links, with no logins or cookies, or reads the file you upload. It respects robots.txt by default and stops at CAPTCHAs, bot challenges and login walls instead of trying to get around them. Copyright and licences still apply to what you do with the text, and so do the source site's own terms (for the sample arXiv paper: arXiv's terms of use and the paper's licence). This is general information, not legal advice.

Does it respect robots.txt? Yes, by default (Respect robots.txt). Before it downloads a document from a link, it fetches that site's robots.txt once and follows the rules for AIDevsBot if the file has them, otherwise the rules for all bots (*); the longest matching rule wins, and redirect targets are checked too. If robots.txt answers 401 or 403, the site is treated as off-limits; if there is none (404), the document is read; if it can't be loaded (429, server error, timeout), the document isn't downloaded in that run. Documents skipped for this reason are reported for free (ROBOTS_DISALLOWED or ROBOTS_UNREACHABLE). Uploaded files aren't affected. Some file hosts, such as private cloud-storage buckets, answer robots.txt with 403: if the files are yours or you have permission, upload them or turn the option off. Turn it off only for sites you own or have permission to read.

Requests identify as AIDevsBot; site owners can opt out with User-agent: AIDevsBot / Disallow: / in robots.txt.

What does tdmReserved mean? Under EU copyright law (Article 4(3) of the DSM Directive) a rightholder can reserve text-and-data-mining rights in machine-readable form. The Actor reads the TDMRep signals of each document: the tdm-reservation and tdm-policy HTTP headers and, for HTML documents, the matching <meta> tags (the tag wins). It reports them as tdmReserved (true or false) and tdmPolicy (the rightholder's policy link, or null). A reserved document is still converted to text and Markdown, and charged as a document read, but it is never sent to AI: no AI call and no AI charge. The general EU text-and-data-mining exception doesn't cover reserved documents, so get the rightholder's permission before you use their text for data mining or AI training.

Why does a page say needsOcr: true? The page is an image without a text layer, and OCR did not run for it. Either OCR for scanned pages is Off, the Max OCR pages limit or your maximum total charge was reached, or OCR hasn't started yet for this Actor (it starts together with its price; see the cost table). The ocrNote field says which.

Do I need an OpenAI key for the summary? No. Summaries go through Apify's AI gateway for $0.02 per summary (Apify may also bill the model usage separately; see AI and your data). If you prefer, add your own OpenAI key: there is then no AI charge and OpenAI bills you for the tokens.

How do I cap the output size? Use Page range for PDFs and Max characters for any document. Very large results are shortened to fit Apify's 9 MB dataset item limit, and the record says so (truncated: true).

What happens if the link is blocked? The Actor stops at CAPTCHAs, bot challenges and login walls, reports it, and charges nothing. It never tries to get around them.

What happens to my data? AIDevs processes your input and results only to run the Actor. Nothing is kept or shared beyond your own Apify storages and the AI service you switch on.

Wrong charge? Report it in the Issues tab; we reply within 14 days.

Limitations

  • Up to 100 documents per run (list them under More document URLs); for more, split the list over several runs and space them out: a robots.txt Crawl-delay isn't applied across runs.
  • Large arXiv jobs: arXiv asks that automated downloads not be indiscriminate, so for more than a handful of papers use arXiv's own bulk-data options instead of this Actor.
  • OCR reads English only and is slower than text extraction (about 1-3 seconds per page). Handwriting and very low-quality scans give poor results.
  • PDF table detection is best effort: grid tables with short cells are converted; complex tables (merged cells, multi-line cells) stay as text lines.
  • No password-protected files, no logins or cookies: public links or uploads only.
  • Legacy .doc, spreadsheets, presentations and images are not supported.
  • AI summaries can contain mistakes; they are labelled aiGenerated: true with an aiNotice.
  • Uses Apify's standard datacenter proxies only; residential and custom proxies aren't supported.

Works with AI agents through Apify's MCP server.

Not affiliated with, endorsed by or sponsored by arXiv, Microsoft, OpenAI, Anthropic, OpenRouter, LangChain, LlamaIndex, Make, Zapier or n8n.

More tools from AIDevs


Input reference

FieldTypeDefaultDescription
urlstring(sample PDF in the form)Document URL (PDF, DOCX, TXT or HTML).
documentFilestring (file upload)(empty)Uploaded file; used instead of url when set.
urlsarray[]More document URLs to read in the same run (up to 100 documents in total). One row and one "Document read" charge per document read; maxOcrPages applies to the whole run.
pageRangestring(all pages)PDF pages to read, e.g. 1-3,7 or 5-.
ocrModeenumautoauto = OCR pages without a text layer, off = never, force = every selected page.
maxOcrPagesinteger20Maximum pages read with OCR per run.
summarizebooleanfalseAI TL;DR and key points ($0.02 via Apify's AI gateway, no AI charge with your own key).
openaiApiKeystring (secret)(empty)Optional own OpenAI key for the summary.
modelenumgpt-4o-miniModel for the summary.
aiModelstring(empty)Advanced: model ID such as openai/gpt-4o-mini; on the gateway only openai/... and anthropic/... models.
maxCharsinteger0Cap returned text/Markdown length (0 = no limit).
respectRobotsTxtbooleantrueCheck the site's robots.txt (rules for AIDevsBot, otherwise *) before downloading a link; uploads aren't affected. Turn off only for sites you own or have permission to read.
proxyConfigurationobjectApify ProxyProxy settings for downloads. Apify's standard datacenter proxies only; residential and custom proxies are ignored.

Example input: several documents in one run

{
"url": "https://files.example.com/quarterly-report.pdf",
"urls": [
"https://files.example.com/annual-report.pdf",
"https://files.example.com/price-list.docx"
],
"pageRange": "1-5",
"ocrMode": "auto",
"maxOcrPages": 20
}

Each document becomes its own row. pageRange and the OCR settings apply to every document, and maxOcrPages is shared by the whole run.

Output reference

FieldDescription
url, source, fileNameThe document link (or uploaded file), whether it came from a url or an upload, and its file name.
fileTypepdf, docx, html or text.
title, authorDocument metadata, if available.
pageCount, pagesProcessed, pageRangeTotal PDF pages, pages read, and the applied range.
wordCountWord count of the extracted text.
contentClean plain text (table rows tab-separated).
markdownLLM-ready Markdown, including Markdown tables.
tableCountTables converted to Markdown.
pagesPDFs: per-page pageNumber, method (text, ocr or none), needsOcr, charCount and text.
ocrPageCount, needsOcr, ocrNotePages read with OCR, whether any page still needs OCR, and why.
tdmReserved, tdmPolicyWhether the rightholder reserves text-and-data-mining rights (TDMRep), and their policy link.
summary, keyPointsAI summary (only when requested and produced).
aiGenerated, aiModel, aiGeneratedAt, aiDigitalSourceType, aiNotice, aiErrorAI transparency labels (model, generation time in UTC, IPTC source type, notice), and why a requested summary was not produced.
fetchedAtISO timestamp.

Documents that could not be read have ok: false, error and errorCode, for example HTTP_404, BLOCKED, ROBOTS_DISALLOWED, ROBOTS_UNREACHABLE, UNSUPPORTED_FILE_TYPE, PASSWORD_PROTECTED, INVALID_PDF, PAGE_RANGE_EMPTY, NEEDS_OCR or EMPTY_CONTENT (rarely BAD_REDIRECT, for a redirect to a non-web address). These are free.

API and integrations

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", "pageRange": "1-5" }'

Several documents in one call:

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", "urls": ["https://example.com/terms.docx", "https://example.com/notes.txt"] }'
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")
for page in doc.get("pages") or []:
print(page["pageNumber"], page["method"], page["charCount"])

LangChain and LlamaIndex: map markdown (or each entry of pages, for page-level citations) to documents with url and pageNumber as metadata.

Make, Zapier and n8n: trigger on a document URL or a file, then route the Markdown into your vector database, CRM or knowledge base.