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.