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.mdThe 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
{
"complete": true,
"markdown": "# CONTOSO LTD.\n\n# INVOICE\n\nINVOICE: INV-100\nDATE: 11/15/2019\nDUE DATE: 12/15/2019\n\n| SALESPERSON | P.O. NUMBER | REQUISITIONER | SHIPPED VIA | F.O.B. POINT | TERMS |\n| --- | --- | --- | --- | --- | --- |\n| | PO-3333 | | | | |\n\n| QUANTITY | DESCRIPTION | UNIT PRICE | TOTAL |\n| --- | --- | --- | --- |\n| 1 | Test for 23 fields | $100.00 | $100.00 |\n\nTOTAL DUE: $610.00\n\n> Processed by pdfToMarkdown.dev",
"pages": 1,
"request_id": "req_example_invoice"
}A success is explicitly marked complete: true. Simple rectangular tables use escaped GFM pipe-table syntax. Complex tables with spans or nested content remain sanitized CommonMark-compatible raw HTML so their structure is not discarded. Over-budget complete output fails with response_too_large instead of returning partial Markdown.
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.
Built on PaddleOCR-VL-1.6 — see the hosted model page for model, deployment, and access details.
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.