How to generate an invoice PDF from JSON
Keep invoice data as JSON, keep the layout in one HTML template, and render the PDF with one call. Worked example for a Nepal VAT invoice; the same pattern covers an Indian GST invoice.
By Saurav N, senior software engineer · Updated
· 6 min readShape the data
Put everything that changes per invoice in the JSON: seller, buyer, invoice number and date, line items and totals. Compute the tax in your system of record, so the PDF shows the same numbers your accounts do.
A Nepal VAT invoice shows the seller’s and buyer’s PAN, the taxable amount and 13% VAT. An Indian GST invoice shows GSTINs, HSN codes and, within a state, the CGST and SGST split.
{
"seller": { "name": "Himalayan Traders Pvt Ltd", "address": "New Baneshwor, Kathmandu", "pan": "601234567" },
"buyer": { "name": "Sita Sharma", "address": "Jawalakhel, Lalitpur", "pan": "609876543" },
"invoice": { "number": "INV-2026-0311", "date": "2026-09-29", "taxable": 11300, "vat": 1469, "total": 12769 },
"items": [
{ "sn": 1, "name": "Ilam tea 500 g", "qty": 10, "rate": 650, "amount": 6500 },
{ "sn": 2, "name": "Basmati rice 5 kg", "qty": 4, "rate": 1200, "amount": 4800 }
]
}Write the template once
The template is HTML with Handlebars placeholders. {{#each items}} repeats a row per line item, and formatCurrency prints amounts in the right currency, such as NPR 12,769.00 or ₹49,402.50.
<table class="items">
<thead>
<tr><th>S.N.</th><th>Description</th><th class="num">Qty</th><th class="num">Rate</th><th class="num">Amount</th></tr>
</thead>
<tbody>
{{#each items}}
<tr>
<td>{{sn}}</td><td>{{name}}</td><td class="num">{{qty}}</td>
<td class="num">{{formatCurrency rate "NPR"}}</td>
<td class="num">{{formatCurrency amount "NPR"}}</td>
</tr>
{{/each}}
</tbody>
</table>
<p class="num">Taxable {{formatCurrency invoice.taxable "NPR"}}<br>VAT 13% {{formatCurrency invoice.vat "NPR"}}</p>
<p class="total">Total {{formatCurrency invoice.total "NPR"}}</p>Render it
Save the template in a workspace, then post the JSON. The Idempotency-Key makes retries safe: the same key and body within 24 hours return the original PDF instead of making a second one.
curl -X POST "https://templater.nestutils.com/v1/pdfs/render?wait=20" \
-H "Authorization: Bearer $TEMPLATER_KEY" \
-H "Idempotency-Key: invoice-INV-2026-0311" \
-H "Content-Type: application/json" \
-d "{ \"template\": \"nepal-vat-invoice\", \"returnAs\": \"binary\", \"data\": $(cat invoice.json) }" \
-o invoice.pdfSend it with the invoice email
The same data can send the invoice email and attach this PDF in one request: POST /v1/emails/send with "attachments": [{ "template": "nepal-vat-invoice" }].
Questions
Should the template calculate the tax?
Better not. Calculate totals and tax where your accounts live and send the results, so the PDF can never disagree with your books.
How do I show the amount in words?
Send it as a field, such as invoice.inWords, from your system. Templates stay logic-free on purpose.
Can I start from an invoice PDF I already have?
Yes. Upload it to the PDF to HTML converter and it becomes a template with the values as variables.