Async PDF generation API with webhooks
Render PDFs in the background, get notified by webhook when they're done, and upload results directly to your own cloud storage. No polling. No long-running HTTP connections.
Built for production scale
Synchronous when users are waiting. Async with webhooks when they're not.
Two modes share the same templates, the same data format, the same engine. Pick the one that fits the workload — no rewrites when you switch.
- No polling loops
- Get notified the moment a job completes. We POST to your webhook with the job ID, status, and result URL — no status endpoint to hammer on a timer.
- No long-running HTTP connections
- Fire off a request, get a job ID back immediately, and carry on. Friendly to serverless functions, edge runtimes, and any environment with execution-time limits.
- Render hundreds in the background
- Bulk operations — month-end invoices, statement runs, mass exports — don't tie up your UI or your worker pool. Queue them up, walk away, get paged when they're done.
- Upload directly to your own storage
- Pass a pre-signed URL and we PUT the rendered document straight into your bucket — S3, GCS, Azure Blob, Cloudflare R2, Backblaze B2, DigitalOcean Spaces, Wasabi. Combine with webhooks for a fully push-based pipeline. Zero polling, zero downloads.
How it works
Three steps to background PDF generation
Start a job
POST to /render/async/pdf/{templateId}
with your data. Optionally pass webhookUrl
and
outputPresignedUrl. You get
a job ID back instantly.
We render in the background
Your job is rendered using the same headless Chromium engine as the synchronous endpoint. Same templates, same data format, same output quality.
Get notified or fetch
When complete, we POST your webhook with the job result. If you provided a presigned URL, the PDF is already in your bucket. Otherwise, download from our pre-signed URL within 24 hours.
Webhook PDF generation in code
Start a job and get a job ID immediately:
// Start an async PDF render — get a job ID instantly
const response = await fetch(
'https://api.templateto.com/render/async/pdf/tpl_abc123',
{
method: 'POST',
headers: {
'X-Api-Key': 'your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
customerName: 'Acme Corp',
invoiceNumber: 'INV-2026-001'
})
}
);
const { jobId, statusUrl, resultUrl } = await response.json();
// 202 Accepted — your app continues immediately. No connection held open. Or skip polling entirely with a webhook callback and direct-to-storage upload:
// Same call, but pass webhookUrl + outputPresignedUrl
const url = 'https://api.templateto.com/render/async/pdf/tpl_abc123?' +
new URLSearchParams({
webhookUrl: 'https://your-app.com/webhooks/templateto',
outputPresignedUrl: yourPresignedS3Url
});
await fetch(url, {
method: 'POST',
headers: { 'X-Api-Key': 'your-api-key', 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
// When the job completes:
// 1. We PUT the rendered PDF directly to your S3/GCS/Azure URL
// 2. We POST your webhook with { jobId, status, resultUrl, errorMessage }
// Your application never polls and never downloads from us. Full request/response shapes, retry policy, and error handling are documented in the async rendering developer guide.
What async PDF generation replaces
The patterns developers traditionally use to work around synchronous-only PDF APIs — and what TemplateTo gives you instead.
⛔ Without async + webhooks
- • Polling loops checking status every few seconds
- • Long-running HTTP requests that time out on serverless
- • Browser tabs hung waiting for batch jobs to finish
- • Workers blocked on download bandwidth from the PDF service
- • Custom queue + worker code on your end to coordinate
✅ With TemplateTo async
- • Push notifications via webhook the moment a job completes
- • Sub-second API call to start the job, then your function exits
- • Bulk runs queue cleanly and report back asynchronously
- • PDF lands in your bucket directly — zero download from us
- • No queue infrastructure to build or maintain on your side
When to use async PDF rendering
Batch PDF generation
Month-end invoice runs, statement exports, mass certificate generation. Queue hundreds or thousands of jobs and let webhooks coordinate the result handling.
Serverless functions
AWS Lambda, Cloudflare Workers, Vercel Edge Functions — all have execution-time limits. Async rendering returns immediately so your function exits before the timer.
Large or complex documents
Multi-hundred-page reports, embedded image-heavy PDFs, slow-rendering layouts. Don't hold an HTTP connection open — get notified when it's done.
Event-driven architectures
Domain event fires → render job dispatched → completion webhook triggers downstream processing. Each step is decoupled.
User-facing background jobs
"We're generating your report — we'll email it when it's ready." Better UX than a spinner that ties up the browser tab.
Generate PDFs and upload to S3
Skip the download-then-reupload step. Pre-signed URL goes in, PDF lands in your bucket with the right Content-Type and ACL.
FAQ
Common questions about async PDF generation
- Yes. Pass a
webhookUrlwhen starting an async render and TemplateTo will POST to your endpoint when the job completes — successful or failed. The payload includes thejobId,status,resultUrl, and any error message. Webhooks are retried with exponential backoff on non-2xx responses. - Use the async render endpoints (e.g.
/render/async/pdf/{templateId}). The API returns a 202 Accepted with a job ID immediately and renders the PDF in the background. You can either poll the status endpoint, receive a webhook, or both. - Yes. Async rendering is the recommended pattern for batch PDF generation. Queue jobs in a loop and process webhook callbacks as documents complete — no need to hold connections open or poll for each one. See the Batch vs On-Demand article for guidance on choosing the right pattern.
- Yes. Pass an
outputPresignedUrlparameter pointing to a pre-signed PUT URL on your own storage. TemplateTo PUTs the rendered PDF straight into your bucket. Works with AWS S3, Google Cloud Storage, Azure Blob Storage, Cloudflare R2, Backblaze B2, DigitalOcean Spaces, and Wasabi. - Synchronous rendering returns the PDF in the HTTP response — best when a user is waiting for an immediate download. Async rendering returns a job ID immediately and notifies you via webhook (or polling) when the document is ready — best for batch operations, large documents, serverless functions, or any time you don't want to hold a connection open.
- No. Polling works for simple scripts and CLI tools, but the recommended pattern is to provide a
webhookUrlwhen starting the job. TemplateTo POSTs your endpoint as soon as the job completes — no polling loops, no wasted requests.
Ready to dive in?
Start your free trial today.
Generate multiple documents and merge data in
minutes without extensive development knowledge.