REST API reference
Create and manage PDF templates programmatically — ideal for automation and AI agents: draft a template, preview it, fix validation errors, save it, then generate PDFs on demand.
Authentication
All API requests require an API key. Create and manage keys in the dashboard at API Keys. Include the key in the Authorization header. All responses use the envelope { "success": boolean, ... }. Errors include error and often details — field-level messages agents can act on.
Authorization: Bearer pdfex_...Generate Token
Send your data and template ID to generate a single-use token. This operation is non-blocking and instantaneous.
Endpoint
Request Body
- template_id (string) Required
- data (object) Required JSON data
curl -X POST https://pdfex.io/api/pdf/token \ -H "Authorization: Bearer pdfex_..." \ -H "Content-Type: application/json" \ -d '{
"template_id": "651...",
"data": { "name": "Alice" }
}'Success Response (200 OK)
{
"success": true,
"token": "65eb...",
"url": "/api/pdf/65eb..."
}Retrieve PDF
Use the returned URL or Token to fetch the generated PDF file.
Endpoint
curl -O https://pdfex.io/api/pdf/65eb...PDF links expire 15 minutes after the token is issued.
Endpoints
GET /api/schema returns the same contract as /api/capabilities but is public — no API key. Useful for discovery before you have a key.The design loop
- Draft a template (pdfme JSON or html — see engines below).
- POST /api/templates/preview with sample data → returns pdf_base64.
- Inspect the result; fix validation errors in details.
- POST /api/templates to save → returns template id.
- POST /api/pdf/token with template_id + data, then GET the returned url.
Engine: html (recommended for agents)
HTML templates use Handlebars placeholders, rendered by headless Chromium. Write ordinary HTML + CSS; use {{variable}} for data and {{#each items}}...{{/each}} for repeating rows.
- JavaScript is disabled; external network requests are blocked.
- Images must be inline
data:URIs. - Default page size is US Letter; use CSS
@pageandpage-break-*for pagination. - Variables are auto-extracted from placeholders — no need to list them.
Create example
/api/templates{
"name": "Invoice",
"engine": "html",
"html_template": "<html><head><style>body{font-family:Helvetica,Arial,sans-serif;margin:40px} h1{color:#334} table{width:100%;border-collapse:collapse} td,th{border-bottom:1px solid #ddd;padding:8px}</style></head><body><h1>Invoice {{invoice_number}}</h1><p>Billed to: {{customer_name}}</p><table><tr><th>Item</th><th>Amount</th></tr>{{#each items}}<tr><td>{{description}}</td><td>{{amount}}</td></tr>{{/each}}</table><h2>Total: {{total}}</h2></body></html>",
"sample_data": {
"invoice_number": "INV-001",
"customer_name": "Acme Corp",
"items": [{ "description": "Widget", "amount": "$100.00" }],
"total": "$100.00"
}
}Engine: pdfme (coordinate-based)
pdfme templates place fields at exact positions on the page. All units are millimetres.
Template structure
{
"basePdf": { "width": 215.9, "height": 279.4, "padding": [0, 0, 0, 0] },
"schemas": [
[
{ "name": "title", "type": "text", "position": { "x": 20, "y": 20 }, "width": 170, "height": 12, "fontSize": 24, "alignment": "center" },
{ "name": "body", "type": "text", "position": { "x": 20, "y": 40 }, "width": 170, "height": 60, "fontSize": 11 }
]
]
}basePdf— page dimensions in mm. A4 = 210×297, Letter = 215.9×279.4, Legal = 215.9×355.6. Omit to default to A4.schemas— array of pages; each page is an array of fields with uniquename,type,position,width,height.- Supported types:
text,image,svg,line,rectangle,ellipse,table. text—fontSize(pt),alignment,fontColor(hex).image— value is adata:image/...URI or http(s) URL (fetched server-side).table— value is an array of row arrays; setheadandheadWidthPercentageson the field.
For export/import via the dashboard, see Export & import templates. The API uses the same bundle format with GET /api/templates/:id/export and POST /api/templates/import.
Common validation errors
schemas[0][2] ("logo") has unsupported type "qrcode"Only the listed field types are enabled.
schemas[0][1] requires position {x: number, y: number} in mmEvery pdfme field needs numeric position and size.
html_template failed to compile: ...Malformed Handlebars syntax (e.g. unclosed
{{#each}}).HTTP 401 / 404Missing or revoked API key; or template not found / not visible to your key.