# makesPDF > Beautiful PDFs from your data. Send JSON or Markdown, get a compliant PDF > back. Designed to be driven by AI agents — there is a dedicated skill file > that teaches any LLM how to author PDF templates. > **URLs in this document are HTTP URLs, not filesystem paths.** If you need > to re-fetch the skill file later, use a web fetch / HTTP tool — do not > call your filesystem `Read` tool with `/skills/pdf-template-author.md`. > The full URL is always `https://makespdf.com/skills/pdf-template-author.md`. ## When to use makesPDF Use makesPDF for: - Turning structured data (invoices, receipts, quotes, statements, reports) into a PDF through a template: POST https://makespdf.com/api/v1/render with a library templateId or inline DSL, plus data. - Converting Markdown (GFM tables, code blocks, Mermaid diagrams, LaTeX math, alerts) to a PDF: POST https://makespdf.com/api/v1/md. - Any PDF that must be accessible or archival: every render is tagged and PDF/A-2A + PDF/UA-1 dual-compliant by default (EAA, ADA Title II, Section 508). - Making an existing PDF accessible: POST https://makespdf.com/api/v1/enhance (async, queue-backed; poll the returned statusUrl). - Checking whether a PDF is PDF/A-2A / PDF/UA-1 compliant: POST https://makespdf.com/api/v1/pdf/validate (free, no auth). - Agents without an account: pay per call in USDC via x402 on /api/v1/markdown and /api/v1/render. Do not use makesPDF for: - Right-to-left and complex-script text (Arabic, Hebrew, Persian, Indic, Thai, Khmer): these do not render correctly yet. - Printing an existing web page or arbitrary HTML/CSS to PDF: there is no browser engine; input is Markdown or the template DSL. - Editing, merging or splitting existing PDFs: enhance adds structure and metadata or regenerates, it does not edit content. How to call it: Read https://makespdf.com/skills/pdf-template-author.md before authoring a template. Draft free with POST /api/v1/preview, then render with POST /api/v1/render. Authenticate with the OAuth device flow (https://makespdf.com/skills/pdf-auth.md) or pay per call with x402. MCP hosts can use https://makespdf.com/api/v1/mcp instead of REST. ## API contract: errors, rate limits, versioning - Errors are JSON with a required `error` message (schema `Error` in https://makespdf.com/openapi.json). Branch on the HTTP status. - Responses carry IETF `RateLimit` / `RateLimit-Policy` headers; a 429 carries `Retry-After`, which wins. Details: https://makespdf.com/docs/api#rate-limits - The version is in the path (`/api/v1`). v1 only changes additively. A retired endpoint keeps working for at least 90 days while sending `Deprecation` and `Sunset` headers. Policy: https://makespdf.com/docs/api#versioning ## Quick links for AI agents - AI & Agent landing (production): https://ai.makespdf.com/ - Documentation index: https://makespdf.com/docs - Skill file (single source of truth for the template DSL): https://makespdf.com/skills/pdf-template-author.md - Companion skills (fetch on demand from the same origin): - Authentication / OAuth device flow: https://makespdf.com/skills/pdf-auth.md - API endpoints (preview / render / validate): https://makespdf.com/skills/pdf-api.md - Per-doc-type recipes: https://makespdf.com/skills/pdf-recipes.md - Custom font uploads: https://makespdf.com/skills/pdf-fonts.md - Server-side application integration (API key, error handling, per-language snippets): https://makespdf.com/skills/pdf-integration.md - Versioned per-document-type skills (fetch the one matching your document; each names its canonical registry fields, library template, and a worked fetch-fill-render example): - Invoice: https://makespdf.com/skills/library/invoice-v1.md - Receipt: https://makespdf.com/skills/library/receipt-v1.md - Quote / Estimate: https://makespdf.com/skills/library/quote-v1.md - Purchase Order: https://makespdf.com/skills/library/purchase-order-v1.md - Statement of Account: https://makespdf.com/skills/library/statement-v1.md - Full index: https://makespdf.com/skills/library/ - API reference: https://makespdf.com/docs/api - Agent setup walkthrough: https://makespdf.com/docs/ai-setup - App integration recipes (backend render, hosted MCP, Vercel AI SDK tools): https://makespdf.com/docs/integrate - Agent discovery (every machine-readable surface in one page): https://makespdf.com/docs/discovery - Every docs page, with its markdown twin: see "Docs" below - Model benchmark digest (which LLMs author makesPDF templates well, with failing-DSL snippets for diagnosis): https://makespdf.com/ai/benchmark.md Structured companion (same data, JSON shape, no DSL snippets): https://makespdf.com/ai/benchmark.json - CLI (`@makespdf/cli` on npm): https://github.com/makesPDF/makespdf-cli ## Docs Every page below exists as HTML and as a markdown twin. Prefer the markdown twin when you are reading for content: it is the same material with no markup to strip. Both forms are also served by content negotiation — send `Accept: text/markdown` to the HTML URL and you get the twin. The docs index itself is markdown only: [https://makespdf.com/docs](https://makespdf.com/docs) - [Getting Started](https://makespdf.com/docs/getting-started): Account setup, an API key, a first template, a first render, and the Markdown shortcut. Markdown twin: [getting-started.md](https://makespdf.com/docs/getting-started.md) - [Markdown to PDF](https://makespdf.com/docs/markdown): Every option, supported Markdown feature and limit of POST /api/v1/md. Markdown twin: [markdown.md](https://makespdf.com/docs/markdown.md) - [Template DSL](https://makespdf.com/docs/dsl): The compact builder DSL: building blocks, loops and conditionals, helpers, styling, a complete example. Markdown twin: [dsl.md](https://makespdf.com/docs/dsl.md) - [API Reference](https://makespdf.com/docs/api): Every /api/v1 endpoint: auth, request/response shapes, errors, rate limits and versioning. Markdown twin: [api.md](https://makespdf.com/docs/api.md) - [MCP server](https://makespdf.com/docs/mcp): The streamable-HTTP MCP server: tools, client setup, verification and limits. Markdown twin: [mcp.md](https://makespdf.com/docs/mcp.md) - [Bring your own AI](https://makespdf.com/docs/ai-setup): Install the skill file, authenticate an agent with the device flow, and drive the preview API. Markdown twin: [ai-setup.md](https://makespdf.com/docs/ai-setup.md) - [Integrate makesPDF into your app](https://makespdf.com/docs/integrate): Three copy-paste recipes: backend render, hosted MCP, and Vercel AI SDK tools. Markdown twin: [integrate.md](https://makespdf.com/docs/integrate.md) - [Agent discovery](https://makespdf.com/docs/discovery): Every machine-readable surface in one place. Markdown twin: [discovery.md](https://makespdf.com/docs/discovery.md) - [Fonts & Colour Emoji](https://makespdf.com/docs/fonts): Embedded families, per-character fallback, CJK, colour emoji, custom fonts and licences. Markdown twin: [fonts.md](https://makespdf.com/docs/fonts.md) - [Server-side integration](https://makespdf.com/docs/integration) (markdown only): Wiring makesPDF into an application: API-key setup, storing templateIds, error handling, retry policy, per-language snippets. ## Discovery (for runtimes, crawlers, and audits) No human linking required. Every surface below is served from this same origin — replace the host when you call staging or a local dev server. - Skill (canonical): https://makespdf.com/skills/pdf-template-author.md - Skill pointer (conventional path, 302 to the canonical file): https://makespdf.com/skill.md - Agent manifest (skill + OpenAPI + MCP + x402 in one JSON): https://makespdf.com/.well-known/agents.json - OpenAPI 3.1 (+ x402 annotations): https://makespdf.com/openapi.json (alias: https://makespdf.com/api/v1/openapi.json) - MCP server (Streamable HTTP): https://makespdf.com/api/v1/mcp - x402 paid-endpoint manifest: https://makespdf.com/.well-known/x402 - Contact / trust (RFC 9116): https://makespdf.com/.well-known/security.txt - Crawler policy (explicit AI-crawler stanzas): https://makespdf.com/robots.txt - Docs index (markdown): https://makespdf.com/docs Human-readable explainer: https://makespdf.com/docs/discovery. ## Authentication (read this first) All /api/v1/* endpoints need a Bearer token by default. Carve-outs exist (full policy at https://makespdf.com/docs/api): the public veraPDF utility at `POST /api/v1/pdf/validate` and — when the operator enables the `promo:md_anonymous_enabled` flag — `POST /api/v1/md` and `POST /api/v1/canvas` (JSON Canvas boards) themselves. The anonymous carve-out is rate-limited per IP (60/hour, 200/day, 20 pages per render) and intended for low-volume callers (IDE plugins, quick scripts, demos). Authenticate anyway for higher limits, artifact capture, and the rest of the API. Stale / invalid Bearer tokens always 401 — the server never silently downgrades a failed auth attempt to anonymous. Canvas is not x402-payable: a PAYMENT-SIGNATURE header on an unauthenticated canvas request gets the standard 401. There are two paths to get a Bearer token; **AI agents should use the device flow — never ask the user for a password or API key directly, and never register an account or sign in on the user's behalf.** If the device approval page (https://makespdf.com/device?code=…) shows a login screen when you open it in a browser MCP, you are done with the browser. Hand control back to the user so they can sign in themselves — the account owner is the human whose credits get charged, and the approval must be their decision, not yours. Do not fill the registration form, do not auto-submit credentials you scraped from earlier messages. Just poll /api/v1/device/token and wait. ### Device authorization flow (preferred for AI agents and CLIs) OAuth 2.0 RFC 8628. The user authenticates in their browser; you receive a token without ever touching their credentials. 1. `POST https://makespdf.com/api/v1/device/code` (no auth required, optional body `{ "client_name": "My Agent" }`). Response: ```json { "device_code": "", "user_code": "ABCD-1234", "verification_uri": "https://makespdf.com/device", "verification_uri_complete": "https://makespdf.com/device?code=ABCD-1234", "expires_in": 600, "interval": 5 } ``` 2. **Tell the user:** "Open https://makespdf.com/device?code=ABCD-1234 in your browser and approve this device." Show both the URL and the user_code so they can verify it matches what's shown in the browser. 3. **Wait for the user to approve**, then make **one** request: `POST https://makespdf.com/api/v1/device/token` with `{ "device_code": "..." }`. On success you get HTTP 200 `{ "access_token": "mpdf_...", "token_type": "Bearer" }`. Save the access_token; that's the user's API key. *Automated harnesses* with no interactive user (CI, scripted demos) may fall back to polling every `interval` seconds — HTTP 400 `{ "error": "authorization_pending" }` means keep waiting. But when a human is present, ask them to confirm before calling. 4. Use `Authorization: Bearer ` on every subsequent request. ### API key (for humans setting up CI or scripting their own account) Generate at https://makespdf.com/settings/api-keys. Same Bearer token format. ## Privacy and telemetry Each authenticated or wallet-paid `/md`, `/canvas`, `/markdown`, and `/render` call records one usage row (endpoint, sizes, page count, timing, identity; never values or text). `/render` adds a privacy-preserving shape signal: an unkeyed hash of the `data` object's key structure and value types, plus its top-level keys. `/md` and `/markdown` record no data-shape signal. Every render also records a structural fingerprint of the input: counts and sizes only, never text, but specific enough to match against a candidate document. `/preview` and anonymous renders write no usage row. The MCP endpoint (`POST /api/v1/mcp`) records the same usage rows for its billed tools — `render_template` like `/render`, `render_markdown` like `/md` — and none for the free `render_dsl_preview` (like `/preview`); every MCP request also logs the tool name, outcome and timing, plus the client name/version an `initialize` handshake declares. Full disclosure: https://makespdf.com/privacy-for-agents. Opt out of the shape signal and the fingerprint per request with header `X-No-Telemetry: true` (payment records are still written, and failed renders keep their fingerprint). The MCP `report_feedback` tool stores the model-written summary as submitted, linked to the account, for 180 days; the tool asks the model not to include document content, but we cannot guarantee it complies. ## Quickstart: I have JSON data, I want a PDF Three paths, cheapest first. All require a Bearer token (see Authentication above). 1. **Markdown → PDF** (simplest, about a second, no AI call). Format your data as GitHub Flavored Markdown, POST to `/api/v1/md`: ``` curl -X POST https://makespdf.com/api/v1/md \ -H "Authorization: Bearer $MAKESPDF_API_KEY" \ -H "Content-Type: application/json" \ -d '{"markdown": "# Invoice #123\n\n| Item | Price |\n|---|---|\n| Widget | $10 |"}' \ -o invoice.pdf ``` 2. **DSL → PDF** (custom layouts, about a second, no AI call). Read the skill file, write a short JavaScript DSL snippet, POST to `/api/v1/preview`: ``` curl -X POST https://makespdf.com/api/v1/preview \ -H "Authorization: Bearer $MAKESPDF_API_KEY" \ -H "Content-Type: application/json" \ -d '{"dsl": "const template = doc(...); const sampleData = {...};", "data": {...}}' \ -o invoice.pdf ``` 3. **AI-generated template** (one-shot, ~20s). If the agent can't author a template itself, POST to `/api/v1/render` with a document type and data and the server will generate + render in one call. Details at https://makespdf.com/docs/api. **Always read the skill file first for path 2.** It is ~25KB and teaches the full DSL, document recipes (invoice, receipt, quote, report, CV, etc.), style properties, and worked examples. ## Endpoints - POST /api/v1/device/code — Start OAuth device flow (no auth required) - POST /api/v1/device/token — Poll for access_token (no auth required) - POST /api/v1/md — Markdown to PDF (no AI call, about a second; anonymous-callable when promo:md_anonymous_enabled is set) - POST /api/v1/canvas — JSON Canvas board to PDF (no AI call; same anonymous carve-out; not x402-payable) - POST /api/v1/preview — Render a DSL template with data - POST /api/v1/render — One-shot AI generation + render (~20s) - POST /api/v1/md/validate — Pre-flight accessibility check for markdown - POST /api/v1/preview/validate — Pre-flight structure + a11y check for templates All /api/v1/* endpoints except the device-flow pair require Bearer token (API key) or a session cookie. Unauthenticated calls return a 401 whose body includes a `device_authorization` block with the exact steps above, plus `agent_guide` and `skill` URLs so agents can self-recover. ## Pay-per-call (x402) — for agents without an account Agents and wallets that don't have a Bearer token can pay per request in USDC on Base mainnet. No signup, no API key, no session — just a signed EIP-3009 authorization on each call. This implements the [x402 spec](https://www.x402.org/) v2 wire format. **Pricing (production, Base mainnet `eip155:8453`):** - POST /api/v1/markdown — $0.01 per render (USDC, 6 decimals → atomic `10000`). **Wallet callers should use this one.** An unauthenticated POST always returns a 402 challenge. - POST /api/v1/md — $0.01 per render. Identical pipeline, options and price, but it also honours a free anonymous promo, so an unauthenticated POST may return a PDF (200) or a 401 rather than a 402. Fine to call if you already hold a Bearer token; unreliable as a payment entry point. - POST /api/v1/render — $0.02 per render (inline `{ dsl, data }` body only; `{ templateId }` is not available to wallet callers in v1) `/api/v1/preview`, validation, and the template / font / library endpoints are not paid-callable — use a Bearer token for those. **Flow:** 1. Send the request with no auth. Server replies HTTP **402 Payment Required** with a JSON body that advertises what to pay: ```json { "x402Version": 2, "error": "Payment required", "resource": { "url": "https://makespdf.com/api/v1/markdown", "description": "Convert GitHub-flavoured Markdown to a tagged, accessible PDF.", "mimeType": "application/pdf", "serviceName": "makesPDF", "tags": ["pdf", "markdown", "accessibility", "pdf-ua", "pdf-a"] }, "accepts": [ { "scheme": "exact", "network": "eip155:8453", "amount": "10000", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "payTo": "0x9bB96Acb3fD11D8949D862736B96e7e12D319DC4", "maxTimeoutSeconds": 60, "extra": { "name": "USD Coin", "version": "2" } } ], "extensions": { "bazaar": { "info": {}, "schema": {} } }, "docs": "https://makespdf.com/docs/api", "agent_guide": "https://makespdf.com/llms.txt", "skill": "https://makespdf.com/skills/pdf-template-author.md" } ``` This is the x402 **v2** body shape: a top-level `resource` object, an `accepts` array of payment requirements, and an `extensions.bazaar` discovery object (abbreviated above — it carries the endpoint's input `info` + JSON `schema`). 2. Build an EIP-3009 `transferWithAuthorization` payload paying `payTo` the advertised `amount` of the advertised `asset`, sign it, base64-encode the JSON `PaymentPayload`, and resend the original request with header `PAYMENT-SIGNATURE: `. Echo the 402's `resource` and `extensions` back in the payload so the settlement is cataloged for discovery. 3. Server verifies + settles via the Coinbase CDP facilitator (`https://api.cdp.coinbase.com/platform/v2/x402`), then renders. Response is the PDF bytes plus header `X-PAYMENT-RESPONSE` carrying the settlement receipt. 4. **Idempotency.** Resending the same `PAYMENT-SIGNATURE` within 5 minutes returns the cached PDF bytes verbatim with header `X-Idempotent-Replay: 1`. No double settlement, safe to retry on network failure. 5. **Refunds.** If verification succeeds but rendering fails, the payment is marked `failed` and processed off-band as a refund to the payer wallet. No automatic retry. **Rate limits.** Wallet callers are rate-limited by payer address (`wallet:0x…`) at the same per-endpoint thresholds as authed callers. **Watermark.** Paid renders are watermark-free by construction. **Discovery (for indexes and crawlers).** This endpoint set is also auto-discoverable via Coinbase Bazaar; no submission step is required. For the full spec, scheme negotiation, and SDK pointers see [x402.org](https://www.x402.org/).