Async Rendering API
The async rendering API allows you to generate documents in the background, which is ideal for large documents, batch processing, or when you don't want to block your application waiting for a response.
Overview
Unlike synchronous rendering which returns the document directly, async rendering:
- Starts a background job - Returns immediately with a job ID
- Processes in the background - Document generation happens asynchronously
- Provides status polling - Check if your document is ready
- Returns a download URL - Fetch the completed document
Result Expiration
Completed documents are available for download for 24 hours after generation. After this period, you'll need to render the document again.
Authentication
All async endpoints require an API key. Pass your API key in the X-Api-Key header.
See API Key Management for details on creating API keys.
Endpoints
Start Async Job (Template)
Start a background document generation job using a template.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
renderType |
string | Document type: pdf, docx, or txt |
templateId |
string | Your template ID |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
templateVersionId |
string | Optional. Specific template version to use |
Request Body
Pass your template data as JSON:
{
"customerName": "Acme Corp",
"invoiceNumber": "INV-2024-001",
"items": [
{ "description": "Widget", "quantity": 5, "price": 10.00 },
{ "description": "Gadget", "quantity": 2, "price": 25.00 }
]
}
Response (202 Accepted)
{
"jobId": "01HQXYZ123456789ABCDEF",
"status": "Pending",
"templateId": "tpl_abc123",
"renderType": "pdf",
"createdAt": "2024-01-15T10:30:00Z",
"expiresAt": "2024-01-16T10:30:00Z",
"statusUrl": "/render/async/status/01HQXYZ123456789ABCDEF",
"resultUrl": "/render/async/result/01HQXYZ123456789ABCDEF"
}
Start Async Job (Raw HTML)
Start a background PDF generation job from raw HTML content.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
renderType |
string | Currently only pdf is supported |
Request Body
Base64 Encoding
The HTML content must be Base64 encoded. In JavaScript: btoa(htmlString). In Python: base64.b64encode(html_string.encode()).decode().
Response (202 Accepted)
Same format as template-based jobs, but templateId will be null.
Check Job Status
Poll this endpoint to check if your document is ready.
Response (200 OK)
{
"jobId": "01HQXYZ123456789ABCDEF",
"status": "Completed",
"templateId": "tpl_abc123",
"renderType": "pdf",
"createdAt": "2024-01-15T10:30:00Z",
"completedAt": "2024-01-15T10:30:05Z",
"expiresAt": "2024-01-16T10:30:00Z",
"elapsedTimeMs": 5234,
"resultUrl": "/render/async/result/01HQXYZ123456789ABCDEF"
}
ResultUrl
The resultUrl field is only included when status is Completed.
Get Result
Retrieve the completed document. This endpoint redirects to a temporary download URL.
Response
- 302 Found - Redirects to a pre-signed download URL
- 400 Bad Request - Job is not yet completed
- 404 Not Found - Job not found or expired
Job Statuses
| Status | Description |
|---|---|
Pending |
Job is queued and waiting to be processed |
Processing |
Document generation is in progress |
Completed |
Document is ready for download |
Failed |
An error occurred during generation |
Expired |
Result is no longer available (24 hours passed) |
Complete Example
Here's a complete workflow in JavaScript:
const API_BASE = 'https://api.templateto.com';
const API_KEY = 'your-api-key';
async function generateDocumentAsync(templateId, data) {
// 1. Start the job
const startResponse = await fetch(
`${API_BASE}/render/async/pdf/${templateId}`,
{
method: 'POST',
headers: {
'X-Api-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}
);
const job = await startResponse.json();
console.log(`Job started: ${job.jobId}`);
// 2. Poll for completion
let status = job.status;
while (status === 'Pending' || status === 'Processing') {
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second
const statusResponse = await fetch(
`${API_BASE}/render/async/status/${job.jobId}`,
{ headers: { 'X-Api-Key': API_KEY } }
);
const statusData = await statusResponse.json();
status = statusData.status;
console.log(`Status: ${status}`);
}
if (status !== 'Completed') {
throw new Error(`Job failed with status: ${status}`);
}
// 3. Get the result (follow redirect to download)
const resultResponse = await fetch(
`${API_BASE}/render/async/result/${job.jobId}`,
{
headers: { 'X-Api-Key': API_KEY },
redirect: 'follow'
}
);
return await resultResponse.blob();
}
// Usage
const pdfBlob = await generateDocumentAsync('tpl_abc123', {
customerName: 'Acme Corp',
total: 150.00
});
Error Handling
Common Error Responses
| Status Code | Meaning |
|---|---|
| 400 | Invalid request (bad render type, missing data, job not completed) |
| 401 | Authentication required or invalid |
| 404 | Template or job not found |
| 500 | Internal server error |
Error Response Format
Failed Jobs
If a job fails, check the errorMessage field in the status response for details about what went wrong.