API reference
PDFLoom has one endpoint. POST JSON to it and the response body is the PDF.
Authentication
Create an account to get an API key, then send it in the Authorization header:
Authorization: Bearer plk_...
The X-API-Key: plk_... header also works.
POST /v1/pdf
curl https://pdfloom.dev/v1/pdf \
-H "Authorization: Bearer $PDFLOOM_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Invoice #1042</h1><p>Total: $120.00</p>", "format": "A4"}' \
-o invoice.pdf
Body parameters
| Name | Type | Description |
|---|---|---|
html | string | HTML document to render (max 5 MB). Required unless url is set. |
url | string | Public http(s) URL to render. Required unless html is set. |
format | string | A4 (default), Letter, Legal, Tabloid, Ledger, A0–A6. |
width / height | string | Custom page size, such as "4in" or "100mm". Overrides format. |
landscape | boolean | Landscape orientation. Default false. |
margin | string | object | One value for all sides ("20mm") or {"top","right","bottom","left"}. |
printBackground | boolean | Print background colors and images. Default true. |
scale | number | Rendering scale, 0.1–2. Default 1. |
displayHeaderFooter | boolean | Enable headerTemplate and footerTemplate. |
headerTemplate / footerTemplate | string | HTML for the header and footer. Elements with classes pageNumber, totalPages, date, title and url are filled in. Set a font-size, because the default is tiny. |
pageRanges | string | Pages to include, such as "1-3, 5". |
preferCSSPageSize | boolean | Use the size from CSS @page rules instead of format. |
waitUntil | string | load, domcontentloaded, networkidle0 or networkidle2. Default is load for HTML and networkidle2 for URLs. |
emulateMedia | string | print (default) or screen. |
Page numbers in the footer
{
"html": "...",
"margin": {"top": "20mm", "bottom": "20mm"},
"displayHeaderFooter": true,
"footerTemplate": "<div style='font-size:9px;width:100%;text-align:center'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></div>"
}
Responses
| Status | Meaning |
|---|---|
| 200 | Success. Body is application/pdf. The X-Usage header shows this month's usage and quota. |
| 400 | Invalid parameters, or the page failed to render. JSON body: {"error": "..."} |
| 401 | Missing or invalid API key. |
| 429 | Monthly quota reached. Upgrade or wait for the next month. |
POST /v1/invoice
Generates an invoice, receipt, quote or estimate PDF from JSON, with no HTML needed. See the invoice API reference.
GET /v1/usage
Returns {"plan": "free", "used": 12, "quota": 100, "month": "2026-10"}.
Tips
- Use absolute URLs for images, stylesheets and fonts, or inline them as data URIs.
- Control page breaks with CSS:
break-before: page,break-inside: avoid. - Set the page size and margins in CSS with
@page { size: A4; margin: 15mm }andpreferCSSPageSize: true. - Rendering times out after 30 seconds.