Documentation

RelayPDF API docs

Use this hub to pick the right RelayPDF surface: generate a PDF from HTML, Markdown, a URL, or a published template; screenshot a page; convert Office files; or run PDF tools (merge, protect, stamp, forms). One bearer key covers REST, the official SDKs, the CLI, and MCP. Agents should run relaypdf setup and wait for browser approval instead of asking for a pasted key.

Everything is a POST to https://api.relaypdf.com with a bearer key. The same key covers PDFs, screenshots, converts, and the PDF tools.

Authorization: Bearer pdf_live_…

Keys are created in the dashboard and shown once — only a SHA-256 hash is stored, and query-string keys are not accepted. Coding agents should run relaypdf login and wait for approval in the browser instead of asking a human for a key.

Guides

Quickstart

1. Get a key

terminalCLI
# device flow — approve once in the browser
$ npx @relaypdf/cli setup
# writes RELAYPDF_API_KEY to your env file with mode 0600

2. Make your first PDF

curlshell
curl -X POST https://api.relaypdf.com/v1/pdf \
  -H "Authorization: Bearer pdf_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Invoice #1042</h1><p>Total: $1,200.00</p>",
    "filename": "invoice.pdf"
  }' \
  --output invoice.pdf
index.tsNode
import { RelayPDF } from "@relaypdf/sdk";

const client = new RelayPDF({ apiKey: process.env.RELAYPDF_API_KEY });

const pdf = await client.pdf.fromHtml(
  "<h1>Invoice #1042</h1><p>Total: $1,200.00</p>",
  { filename: "invoice.pdf" },
);

await pdf.save("invoice.pdf");
main.pyPython
import os
from relaypdf import RelayPDF

client = RelayPDF(api_key=os.environ["RELAYPDF_API_KEY"])

pdf = client.pdf.from_html(
    "<h1>Invoice #1042</h1><p>Total: $1,200.00</p>",
    filename="invoice.pdf",
)
pdf.save("invoice.pdf")

Official SDKs: npm i @relaypdf/sdk, pip install relaypdf, Composer, NuGet, and Maven. JSON field names match REST. Full surface: Node.js SDK and Python, PHP, C#, Java.

Endpoint reference

All write endpoints require a bearer key and a JSON body. Every generating endpoint also accepts response: "binary" | "url" | "async".

MethodPathJob
POST/v1/pdfHTML, URL, Markdown, or template → PDF (Chromium)
GET/v1/templatesList stored Handlebars templates
POST/v1/imagesHTML or URL → png / jpeg / webp
POST/v1/pdf/mergeMerge 2–20 PDFs
POST/v1/pdf/extractExtract or split page ranges
POST/v1/pdf/protectPassword-protect (AES-256)
POST/v1/pdf/unlockRemove a user password
POST/v1/pdf/bookmarksAdd outline bookmarks
POST/v1/pdf/rasterPDF pages → png/jpeg (zip if multiple)
POST/v1/pdf/from-imagesPNG/JPEG images → PDF
POST/v1/pdf/stampText or image watermark
POST/v1/pdf/rotateRotate pages (multiple of 90°)
POST/v1/pdf/delete-pagesDelete page ranges
POST/v1/pdf/compressLossless rewrite
POST/v1/pdf/infoPage count and metadata JSON
POST/v1/pdf/textExtract existing text layer (no OCR)
POST/v1/pdf/form/fieldsList AcroForm fields
POST/v1/pdf/form/fillFill and flatten form fields
POST/v1/barcodesBarcode or QR image (PNG or SVG)
POST/v1/zipZip named files
POST/v1/convertLibreOffice / wkhtmltopdf conversion
GET/v1/jobs/:idPoll an async job (same API key)
GET/v1/files/:idPublic 24h download (no key)
GET/v1/accountPlan, rate tier, wallet millicents (not billed)
GET/healthLiveness — { ok: true }
binary

Default. File bytes with x-relaypdf-id, x-relaypdf-size, and content-disposition headers.

url

JSON with id, status, url, filename, sizeBytes, and expiresAt — a public download good for 24 hours.

async

202 with a pollUrl. Poll GET /v1/jobs/:id until completed or failed, or supply a callbackUrl.

CLI and MCP

Install with npx @relaypdf/cli. Credentials live in ~/.config/relaypdf/credentials.json with mode 0600 and are never printed. See CLI, MCP, and n8n.

relaypdf loginDevice-code flow; opens /cli/authorize
relaypdf setup [--env file]Log in if needed, then write env
relaypdf pdf --html|--url|--markdown|--templateChromium PDF
relaypdf templates list|create|publishStored Handlebars templates
relaypdf image --html|--url [--full-page]Screenshot
relaypdf convert <file> --to pdf|docx|xlsx|html|pngLibreOffice / wkhtml
relaypdf merge a.pdf b.pdf …Merge paths or https URLs
relaypdf extract file.pdf --pages 1-3Extract pages
relaypdf protect file.pdf --password …Password-protect
relaypdf barcode --type qr --data '…'Barcode or QR
relaypdf jobs get|wait <id>Async job polling
relaypdf mcpStdio MCP server for Cursor / Claude

Errors are structured JSON

Every failure returns { "error": { "code", "message" } }. Failed requests are never billed. Full table: Errors.

invalid_requestBody failed validation — check field names and types.
payment_requiredWallet balance is empty. Top up or enable auto-reload.
rate_limited429 with Retry-After. Never billed.
account_suspended403 — keys cannot be created or used.
url_not_allowedPrivate, loopback, or metadata hosts are rejected. callbackUrl must be https.
convert_unavailable503 — document worker cold or unreachable. Not billed.

Can't find what you need?

We are happy to review your payload, your page templates, or your whole document pipeline.