PDF to Markdown API
Convert native and scanned PDFs to Markdown with one REST endpoint built for developers, RAG pipelines, and document automation.
Endpoint
POST https://pdftomarkdown.dev/v1/convert
curl
curl -X POST https://pdftomarkdown.dev/v1/convert \
-H "Authorization: Bearer demo_public_key" \
-H "Content-Type: application/json" \
-d '{"input":{"pdf_url":"https://pdftomarkdown.dev/samples/invoice.pdf"}}' Python
import requests
response = requests.post(
"https://pdftomarkdown.dev/v1/convert",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"input": {"pdf_url": "https://pdftomarkdown.dev/samples/invoice.pdf"}},
)
print(response.json()["markdown"]) CLI
npx pdftomarkdown document.pdf > document.md The official CLI (Node 18+, nothing to install) converts local files, URLs, or stdin and prints markdown to stdout. Set PDFTOMARKDOWN_API_KEY for your own key. Claude Code users can install the official plugin instead — details in the CLI guide.
Request body
input.pdf_url: public URL of a PDF.input.pdf_base64: base64-encoded PDF bytes.input.include_raw: optional debug field for raw model output.input.max_pages: optional page cap. The public demo tier always caps to page 1.
Response
{
"markdown": "# Invoice\n\n| Item | Qty | Price |\n|---|---|---|",
"pages": 1,
"request_id": "req_abc123"
} When to use it
Use the API when Markdown is the handoff format for chunking, embeddings, LLM prompts, search indexing, document review, or downstream extraction. If you need local-only processing, use a local parser instead.
Frequently asked questions
What are the rate limits and quotas?
The keyless demo tier allows 3 requests per minute per IP and converts page 1 only. A free Developer key (GitHub login) gives 100 pages per month with full multi-page support. Every 429 response includes retry_after_seconds.
Can I call the API from browser JavaScript?
Yes — CORS is enabled (Access-Control-Allow-Origin: *), and the timing and request-id headers are exposed to browser code.
How do I keep latency bounded on large PDFs?
Set input.max_pages to cap the pages processed, and give your HTTP client a timeout of at least 10 minutes. Each response reports x-queue-ms (worker wait) and x-processing-ms (actual OCR time) so you can see where time went.
What do error responses look like?
Every error is JSON with the same shape: error (machine-readable code), message (states the recommended fix), docs (URL), and request_id. For example, an unreachable pdf_url returns 422 with a message suggesting the pdf_base64 fallback.
Is there an SDK?
No SDK is required — it's one HTTP call from any language, and the OpenAPI 3.1 spec can generate a typed client. There is also an official CLI (npx pdftomarkdown) and a Claude Code plugin.
Trust links
Review security, privacy, and data retention before processing sensitive documents.