v1
API reference
Authenticate with a bearer API key. Every generating endpoint returns a binary file by default, or JSON with a 24-hour download URL.
Agent setup
Do not paste a key. Have the agent run the CLI; you only approve in the browser.
pnpm --filter @relaypdf/cli relaypdf setup --env .env.localSDKs
Official clients live in this repo: Node @relaypdf/sdk and Python relaypdf. Same endpoints as this page.
import { RelayPDF } from "@relaypdf/sdk";
const client = new RelayPDF({ apiKey: process.env.RELAYPDF_API_KEY });
const pdf = await client.pdf.fromHtml("<h1>Hello</h1>");
await pdf.save("hello.pdf");from relaypdf import RelayPDF
client = RelayPDF(api_key="pdf_live_...")
client.pdf.from_html("<h1>Hello</h1>").save("hello.pdf")Authentication
Send Authorization: Bearer pdf_live_.... Keys are hashed at rest. Local development uses pdf_dev_... from apps/api/.dev.vars.
POST /v1/pdf
Provide exactly one of html, url, or markdown.
{
"html": "<html><body><h1>Statement</h1></body></html>",
"filename": "statement.pdf",
"response": "binary",
"options": {
"format": "letter",
"printBackground": true,
"margin": { "top": "0.5in", "right": "0.5in", "bottom": "0.5in", "left": "0.5in" }
}
}{
"markdown": "# Invoice 1042\n\n**Total:** $480.00",
"filename": "invoice.pdf"
}POST /v1/images
Screenshot HTML or a public URL. Types: png (default), jpeg, webp.
{
"url": "https://example.com",
"options": { "type": "png", "fullPage": true, "viewport": { "width": 1280, "height": 720 } }
}PDF tools
POST /v1/pdf/merge, /extract, /protect, /bookmarks. Each input file is a public URL or base64 file.
{
"files": [
{ "url": "https://example.com/cover.pdf" },
{ "url": "https://example.com/body.pdf" }
],
"filename": "pack.pdf"
}POST /v1/barcodes
QR, Code 128, Code 39, EAN-13, UPC-A, PDF417, Data Matrix. PNG or SVG.
{
"type": "qr",
"text": "https://example.com/order/1042",
"format": "png"
}POST /v1/zip
Bundle named files. Each entry needs filename plus url or file.
POST /v1/convert
LibreOffice (default) converts Office, images, and email to PDF, HTML to Docx/Xlsx, PDF to HTML, and thumbnails ( to: "png"). Set engine: "wkhtmltopdf" for the compatibility HTML/URL → PDF engine. Chromium remains POST /v1/pdf.
{
"file": "UEsDBBQ...",
"sourceFilename": "letter.docx",
"to": "pdf"
}PDF options
| Field | Default | Notes |
|---|---|---|
| format | letter | letter, legal, tabloid, ledger, a0–a6 |
| landscape | false | Rotate the page |
| printBackground | true | Include CSS backgrounds |
| margin | — | CSS units such as 0.5in or 12mm |
| headerTemplate / footerTemplate | — | HTML; enables header/footer |
| waitUntil | networkidle0 | load, domcontentloaded, networkidle0/2 |
| timeout | 30000 | Milliseconds, max 60000 |
Errors
Errors are JSON. Failed operations and rate-limited requests are not billed. Trial wallets: 20 operations/minute and 5 every 10 seconds. After a Stripe top-up or auto-reload: 60/minute. Insufficient balance returns 402 payment_required. Downloads: 60/minute per IP.
{
"error": {
"code": "invalid_request",
"message": "Provide exactly one of `html`, `url`, or `markdown`."
}
}Async and webhooks
Set response: "async" to get 202 and poll GET /v1/jobs/:id. Optional callbackUrl receives a JSON POST for that job. Register signed account webhooks in the dashboard.
{
"file": "UEsDB...",
"sourceFilename": "letter.docx",
"to": "pdf",
"response": "async",
"callbackUrl": "https://example.com/relaypdf"
}