Skip to main content

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_number or customer.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.

Copy the request from the dashboard

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

Learn about authentication →

Request

Endpoint

POST https://api.podpdf.com/templates/{template_id}/render

Body

FieldTypeRequiredDescription
dataobjectYesValues 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.
storebooleanNotrue stores the PDF and returns a download link (valid for 1 hour) instead of the file
filenamestringNoFile name for the Content-Disposition header

Value formats

Field typeSendExample
Text, Multi-line textstring (numbers are accepted)"Acme Ltd", "Line 1\nLine 2"
Numbernumber or numeric string12.5
Money amountnumber, in the template currency1234.56$1,234.56 or 1.234,56 €
Percentagenumber, where 20 means 20%20
DateISO date"2026-09-13"
Image URLpublic https:// URL (PNG or JPEG, up to 2 MB) or data:image/…;base64,…"https://cdn.example.com/logo.png"
Listarray of objects[{ "description": "Design", "quantity": 2 }]

Response

Success (default)

200 OK with the PDF as the body.

HeaderDescription
Content-Typeapplication/pdf
X-Job-IdJob ID, visible in GET /jobs
X-PDF-PagesNumber 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

StatusCodeMeaning
400TEMPLATE_DATA_TOO_LARGEdata is over 1 MB
400PAGE_LIMIT_EXCEEDEDThe document has more pages than your limit
401UNAUTHORIZEDMissing or invalid API key
403INSUFFICIENT_CREDITS, RATE_LIMIT_EXCEEDEDSame as /quickjob
404TEMPLATE_NOT_FOUNDWrong ID, or the template belongs to another account
408QUICKJOB_TIMEOUTRendering 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.

PresetSize
A3, A4, A5ISO sizes
US Letter, US Legal8.5 × 11 in, 8.5 × 14 in
Receipt 80 mm, Receipt 58 mmThermal roll widths; the length follows the content
Shipping label 4 × 6 in101.6 × 152.4 mm
CustomAny 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:

MethodPathPurpose
GET/templatesList your templates
GET/templates/{template_id}Get a template and its definition (including fields)
POST/templatesCreate 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/libraryList starters