Appearance
Render a PDF
POST
/v2/pdf
Renders a PDF from a complete Press document, or from data merged into the template named by template. The response body is the PDF itself.
Authorizations
ApiKeyHeader
Your Papermill API key, sent as an x-api-key header.
Type
API Key (header: x-api-key)
or
BearerAuth
Your Papermill API key, sent as Authorization: Bearer <key>. Equivalent to the x-api-key form.
Type
HTTP (bearer)
Parameters
Query Parameters
template
The template to render or validate against. Required when the body is JSON, CSV, or Markdown; optional when the body is a complete Press document.
Add an @ suffix to pin the content: report@3 for a published version, report@latest for the newest, report@<tag> for the version a tag names, or report@live for the current content, which is also what a bare identifier renders.
Type
string
Examples
"papermill-invoice""papermill-modern-invoice""papermill-modern-letter""papermill-modern-report""papermill-simple-report"template_id
The former name for template, which accepts exactly the same values. Still honoured, with no removal planned, so existing integrations need no change. Sending both names with different values is rejected rather than resolved.
Type
string
flow
With Content-Type: text/markdown, the template flow the body replaces. Defaults to body. Supplying it with any other content type is rejected rather than silently ignored.
Type
string
draft
Set to true to render against your draft allowance instead of your production page allowance. Any other value renders against the production allowance. A draft render carries a DRAFT watermark and is never encrypted or restricted, whatever the template's security settings declare — only a production render applies them.
Type
string
Request Body
XML
Responses
The rendered PDF.
application/pdf
Example
Render a saved template with markdown as the body. The response is the PDF itself, so write the bytes to a file rather than to your terminal.
shell
curl -X POST "https://api.papermill.io/v2/pdf?template=papermill-simple-report" \
-H "Authorization: Bearer $PAPERMILL_API_KEY" \
-H "Content-Type: text/markdown" \
-o report.pdf \
--data-binary @- <<EOF
# Q3 Revenue Summary
Strong quarter overall, driven by add-on adoption.
EOFpython
import os
import requests
response = requests.post(
"https://api.papermill.io/v2/pdf",
params={"template": "papermill-simple-report"},
headers={
"Authorization": f"Bearer {os.environ['PAPERMILL_API_KEY']}",
"Content-Type": "text/markdown",
},
data="# Q3 Revenue Summary\n\nStrong quarter overall.".encode("utf-8"),
)
response.raise_for_status()
with open("report.pdf", "wb") as f:
f.write(response.content)javascript
import fs from 'node:fs/promises'
const response = await fetch('https://api.papermill.io/v2/pdf?template=papermill-simple-report', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PAPERMILL_API_KEY}`,
'Content-Type': 'text/markdown',
},
body: '# Q3 Revenue Summary\n\nStrong quarter overall.',
})
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`)
await fs.writeFile('report.pdf', Buffer.from(await response.arrayBuffer()))A payload should carry only the values that change per render — see Template & Payload for how merging works.