Guide
Save a template once, then render by template ID
Use this guide when your document layout stays stable and only business data changes. The examples move from the smallest useful template render to a more realistic production request and then to a version-pinned, accepted-work path.
POST/v1/pdf
Recommended path
- Start with the smallest saved template and one successful render.
- Move to a realistic data object with stable identifiers and output settings.
- Add version pinning and accepted follow up only when you need deterministic history.
Template auth
Template create, update, and version routes use bearer auth.
Render auth
Template execution uses X-API-Key on the single render create route.
Guide spectrum
This page shows one easiest path, one realistic path, and one advanced path.
Before You Begin
Confirm credentials and template variables first
This workflow crosses template management and render execution. Verify both surfaces before coding the request builder.
01
Bearer access for templates
You need bearer auth access to save, inspect, and version templates under the templates user surface.
GET/user/templates
02
Render API key for execution
The render call uses the render API key model on the single render create route.
POST/v1/pdf
03
Variable names mapped to your template
The runtime data object must match the variable names in the saved template content.
Easiest Path
Save one tiny template and render it once
Start with the smallest useful version of the workflow: one saved template, one small dataobject, and one successful render.
curl -X POST "https://api.solidrelay.io/user/templates" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "receipt-basic",
"content": "<h1>Receipt {{receiptNumber}}</h1><p>{{customerName}}</p><p>{{total}}</p>",
"sampleData": "{\"receiptNumber\":\"R-1001\",\"customerName\":\"Ava Chen\",\"total\":\"24.00\"}"
}'curl -X POST "https://api.solidrelay.io/v1/pdf" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "2a2bc604-feb7-41b5-8e2c-2e2784ecb67d",
"data": {
"receiptNumber": "R-1001",
"customerName": "Ava Chen",
"total": "24.00"
},
"output": "binary"
}'- Store the returned UUID
templateId. Render requests use the ID, not the template name. - Keep this first run small so you can validate auth, variable names, and success handling quickly.
- Use the templates reference for the exact request and response contract.
Realistic Path
Render with richer business data and stable output settings
This is the version most teams ship first: a reusable template ID, nested business data, and explicit output behavior that stays stable across environments.
curl -X POST "https://api.solidrelay.io/user/templates" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "invoice-default",
"content": "<h1>Invoice {{invoice.number}}</h1><p>{{customer.name}}</p><p>{{customer.email}}</p><p>{{totals.grand}}</p>",
"sampleData": "{\"invoice\":{\"number\":\"INV-2026-0042\"},\"customer\":{\"name\":\"Acme Corp\",\"email\":\"ap@acme.test\"},\"totals\":{\"grand\":\"245.00\"}}"
}'curl -X POST "https://api.solidrelay.io/v1/pdf" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Idempotency-Key: invoice-2026-0042" \
-H "Content-Type: application/json" \
-d '{
"templateId": "2a2bc604-feb7-41b5-8e2c-2e2784ecb67d",
"data": {
"invoice": {
"number": "INV-2026-0042",
"issuedAt": "2026-04-10"
},
"customer": {
"name": "Acme Corp",
"email": "ap@acme.test"
},
"totals": {
"subtotal": "225.00",
"tax": "20.00",
"grand": "245.00"
}
},
"output": "url",
"filename": "invoice-2026-0042.pdf"
}'- Send exactly one input source. Do not combine
templateIdwith inline HTML or a source URL. - Use an
Idempotency-Keywhen your client may retry the create request. - Keep the template stable and let the runtime
dataobject carry the business variation.
Advanced Path
Pin a template version and continue through accepted follow up
Use this path for approval-sensitive or audit-stable output. The render request stays small, but now you pin one historical version and handle the accepted job lifecycle end to end.
curl -X POST "https://api.solidrelay.io/v1/pdf" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Idempotency-Key: invoice-2026-0042-v7" \
-H "Content-Type: application/json" \
-d '{
"templateId": "2a2bc604-feb7-41b5-8e2c-2e2784ecb67d",
"templateVersionId": "1b7f6842-48bc-47da-bf7c-bf8fa3f74637",
"data": {
"invoice": {
"number": "INV-2026-0042",
"issuedAt": "2026-04-10"
},
"customer": {
"name": "Acme Corp",
"email": "ap@acme.test"
},
"totals": {
"grand": "245.00"
}
},
"output": "url",
"filename": "invoice-2026-0042-approved.pdf",
"executionMode": "async"
}'{
"success": true,
"jobId": "7b6f4c93-34e3-4f6d-a32d-9a2f0b2054d1",
"status": "queued",
"statusUrl": "/v1/pdf/jobs/7b6f4c93-34e3-4f6d-a32d-9a2f0b2054d1",
"fileUrl": "/v1/pdf/jobs/7b6f4c93-34e3-4f6d-a32d-9a2f0b2054d1/file"
}curl "https://api.solidrelay.io/v1/pdf/jobs/7b6f4c93-34e3-4f6d-a32d-9a2f0b2054d1" \
-H "X-API-Key: YOUR_API_KEY"
curl "https://api.solidrelay.io/v1/pdf/jobs/7b6f4c93-34e3-4f6d-a32d-9a2f0b2054d1/file" \
-H "X-API-Key: YOUR_API_KEY" \
--output invoice-2026-0042-approved.pdf- Use
templateVersionIdonly when you need one fixed historical snapshot. - Version history and rollback are available on Professional and Business plans. Use the template routes to list or manage those saved versions.
- Once create returns
202 Accepted, switch to the accepted-work flow instead of sending a second create request.
Expected Responses
Handle both successful outcomes from the render route
Template renders follow the same execution model as every other single render request.
200 OKmeans the render completed within the sync wait window and returned the requested output mode now.202 Acceptedmeans the render was admitted to the queue and must continue through status and file follow up.GET /v1/pdf/jobs/:id/filereturns404until the job is completed, downloadable, and still within its retention window.
Operational Notes
Treat template identifiers as integration contract data
Reliable template-driven rendering depends on deliberate handling of IDs, versions, and follow-up state.
- Store template IDs in config or a managed data layer, not in display-name lookups at request time.
- Log
templateId, and logtemplateVersionIdwhenever you pin one historical snapshot. - Use idempotency keys on render creates whenever client retries are possible.
- Keep accepted-job persistence separate from template lifecycle persistence so create retries and job polling remain safe.
Common Failure Checks
Check these first when template renders fail
- Verify the auth surface: bearer token for template management,
X-API-Keyfor render execution. - Ensure the request uses exactly one input source and does not combine a saved template with inline HTML or a URL.
- Confirm
templateIdand optionaltemplateVersionIdare valid UUIDs from your account. - Match the runtime
dataobject to the variable names used by the template content. - Use the shared errors page when deciding whether to fix, wait, or retry.
Next Steps
Use reference pages for full route contracts
Template lifecycle
Open templates reference
Exact contract for create, list, update, versions, and rollback behavior.
Single render
Open single render reference
Request fields, output modes, accepted response behavior, and status codes for POST /v1/pdf.
Accepted work
Handle 202 render responses
Use the accepted render flow guide when template-backed creates continue through job status and file retrieval.