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

1

Start a job

POST to /render/async/pdf/{templateId} with your data. Optionally pass webhookUrl and outputPresignedUrl. You get a job ID back instantly.

2

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.

3

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

Ready to dive in?
Start your free trial today.

Generate multiple documents and merge data in
minutes without extensive development knowledge.