Smart Templates
Design PDF layouts as React components, save them as templates, then render documents by passing JSON data. No HTML string concatenation needed.
How it works
- Write a React component that receives your data as props
- Save it as a named template via the API or the dashboard editor
- Call
POST /v1/renderwith the template name and your data - Get back a PDF — same options as the convert endpoint
Creating a template
POST https://api.pdfrelay.com/v1/templates
{
"name": "monthly-invoice",
"description": "Standard monthly invoice",
"environment": "live",
"jsx": "function LineItem({ item, index }) {\n const bg = index % 2 === 0 ? '#fff' : '#F9FAFB';\n return (\n <tr style={{ backgroundColor: bg }}>\n <td style={{ padding: '10px 8px' }}>{item.description}</td>\n <td style={{ textAlign: 'right', padding: '10px 8px' }}>\n ${item.price.toFixed(2)}\n </td>\n </tr>\n );\n}\n\nexport default function Invoice({ company, client, items, total }) {\n return (\n <div style={{ fontFamily: 'sans-serif', padding: 40 }}>\n <h1>{company.name}</h1>\n <p>Bill to: {client.name}</p>\n <table>\n <tbody>\n {items.map((item, i) => (\n <LineItem key={i} item={item} index={i} />\n ))}\n </tbody>\n </table>\n <p style={{ fontWeight: 'bold' }}>Total: ${total.toFixed(2)}</p>\n </div>\n );\n}"
}Writing templates
Templates are standard React components with a few rules:
- 1Must have a
export defaultfunction component - 2Props come from the
dataobject you pass at render time - 3You can define helper components and functions in the same file
- 4Use
classNameinstead ofclass, and inline styles as objects
Available globals
Templates run in a sandboxed environment. These globals are available:
ReactObjectArrayStringNumberBooleanJSONMathDateMapSetparseIntparseFloatisNaNisFiniteRendering a template
Pass the template name and your data as JSON:
POST https://api.pdfrelay.com/v1/render
{
"template": "monthly-invoice",
"data": {
"company": { "name": "Acme Corp" },
"client": { "name": "Jane Smith" },
"items": [
{ "description": "Web Design", "price": 2500 },
{ "description": "Hosting", "price": 199.99 }
],
"total": 2699.99
},
"options": {
"page_size": "A4"
}
}Response:
{
"id": "conv_kP3xNqWm",
"status": "completed",
"document_id": "doc_8c2ef1a3",
"page_count": 1,
"duration_ms": 67,
"template": "monthly-invoice",
"template_version": 3
}The response includes which template version was used, so you can trace exactly what produced each PDF.
Versioning
Every time you update a template, the version number increments automatically. The render response tells you which version was used. You can update templates at any time without redeploying your application — the next render will use the latest version.
Managing templates
Templates can be managed via the API or the dashboard template editor, which includes a live preview, test data editing, and a syntax guide.
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/templates | List all templates |
| POST | /v1/templates | Create a template |
| GET | /v1/templates/:id | Get a template by ID |
| PUT | /v1/templates/:id | Update a template (bumps version) |
| DELETE | /v1/templates/:id | Deactivate a template |
| POST | /v1/render | Render a template to PDF |
Environments
Each template has an environment ("test" or "live"). Test templates can only be rendered with test API keys, and live templates with live keys. This lets you safely iterate on layouts without affecting production.