PDF to Markdown Endpoint Reference

Technical reference for POST /v1/convert, including auth, request fields, response shape, and errors.

Use this page to implement the request, success and error contract. For a first request, start with the quickstart; for local-file integration, use the Python batch recipe. The OpenAPI 3.1 specification provides machine-readable schemas.

Endpoint

POST /v1/convert

Prefer the terminal? The official CLI wraps this endpoint: npx pdftomarkdown document.pdf — see the CLI guide.

Authentication

Send Authorization: Bearer <api_key>. The public demo key is shown in the main docs and converter, but production usage should use a Developer key.

Browser sessions instead require the signed-in session cookie and X-CSRF-Token. For account work, save an Idempotency-Key before submission: 8–128 characters from A–Z a–z 0–9 _ . : -. Reuse it only with identical document bytes and options.

Input schema

{
  "input": {
    "pdf_url": "https://pdftomarkdown.dev/samples/invoice.pdf",
    "include_raw": false,
    "max_pages": 3
  }
}

This example uses URL input only. Provide exactly one source; see separate URL, Base64 and raw upload examples. Send Content-Type: application/json with these fields:

  • input.pdf_url: nonempty, public HTTP(S) PDF URL.
  • input.pdf_base64: nonempty Base64-encoded PDF bytes, instead of a URL.
  • input.max_pages: optional positive safe integer (1–9007199254740991), selecting the first N pages. The original document must still have at most 1,000 pages.
  • input.include_raw: optional boolean, default false; adds debug output.
  • input.draft_id: an owned, server-issued UUID used alone, with no source or option overrides. Account drafts expire after 30 minutes.

Alternatively send raw bytes with Content-Type: application/pdf; supply optional max_pages and include_raw=true|false once in the query string. URL, Base64 and binary input all share the 50 MiB decoded-file limit.

Success schema

{
  "complete": true,
  "markdown": "# CONTOSO LTD.\n\n# INVOICE\n\nContoso Headquarters\n\n123 456th St\n\nNew York, NY, 10001\n\nINVOICE: INV-100\n\nDATE: 11/15/2019\n\nDUE DATE: 12/15/2019\n\nCUSTOMER NAME: MICROSOFT CORPORATION\n\nCUSTOMER ID: CID-12345\n\nMicrosoft Corp\n\n123 Other St,\n\nRedmond WA, 98052\n\nBILL TO:\n\nMicrosoft Finance\n\n123 Bill St,\n\nRedmond WA, 98052\n\nSHIP TO:\n\nMicrosoft Delivery\n\n123 Ship St,\n\nRedmond WA, 98052\n\nSERVICE ADDRESS:\n\nMicrosoft Services\n\n123 Service St,\n\nRedmond WA, 98052\n\n| SALESPERSON | P.O. NUMBER | REQUISITIONER | SHIPPED VIA | F.O.B. POINT | TERMS |\n| --- | --- | --- | --- | --- | --- |\n|  | PO-3333 |  |  |  |  |\n\n<table><tr><th>QUANTITY</th><th>DESCRIPTION</th><th>UNIT PRICE</th><th>TOTAL</th></tr><tr><td>1</td><td>Test for 23 fields</td><td>1</td><td>$100.00</td></tr><tr><td></td><td></td><td></td><td></td></tr><tr><td colspan=\"3\">SUBTOTAL</td><td>$100.00</td></tr><tr><td colspan=\"3\">SALES TAX</td><td>$10.00</td></tr><tr><td colspan=\"3\">TOTAL</td><td>$110.00</td></tr><tr><td colspan=\"3\">PREVIOUS BALANCE</td><td>$500.00</td></tr><tr><td colspan=\"3\">TOTAL DUE</td><td>$610.00</td></tr></table>\n\nTHANK YOU FOR YOUR BUSINESS!\n\nREMIT TO:\n\nContoso Billing\n\n123 Remit St\n\nNew York, NY, 10001\n\n> Processed by pdfToMarkdown.dev",
  "pages": 1,
  "request_id": "req_example_invoice"
}

A success always has complete: true. Simple rectangular HTML tables are converted to escaped GFM pipe tables. Complex tables with spans or nested content remain sanitized CommonMark-compatible raw HTML to avoid losing structure.

Required success fields are complete (boolean true), markdown (string), pages (integer delivered page count), and request_id (string). The optional raw field appears only when requested. Validate the entire success before using or writing Markdown.

Error schema

{
  "error": "rate_limited",
  "message": "Free Hacker-tier limit reached (3 requests per minute per IP). Retry shortly, or get a free API key with higher limits at https://pdftomarkdown.dev/auth/github.",
  "request_id": "req_rate123",
  "retry_after_seconds": 60
}

If the complete canonical payload exceeds the response budget, the endpoint fails explicitly:

{
  "error": "response_too_large",
  "message": "The complete OCR result exceeds the response size limit. Set input.max_pages or split the PDF into smaller documents.",
  "docs": "https://pdftomarkdown.dev/docs/",
  "request_id": "req_large123",
  "pages": 25,
  "max_response_bytes": 3500000,
  "response_bytes": 3900000
}

Conversion errors include string fields error, message and request_id. Optional docs links to guidance. retry_after_seconds and Retry-After appear when a retry interval is meaningful. reset_at applies only to an allowance that actually renews.

Credit shortfalls may include integer required_pages, available_pages and missing_pages. Document-limit errors may include max_document_pages, total_pages and selected_pages. Other optional details include accepted_auth, field and provider; see the OpenAPI schema for their types.

Identity and recovery

Allow up to 11 minutes for synchronous processing. A timeout stops waiting, while processing and charging may continue. For pending or uncertain work, retain the exact input, options and identity. Follow retry_same_idempotency_key and new_conversion_required when present; never silently replace an identity after uncertainty or expiry. Reconcile the earlier outcome before deliberately creating new work.

All sources are limited to 50 MiB; original documents may contain at most 1,000 pages. Account results replay for 24 hours using identical input and the same identity.

Status codes

  • 200: converted successfully.
  • 400: invalid request shape.
  • 401: missing or invalid API key.
  • 403: browser-session Origin or CSRF validation failed.
  • 408: PDF upload exceeded its preflight deadline.
  • 422: invalid source URL or unreadable PDF.
  • 413: input exceeds 50 MiB (input_too_large) or complete output exceeds the response limit (response_too_large).
  • 409: pending or failed work, or an identity conflict; follow the error’s recovery fields.
  • 410: draft or retained result expired.
  • 429: rate limit or quota exceeded.
  • 500: unexpected conversion failure.
  • 503: conversion admission, preparation, provider configuration or settlement is temporarily unavailable.
  • 502: upstream OCR worker failed.
  • 504: upstream OCR worker timed out.