Tree sprawling up into the sky.

Batch vs. On-Demand PDF Generation

There are two ways to generate documents with TemplateTo: on-demand (synchronous) and batch (asynchronous). Which you choose depends on whether you need a document right now or need to produce many documents in the background. Most applications end up using both.

On-Demand: Synchronous Rendering

On-demand generation is the simplest path. You send a POST request with your template data and get the finished PDF back in the HTTP response. One request, one document, done.

curl -X POST \
  "https://api.templateto.com/render/pdf/tpl_abc123" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"customerName": "Acme Corp", "invoiceNumber": "INV-2026-042", "total": 1250.00}' \
  -o invoice.pdf

The response body is the PDF itself. Your application can serve it directly to a user, attach it to an email, or save it to storage.

When to Use On-Demand

  • “Download PDF” buttons — a user clicks a button and gets their document immediately
  • E-commerce receipts — generate and email a receipt the moment an order is placed
  • Contract generation — a sales rep fills in a form, clicks generate, and has a PDF to send to the client
  • Support interactions — an agent generates a warranty document or service agreement during a live chat

The common thread is that someone is waiting for the result. The document needs to exist within a few seconds of the request.

Practical Considerations

Synchronous rendering works well when documents are relatively straightforward — a few pages, standard formatting, moderate image usage. TemplateTo’s rendering engine handles most templates in under two seconds.

If your documents are complex (many pages, high-resolution images, heavy styling) or if you’re generating more than a handful at a time, you’ll want to look at async rendering instead.

Batch: Asynchronous Rendering

Batch generation uses TemplateTo’s async rendering API. Instead of waiting for each document to finish, you fire off jobs that run in the background. Each job returns a job ID immediately, and you collect the results later — either by polling or by receiving a webhook notification.

async function generateBatchInvoices(invoices) {
  const jobs = [];

  for (const invoice of invoices) {
    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(invoice)
      }
    );

    const job = await response.json();
    jobs.push(job);
  }

  // All jobs are now running in the background
  console.log(`Started ${jobs.length} jobs`);
  return jobs;
}

This is the right approach when you need to generate tens, hundreds, or thousands of documents in a single run.

When to Use Batch

  • Monthly billing — generate invoices for your entire customer base at the end of each billing cycle
  • Payroll — produce payslips for every employee on payday
  • Year-end reporting — generate financial summaries, tax documents, or compliance reports for all accounts
  • Marketing campaigns — create personalised brochures, certificates, or letters for a mailing list
  • E-commerce order spikes — during sales events like Black Friday, order volumes spike and synchronous rendering can become a bottleneck

Webhooks and Direct Upload

The real power of batch generation comes from combining async rendering with webhooks and presigned URL uploads. Instead of polling for each job’s status, you tell TemplateTo where to deliver the result and how to notify you:

// Start 500 invoice jobs with webhook notification
for (const invoice of invoices) {
  await fetch(
    `https://api.templateto.com/render/async/pdf/tpl_abc123?${new URLSearchParams({
      webhookUrl: 'https://your-app.com/webhooks/invoice-ready',
      outputPresignedUrl: invoice.presignedUrl
    })}`,
    {
      method: 'POST',
      headers: {
        'X-Api-Key': 'your-api-key',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(invoice.data)
    }
  );
}

// Your webhook handler processes each invoice as it completes
// — no polling, no waiting, no holding connections open

With this setup, each document is uploaded directly to your own storage (S3, Azure Blob, GCS, R2, or any provider that supports presigned URLs) and your application is notified via webhook the moment it’s ready. No polling loops, no held connections, no intermediate downloads from TemplateTo’s servers.

For the full details on webhooks, presigned URLs, and the async job lifecycle, see our async rendering guide.

Choosing the Right Approach

On-Demand (Sync) Batch (Async)
Response PDF in the HTTP response Job ID; result delivered later
Latency Seconds Minutes (for large batches)
Volume One document per request Hundreds or thousands per run
Best for User-triggered actions Scheduled or event-driven bulk runs
Delivery Direct download Webhook + presigned URL upload
Endpoint /render/pdf/{templateId} /render/async/pdf/{templateId}

In practice, most applications use both. A SaaS billing platform might use on-demand rendering when a customer clicks “View Invoice” in their dashboard, and batch rendering for the monthly billing run that generates invoices for all customers at once. Both use the same template and the same data format — the only difference is how the request is made and how the result is delivered.

Not Just PDFs

Both on-demand and batch rendering work with every output format TemplateTo supports:

  • PDF/render/pdf/ or /render/async/pdf/
  • TXT — for plain text output
  • Images (PNG/JPEG)/render/image/ or /render/async/image/ for social media graphics, certificates, badges, and more. See our image generation guide for details.

The same template can produce any of these formats. Design once, render in whatever format the situation calls for.

Getting Started

If you’re already using TemplateTo’s synchronous API, switching to batch is straightforward — change your endpoint from /render/pdf/{templateId} to /render/async/pdf/{templateId} and handle the job ID response instead of the direct PDF.

For the full API reference, head over to our developer documentation. If you’re new to TemplateTo, sign up for a free account and try both approaches with the same template — you’ll see how easy it is to switch between on-demand and batch depending on what your application needs.