Generate SaaS invoice PDFs from subscription data

Turn the billing data from your application into a branded PDF. Store an HTML template once, then send the customer, billing period and line items as JSON for each invoice. Your billing system remains responsible for charges, taxes and invoice numbering.

Challenges

Keep billing calculations in your application

Billing periods and adjustments

Export the service period, plan name, seat count and any prorated adjustments from your subscription system. Pass display-ready amounts to the template; Templatr does not calculate prorations.

One document per business event

Verify the billing webhook signature and deduplicate its event or invoice ID before requesting a PDF. Store the returned document reference with that invoice to avoid generating duplicates.

Solution

From a paid invoice to a PDF

1. Save the HTML layout

Copy the HTML below to template.html. Upload it with the multipart request, then use the template_id from the response in the generation request.

2. Prepare the subscription data

Copy the JSON example to invoice.json. Replace the fictional customer, service dates, quantities and precomputed amounts with the finalized values from your billing system.

3. Generate and store the document

Call the API from your server with a private API key. The format=pdf request writes the binary response to invoice.pdf. Check the HTTP status before sending or storing the file.

Integration

Quick Start Code

1. Save as template.html

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Invoice {{invoice.number}}</title>
  <style>
    @page { size: A4; margin: 20mm; }
    body { font: 14px sans-serif; color: #171717; }
    table { width: 100%; border-collapse: collapse; }
    th, td { padding: 10px 0; text-align: left; border-bottom: 1px solid #ddd; }
    .amount { text-align: right; }
    tr { break-inside: avoid; }
  </style>
</head>
<body>
  <h1>Invoice {{invoice.number}}</h1>
  <p>{{seller.name}} · {{seller.address}}</p>
  <p>Bill to: {{customer.name}} · {{customer.address}}</p>
  <p>Issued: {{invoice.issued}} · Due: {{invoice.due}}</p>
  <p>{{invoice.reference}}</p>
  <table>
    <thead><tr><th>Description</th><th>Quantity</th><th class="amount">Amount</th></tr></thead>
    <tbody>
      {{ items loop }}
      <tr><td>{{item.description}}</td><td>{{item.quantity}}</td><td class="amount">{{item.amount}}</td></tr>
      {{ end loop }}
    </tbody>
  </table>
  <p>Subtotal: {{totals.subtotal}}</p>
  <p>Tax: {{totals.tax}}</p>
  <p><strong>Total: {{totals.total}}</strong></p>
</body>
</html>

2. Save as invoice.json

Fictional data. Amounts are already calculated and formatted.

json
{
  "seller": {
    "name": "Example Studio",
    "address": "10 Example Street"
  },
  "customer": {
    "name": "Ada's Workshop",
    "address": "20 Sample Road"
  },
  "totals": {
    "subtotal": "EUR 100.00",
    "tax": "EUR 20.00",
    "total": "EUR 120.00"
  },
  "invoice": {
    "number": "EXAMPLE-1",
    "issued": "2026-09-01",
    "due": "2026-09-15",
    "reference": "Service period: 1–30 September 2026"
  },
  "items": [
    {
      "description": "Team subscription · September 2026",
      "quantity": 5,
      "amount": "EUR 100.00"
    }
  ]
}

3. Upload, then generate the PDF

Create an API key in Settings. Replace TEMPLATE_ID with template_id returned by the first request. Run these commands from your backend environment.

bash
curl --fail-with-body -X POST 'https://api.templatr.app/upload' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -F 'file=@template.html' -F 'name=Invoice'

curl --fail-with-body -X POST 'https://api.templatr.app/pdf/TEMPLATE_ID?format=pdf' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary @invoice.json --output invoice.pdf

FAQ

Frequently Asked Questions

Does Templatr bill my subscribers?

No. Your billing provider manages subscriptions, payments, taxes and invoice records. Templatr renders the HTML and JSON you supply into a PDF.

How do I show prorations or usage charges?

Calculate them in your billing system and pass each adjustment as a separate JSON line item. The template supports escaped variables and loops, but it does not perform billing calculations.

Can I use a download link instead of binary PDF?

Yes. Omit format=pdf to receive pdf_url and expires_in. The signed link expires after one hour; your account also provides access to document history. Store the PDF in your own system if you need a separate retention policy.

Is this a legally certified invoice template?

No. This is a technical example with fictional data. Your application must supply the invoice content required for your business and jurisdiction. No tax validation, e-invoicing certification or PDF/A output is provided by this example.

Test your subscription invoice layout

Preview the HTML with sample JSON in the editor before connecting your billing workflow.