Appearance
API Overview
The Papermill API generates PDFs from Press documents, markdown, JSON, and CSV over plain HTTPS. Every endpoint lives under a single base URL:
https://api.papermill.ioTIP
If you have not made a request to Papermill before, the Quickstart walks through your first render end to end. This API section is for looking up exact behaviour once you are building an integration.
- The main Papermill endpoints: render a PDF, validate a payload, verify an API key, and read account usage.
- Errors — the error response shape and the codes you can branch on.
Authentication
Every endpoint requires an API key. Create one from Settings → API keys in the Papermill app.
We support two ways of receiving your API key:
| Header | Example |
|---|---|
Authorization | Bearer pap_live_abc… |
x-api-key | pap_live_abc… |
shell
curl https://api.papermill.io/v2/authcheck \
-H "Authorization: Bearer $PAPERMILL_API_KEY"python
import os
import requests
response = requests.get(
"https://api.papermill.io/v2/authcheck",
headers={"Authorization": f"Bearer {os.environ['PAPERMILL_API_KEY']}"},
)
print(response.json())javascript
const response = await fetch('https://api.papermill.io/v2/authcheck', {
headers: { Authorization: `Bearer ${process.env.PAPERMILL_API_KEY}` },
})
console.log(await response.json())Treat the key as a secret: it carries the full permissions of your account, so keep it server-side rather than in browser or mobile code. If a key is exposed, revoke it from the same settings page and issue a new one — Papermill rejects requests using a revoked key with the ERR_KEY_REVOKED code.
Content types
The POST /v2/pdf and POST /v2/validate endpoints that accept a Press payload decide how to read your request body from the Content-Type header:
Content-Type | Body is treated as |
|---|---|
text/xml, application/xml, text/plain | A complete Press document. |
application/json | Data merged into a template's <data> section. |
text/csv | Tabular data merged into a template's <data> section. |
text/markdown | Markdown placed into one of the template's flows. |
Papermill rejects any other type with a 415 naming the type you sent and the ones it accepts.
The last three carry data rather than a whole document, so they need template_id to say which template to merge into. Without it, Papermill rejects the request with a message, e.g., template_id query parameter is required when posting JSON data. See Template & Payload for how merging works — a payload should carry only the values that change per render, since the template supplies the defaults.
Machine-readable specification
An OpenAPI 3.1 description of the endpoints on this page is published at /openapi.json. Import it into Postman or Insomnia, or generate a client from it:
shell
curl -O https://docs.papermill.io/openapi.jsonBeyond the HTTP API
If you are connecting an AI agent rather than writing an integration by hand, Papermill also runs a Model Context Protocol server that exposes template authoring and rendering as tools. See MCP Server.