Templates
Design invoices, receipts, labels and certificates once in the dashboard, then create PDFs by sending JSON.
- Build or customise a template under Templates in the dashboard. Starters are available for invoices, quotes, receipts, utility bills, shipping labels, packing slips, certificates and letters.
- Each template has fields. A field's key is the JSON property you send, for example
invoice_numberorcustomer.name. - Render with
POST /templates/{template_id}/render. Each successful render uses one PDF credit, the same as/quickjob.
Quick Example
curl -X POST https://api.podpdf.com/templates/01J8ZK3QW5V7N2B4X6C8D0E2F4/render \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"data": {
"invoice_number": "INV-1042",
"issue_date": "2026-09-13",
"customer": { "name": "Acme Ltd", "address": "1 Main St\nSpringfield" },
"items": [
{ "description": "Design work", "quantity": 10, "unit_price": 85 },
{ "description": "Hosting", "quantity": 1, "unit_price": 20 }
],
"tax_rate": 20
}
}' \
--output INV-1042.pdf
The totals, currency formatting, page numbers and table headers on every page all come from the template, so you only send the values.
Open a template and click Use via API. It shows the endpoint for that template and an example body with every field, in cURL, JavaScript and Python.
Authentication
Required. Send an API key or a dashboard ID token:
X-API-Key: your_api_key_here
Request
Endpoint
POST https://api.podpdf.com/templates/{template_id}/render
Body
| Field | Type | Required | Description |
|---|---|---|---|
data | object | Yes | Values for the template's fields. Nested keys such as customer.name are nested objects. List fields are arrays of objects. Extra keys are ignored. Up to 1 MB. |
store | boolean | No | true stores the PDF and returns a download link (valid for 1 hour) instead of the file |
filename | string | No | File name for the Content-Disposition header |
Value formats
| Field type | Send | Example |
|---|---|---|
| Text, Multi-line text | string (numbers are accepted) | "Acme Ltd", "Line 1\nLine 2" |
| Number | number or numeric string | 12.5 |
| Money amount | number, in the template currency | 1234.56 → $1,234.56 or 1.234,56 € |
| Percentage | number, where 20 means 20% | 20 |
| Date | ISO date | "2026-09-13" |
| Image URL | public https:// URL (PNG or JPEG, up to 2 MB) or data:image/…;base64,… | "https://cdn.example.com/logo.png" |
| List | array of objects | [{ "description": "Design", "quantity": 2 }] |
Response
Success (default)
200 OK with the PDF as the body.
| Header | Description |
|---|---|
Content-Type | application/pdf |
X-Job-Id | Job ID, visible in GET /jobs |
X-PDF-Pages | Number of pages |
Success with store: true
{
"job_id": "3f5c2a7e-8b1d-4c9e-a2f4-6d7e8f9a0b1c",
"template_id": "01J8ZK3QW5V7N2B4X6C8D0E2F4",
"pages": 2,
"truncated": false,
"download_url": "https://…",
"download_url_expires_at": "2026-09-13T13:00:00.000Z"
}
Invalid data
Every problem is listed so you can fix them all at once. Nothing is charged.
{
"error": {
"code": "TEMPLATE_DATA_INVALID",
"message": "The data does not match the template fields",
"details": {
"errors": [
{ "field": "invoice_number", "error": "is required" },
{ "field": "items[1].quantity", "error": "must be a number" },
{ "field": "customer.logo_url", "error": "must be an https URL or a base64 data:image URI" }
]
}
}
}
Other errors
| Status | Code | Meaning |
|---|---|---|
| 400 | TEMPLATE_DATA_TOO_LARGE | data is over 1 MB |
| 400 | PAGE_LIMIT_EXCEEDED | The document has more pages than your limit |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | INSUFFICIENT_CREDITS, RATE_LIMIT_EXCEEDED | Same as /quickjob |
| 404 | TEMPLATE_NOT_FOUND | Wrong ID, or the template belongs to another account |
| 408 | QUICKJOB_TIMEOUT | Rendering took longer than 30 seconds |
See Error handling for retries.
Page sizes
Page size, orientation and margins are part of the template, so the same JSON always produces the same layout.
| Preset | Size |
|---|---|
| A3, A4, A5 | ISO sizes |
| US Letter, US Legal | 8.5 × 11 in, 8.5 × 14 in |
| Receipt 80 mm, Receipt 58 mm | Thermal roll widths; the length follows the content |
| Shipping label 4 × 6 in | 101.6 × 152.4 mm |
| Custom | Any width 25–1200 mm and height 25–2000 mm, or automatic length |
Managing templates from code
The dashboard is the usual way to create and edit templates. The management routes need a dashboard ID token rather than an API key:
| Method | Path | Purpose |
|---|---|---|
GET | /templates | List your templates |
GET | /templates/{template_id} | Get a template and its definition (including fields) |
POST | /templates | Create from a definition or from a starter ({ "from_starter": "invoice-a4" }) |
PUT | /templates/{template_id} | Replace the definition (expected_version prevents overwriting someone else's edit) |
DELETE | /templates/{template_id} | Delete |
GET | /templates/library | List starters |