210 × 297 mm
Invoices
Product sales invoice
A bold A4 invoice for small goods businesses, easy to edit visually: a coloured letterhead, an invoice-number barcode, order and delivery details, striped product lines with SKUs, mixed VAT rates, a highlighted amount due and a received-by signature line. Embeds ZUGFeRD / Factur-X EN 16931 XML.
Opens Dynamic Document API with this template preloaded in a free workspace.
Template language features
- Loops
- Conditionals
- Currency formatting
- Date formatting
- Number formatting
- Barcode
- Header & footer
- Page numbers
- Repeating table headers
- signature
- columns
Filters such as format_currency and qrcode are described in the template language reference.
Variables
Derived from the sample data: 3 top-level fields, 66 paths in total. Send the same shape as data.
| Path | Type | Example |
|---|---|---|
| invoice | object | |
| invoice.number | string | "MF-2026-0917" |
| invoice.issue_date | date | "2026-09-17" |
| invoice.due_date | date | "2026-10-01" |
| invoice.currency | string | "EUR" |
| invoice.order_reference | string | "BSC-PO-0482" |
| invoice.payment_terms | string | "14 days net. Goods remain our property until p…" |
| invoice.delivery | object | |
| invoice.delivery.date | date | "2026-09-16" |
| invoice.delivery.party_name | string | "Brambleside Café, Quay Street" |
| invoice.delivery.address | object | |
| invoice.delivery.address.line1 | string | "14 Coopers Quay" |
| invoice.delivery.address.city | string | "Cork" |
| invoice.delivery.address.postcode | string | "T12 R7XK" |
| invoice.delivery.address.country | string | "IE" |
| invoice.seller | object | |
| invoice.seller.name | string | "Moonfield Coffee Roasters Ltd" |
| invoice.seller.trading_name | string | "Moonfield Coffee Roasters" |
| invoice.seller.vat_id | string | "IE1234567FA" |
| invoice.seller.electronic_address | object | |
| invoice.seller.electronic_address.id | string | "orders@moonfield.example.com" |
| invoice.seller.electronic_address.scheme | string | "EM" |
| invoice.seller.address | object | |
| invoice.seller.address.line1 | string | "Unit 5, Ardkeen Craft Yard" |
| invoice.seller.address.city | string | "Galway" |
| invoice.seller.address.postcode | string | "H91 X4F2" |
| invoice.seller.address.country | string | "IE" |
| invoice.seller.contact | object | |
| invoice.seller.contact.name | string | "Orla Brennan" |
| invoice.seller.contact.email | string | "orders@moonfield.example.com" |
| invoice.buyer | object | |
| invoice.buyer.name | string | "Brambleside Café Ltd" |
| invoice.buyer.vat_id | string | "IE7654321WA" |
| invoice.buyer.electronic_address | object | |
| invoice.buyer.electronic_address.id | string | "accounts@brambleside.example.com" |
| invoice.buyer.electronic_address.scheme | string | "EM" |
| invoice.buyer.address | object | |
| invoice.buyer.address.line1 | string | "9 Merchant's Row" |
| invoice.buyer.address.line2 | string | "2nd floor" |
| invoice.buyer.address.city | string | "Cork" |
| invoice.buyer.address.postcode | string | "T12 K3PD" |
| invoice.buyer.address.country | string | "IE" |
| invoice.buyer.contact | object | |
| invoice.buyer.contact.name | string | "Niamh Kearney" |
| invoice.payment | object | |
| invoice.payment.means_code | string | "58" |
| invoice.payment.remittance_information | string | "MF-2026-0917" |
| invoice.payment.credit_transfers | array<object> · 1 | |
| invoice.payment.credit_transfers[].account_id | string | "IE00EXMP99021512345678" |
| invoice.payment.credit_transfers[].account_name | string | "Moonfield Coffee Roasters Ltd" |
| invoice.payment.credit_transfers[].bic | string | "EXMPIE2D" |
| invoice.lines | array<object> · 7 | |
| invoice.lines[].quantity | string | "12" |
| invoice.lines[].unit | string | "H87" |
| invoice.lines[].net_amount | string | "268.80" |
| invoice.lines[].price | object | |
| invoice.lines[].price.net | string | "22.40" |
| invoice.lines[].tax | object | |
| invoice.lines[].tax.category | string | "Z" |
| invoice.lines[].tax.rate | string | "0" |
| invoice.lines[].item | object | |
| invoice.lines[].item.name | string | "House espresso blend, 1 kg" |
| invoice.lines[].item.description | string | "Whole bean · Brazil and Colombia · roasted 12 …" |
| invoice.lines[].item.seller_id | string | "MF-ESP-1000" |
| tagline | string | "Small-batch coffee, roasted in Galway" |
| bank_name | string | "Westerly Mutual Bank" |
Sample data
Fictional records used for previews. Replace them with your own data when you call the API.
{
"invoice": {
"number": "MF-2026-0917",
"issue_date": "2026-09-17",
"due_date": "2026-10-01",
"currency": "EUR",
"order_reference": "BSC-PO-0482",
"payment_terms": "14 days net. Goods remain our property until paid in full.",
"delivery": {
"date": "2026-09-16",
"party_name": "Brambleside Café, Quay Street",
"address": {
"line1": "14 Coopers Quay",
"city": "Cork",
"postcode": "T12 R7XK",
"country": "IE"
}
},
"seller": {
"name": "Moonfield Coffee Roasters Ltd",
"trading_name": "Moonfield Coffee Roasters",
"vat_id": "IE1234567FA",
"electronic_address": {
"id": "orders@moonfield.example.com",
"scheme": "EM"
},
"address": {
"line1": "Unit 5, Ardkeen Craft Yard",
"city": "Galway",
"postcode": "H91 X4F2",
"country": "IE"
},
"contact": {
"name": "Orla Brennan",
"email": "orders@moonfield.example.com"
}
},
"buyer": {
"name": "Brambleside Café Ltd",
"vat_id": "IE7654321WA",
"electronic_address": {
"id": "accounts@brambleside.example.com",
"scheme": "EM"
},
"address": {
"line1": "9 Merchant's Row",
"line2": "2nd floor",
"city": "Cork",
"postcode": "T12 K3PD",
"country": "IE"
},
"contact": {
"name": "Niamh Kearney"
}
},
"payment": {
"means_code": "58",
"remittance_information": "MF-2026-0917",
"credit_transfers": [
{
"account_id": "IE00EXMP99021512345678",
"account_name": "Moonfield Coffee Roasters Ltd",
"bic": "EXMPIE2D"
}
]
},
"lines": [
{
"quantity": "12",
"unit": "H87",
"net_amount": "268.80",
"price": {
"net": "22.40"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "House espresso blend, 1 kg",
"description": "Whole bean · Brazil and Colombia · roasted 12 Sept",
"seller_id": "MF-ESP-1000"
}
},
{
"quantity": "4",
"unit": "H87",
"net_amount": "118.40",
"price": {
"net": "29.60"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "Ethiopia Guji single origin, 1 kg",
"description": "Whole bean · washed · light roast",
"seller_id": "MF-ETH-1000"
}
},
{
"quantity": "3",
"unit": "H87",
"net_amount": "80.40",
"price": {
"net": "26.80"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "Colombia decaf, 1 kg",
"description": "Whole bean · sugarcane process",
"seller_id": "MF-DEC-1000"
}
},
{
"quantity": "24",
"unit": "H87",
"net_amount": "166.80",
"price": {
"net": "6.95"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "Guatemala retail bags, 250 g",
"description": "Ground for filter · for resale",
"seller_id": "MF-GUA-0250"
}
},
{
"quantity": "2",
"unit": "H87",
"net_amount": "76.00",
"price": {
"net": "38.00"
},
"tax": {
"category": "S",
"rate": "23"
},
"item": {
"name": "Stoneware espresso cups, set of 6",
"description": "80 ml · speckled oat glaze",
"seller_id": "MF-CUP-0080"
}
},
{
"quantity": "2",
"unit": "H87",
"net_amount": "29.00",
"price": {
"net": "14.50"
},
"tax": {
"category": "S",
"rate": "23"
},
"item": {
"name": "Grinder cleaning tablets",
"description": "430 g tub",
"seller_id": "MF-CLN-0430"
}
},
{
"quantity": "10",
"unit": "H87",
"net_amount": "45.00",
"price": {
"net": "4.50"
},
"tax": {
"category": "S",
"rate": "23"
},
"item": {
"name": "Paper filters, size 02",
"description": "Box of 100 · unbleached",
"seller_id": "MF-FLT-0002"
}
}
]
},
"tagline": "Small-batch coffee, roasted in Galway",
"bank_name": "Westerly Mutual Bank"
}Source
The body markup with Jinja, the stylesheet placed in <head> and the header and footer settings.
<div class="letterhead">
<div>
<div class="brand">
<img class="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAwFBMVEX0sjQAAAB9HUTsqDX0sjT0sjSEJkP0sjT2szP8ti71szOSN0H0sjTShzisVz23ZTzFdzrclDecRED//wDimzb/rTOjTD//v0D/qgB/IET/zDOgSUC/cDueRj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADvsp2VAAAAMHRSTlP+AP//zI7/ri4STf9v////////Af8P/wQD/wX///8AAAAAAAAAAAAAAAAAAAAAAACY3OqJAAAKlklEQVR42u2d6XakOAyFxWLAZqdSlaVn3v81p5L09NRCFbZ1ZTAT/eqkz8nBH9KVZLxQ8j83+gHwA+AHQFjTplFKlWWZ5zl92fkf5x/Pv2yM3jWAz6H/HvNjywNjCASgshj6DYZqLwAOVVOSl5VNdYgcgP/gg0GQBFApgpiqYgRQuQX9kiRUcQGAjl6WAUkoPnz0vxlIZAaKZfRSDLAAtCJxU3qzAKoAw4dnBRyAqqRgVlabAxBy+FAEGAAmp+CWm80ACP32oV5AUSi/YEZgAzC0qpmVAeiSVrZSrwjgtaENWPO6FoAqp01YXq0C4EPRZkx9hAewldf/2wl0aACGNmYmKACtaHPmWRNQ/O7P00Lag/tzwoAirH2gVZEzAJ3Ths09G9Auwp8hBI4AKtq8VZIADEVgRg5AQ1FYIwVAUSSmRAAcS4rGyiMegM4pIrNPh7ST9OdNgPb4/l0I2AF4Kyk6K9+AACIc/5kADoCiKE2hADQUqTUYAIaiNYMAEPH4bQjQDvo/Vm+4BEBT5KZ5AA5l7ADKAwuAouhNcQAY2oEZfwCadmHaF0D8AmAhA7RvAViWAdq5ACzKAO1dAJZkgPYuAEsyQLtrAR0bw0cAjrQzOzoCUHsDoNwAAHvArO1PdV0XaVrUU9f3Q5ttqS+cB3AATQJnw+k88Dur+xUg5AcHAA1m9H+njy08hMYeAEIBs65IF6w4tevrIEnNgmd9amFFN66sgySngG1qZXW7qg6SnAJSn1oiGAKpQW4HANYEZYUlgbQIhMBYAcB9B53S1B7BSi5AaAdoPWIgnBYYCwA8B+i6ix+G1MlO2QouQFgH6NKTex4IGQfVIgBWDXB+5fXFjy+pq9VZ6G/mhKwBPt94cfkLZwDyTlAtAOA4wMtX2rt8h4U7gXTKgroAAR2g/hrAePcbVydoQ7oA4Rzgt+Z758H/rA/YERBsJvjfuu8yiEc/ALJhoJ8AUKwM+G2XhYCXCHyFwRjKBa4AvHIU8M+zz1HZVDZ4fQjAABzgWgR8Y0BUCMxDAAwJzN7/PDkkBm7/jlgmJJAEXuh9Qfw88N0bhJBBwkyFXrX+o9ecQMBkYB4AKEHTXz35d4RBCJTzADREAtPrfsizGhQmoGcBcD4GXDt6BnOBdJL+RECQmZD2mX6zXEBGCfM5ABUqAs72cvmf4zuLQCfbERGkDK6fPjQvCEQIqBkAnLnAu4cefWeHA9WE+T0ATg4YF7SLVQzcFNfoPECIPmBYeuaRB6B4kauFCNkJP6wFWBXxJ4FMTAQIIQFzMT4QUgYmMREgxKrAevmlZdPGUoG+AcD6HjKrcTdBkNXbEkJzA4C1KszqpTEJoGVA3QDgSEBm99KYBGoZESCABLxYZi8mgV5EBAggAa3tlz6mErYSIkAACWjtW7luOzKgrgCwFgWMDm7bbyYIyisAJAQgHSzKZnuDfi65BMDbHPF0GcAdgbbYSCbQFwB4KwMzN+niJIO/4JMiBFgXkzmKNyMZIHXQXABgLo5eeOqBcFJ4Qs+MEmJxcO2s3sP7+jpYXgDIhRdE3vdyY7F6Y5xfAGD+qc6jm/WWwhabBwmxP6D3+sTTr50Kj38AcNfHD34rAD0rggGaBwmxQ6b1XPXiFwYFNA1AAGS+y9+ybk0X+A8Ae5Ng7d3M+IRBjewHMQA6/zLmpV4tEQABDIzF0B5h8AsNgL1LbGQtABycw+AFVwpiADgsBptbAOhcFnZgAPxdQieXp58Jg2mNphAJYODuiuhXyIQ5EEDGXhDvlg8nLADAH6vZ05tu+TBDdUMoAD1//ZuTEPRbA9AiFsT3gatBJACPVdG8wnjcGgCP7v5X9mDfVagYgAJw3yN49mNGh1wjAUC2S9eYfSHZr2B5IMcC8PvmNVMWdqFqoRzYC/gvBpwpC4dAXwhKLADfT98zZaFVMig2B+Al9bTBrz0ccQBU8AMjEN9Nhg3NCHlWg0+EwKIg6DYHgLE14r4wXi4I6u1MiwNWf9xL4XJWwQGAHZxTIxcALRIYEQsECHp4XpsilwMvERhgn8Zwx0di98gtKGEP+zia0CZc4D4ZPCfQwT6Pr3N4lA2Bp/XAhFsggTtCF705ppXLgwq3SAq2GHamIOjFuoEGtkwOukPsjsAkNSVgYAslCblN8o7Ak5Iwgy2UhJ4jXoMJjEIADrDF0qi2+NGXv17mIzFuuTx0SfxcNqwlAJS4DRPI1dCzGf5RPTTiNkxgL1MYuQBuq9xBAIDBbZoSCILbZUA1HoDGbZuDV8T3QjjCs0CO3DiJL4fuZOCEnhFRyK2z8LbwXgYydClskJunBXqCuwjvwc2QRm6fFykIb2RgJqgm5PZ5/J0a/GqgW3CpHnqAAv5apRe2EGbPVWCAHqEhcK9SK+wCI/QQlUTgbukBqoMjMAvm4IOUpFLB6Zms1uCDlERuV+2QFXGPmxSuwIepiRGon8hgCz5MTeh2sV9AF5hQdWADP1DxSTkw4VqCARUBGn6kplxBlD2KgRZ+pKbUDXs8Hxge5AHOlgEjcKwuobZTPI2BHlMHa4GDleVmiLLZ2vI9EzhYWfCa1QEUAwVCAo3I4epLfUEBqQYnxIy40PH6S72hbzK4cvYO4ABK6IIFsWTQ3ocSa9eYlrpiQ0oKZ66sGHC3rJDYXaMwIejuSqFJ7pIVWRfwqwqn2zTACoBS8qIlm3xY8A5MqLkfhJYuWpJpinnZILvOg4PoVVsB7pzvC8bEWMdcHWikr9uzcoKTfx7sO+nr9gK4wDkd1L4fyVr5CxcDuICjGE5hr9yUmha4u5e6CH5ujuWlq4cgLvCJoA58lObc9eMke/U8SAvaoBcvS5eDVzZ2hef+SkANIHr5un0ktKf3MBcz21++HkgHLxj09bML2lv03TqLAELp4DWESXD08wr4EEBAHbymMLZD301f7lDUXd9mslfPPwYQUgfDmErcABz3BuDoCCC0Dkpbk7gCOOwqCMqDMwDRGeLgphN3AEH64kBmEh8Akp9JtpEBlgDsRQYeC8ACgL3IgE58AexDBkziD2APMqASDoCPPPbx568sAPHLgE54AGKXgSrhAoibgEn4AGJui5oEASDeVGAxfisAsRJQCQpAnDXx0wrYDUDyFiGB8i3BAUh0dAVRrhMkgOgI2I7fGkBkBKzHbw8g0RHpQHlM8AAiUkI7/XcGEE09oFzG5AQgjqq4SeQAxNAZmUQSwPYJOI7fGcBa341h/T8bwKYLAvv0zwCQvG02Gai3JASAzYZB5TMWLwDJsYy6+uMD2GBFYDwH4gsgqTalhXmVhAaQfGxIC9VHEh7AdpzA//UzASSvm1CC5pCsBeBcFa0eB6XmjYAJYO04YHk/BkByaGL1fhCA9eKA6/0wAOc4WKEyLCvIo2MAhEcAGj4OwBlBwEBQFeyxcQDCaYHSwIdGAgiDADp8NIAzAuGk2GjwA6MBiIoBMPQlAZxrIyPAQJmDxLOKAPgMBQPNi6XRQg8qBeBLDkBtQt5ouacUBPDlB4oJIVdGiz6iLIBvCI1nNJSN8ODDAPjODI1yolCqpgrzZIEAfE+mV6ZZColcNaY6BnyokAD+jYnKmKZRqizzLxp5XpZKNY0xlQ7/NCsA2Jb9APgB8D8H8A87qcQp3hcprQAAAABJRU5ErkJggg==" alt="{{ invoice.seller.trading_name }} logo">
<div>
<h1>{{ invoice.seller.trading_name }}</h1>
<p class="tagline">{{ tagline }}</p>
</div>
</div>
<p class="seller">{{ invoice.seller.address.line1 }}, {{ invoice.seller.address.city }} {{ invoice.seller.address.postcode }}</p>
<p class="seller">VAT {{ invoice.seller.vat_id }} · {{ invoice.seller.contact.email }}</p>
</div>
<div class="doc-info">
<p class="label">Invoice</p>
<p class="doc-number">{{ invoice.number }}</p>
<p class="issued">Issued {{ invoice.issue_date | format_date("long", "en-IE") }}</p>
<p class="barcode">{{ invoice.number | barcode("code128", module_width=0.24, module_height=8, write_text=false, foreground="#4d0f2b", alt="Barcode " ~ invoice.number) }}</p>
</div>
</div>
<div class="parties">
<div>
<h2 class="label">Bill to</h2>
<p><strong>{{ invoice.buyer.name }}</strong></p>
{% if invoice.buyer.contact.name %}<p>Attn. {{ invoice.buyer.contact.name }}</p>{% endif %}
<p>{{ invoice.buyer.address.line1 }}</p>
{% if invoice.buyer.address.line2 %}<p>{{ invoice.buyer.address.line2 }}</p>{% endif %}
<p>{{ invoice.buyer.address.city }} {{ invoice.buyer.address.postcode }}</p>
{% if invoice.buyer.vat_id %}<p class="muted">VAT {{ invoice.buyer.vat_id }}</p>{% endif %}
</div>
<div>
<h2 class="label">Delivered to</h2>
{% if invoice.delivery.address %}
<div>
<p><strong>{{ invoice.delivery.party_name }}</strong></p>
<p>{{ invoice.delivery.address.line1 }}</p>
<p>{{ invoice.delivery.address.city }} {{ invoice.delivery.address.postcode }}</p>
</div>
{% endif %}
</div>
<div>
<h2 class="label">Order</h2>
<table class="facts">
<tbody>
{% if invoice.order_reference %}<tr><th scope="row">Your order</th><td><strong>{{ invoice.order_reference }}</strong></td></tr>{% endif %}
{% if invoice.delivery.date %}<tr><th scope="row">Delivered</th><td>{{ invoice.delivery.date | format_date("long", "en-IE") }}</td></tr>{% endif %}
<tr><th scope="row">Due date</th><td><strong>{{ invoice.due_date | format_date("long", "en-IE") }}</strong></td></tr>
</tbody>
</table>
</div>
</div>
<table class="items">
<thead>
<tr>
<th class="sku" scope="col">SKU</th>
<th scope="col">Product</th>
<th class="qty" scope="col">Qty</th>
<th class="price" scope="col">Unit price</th>
<th class="vat" scope="col">VAT</th>
<th class="amount" scope="col">Amount</th>
</tr>
</thead>
<tbody>
{% for line in invoice.lines %}
<tr>
<td class="sku">{{ line.item.seller_id }}</td>
<td>
<p class="item-name">{{ line.item.name }}</p>
{% if line.item.description %}<p class="item-note">{{ line.item.description }}</p>{% endif %}
</td>
<td class="qty">{{ line.quantity | format_number("en-IE") }}</td>
<td class="price">{{ line.price.net | format_currency(invoice.currency, "en-IE") }}</td>
<td class="vat">{{ line.tax.rate | format_number("en-IE") }}%</td>
<td class="amount">{{ render.invoice.lines[loop.index0].net_amount | format_currency(invoice.currency, "en-IE") }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="summary">
<div>
<h2 class="label">Payment by bank transfer</h2>
<table class="facts">
<tbody>
{% if bank_name %}<tr><th scope="row">Bank</th><td>{{ bank_name }}</td></tr>{% endif %}
<tr><th scope="row">Account</th><td>{{ invoice.payment.credit_transfers[0].account_name }}</td></tr>
<tr><th scope="row">IBAN</th><td><strong>{{ invoice.payment.credit_transfers[0].account_id }}</strong></td></tr>
<tr><th scope="row">BIC</th><td>{{ invoice.payment.credit_transfers[0].bic }}</td></tr>
<tr><th scope="row">Reference</th><td><strong>{{ invoice.payment.remittance_information }}</strong></td></tr>
</tbody>
</table>
{% if invoice.payment_terms %}
<div class="terms">
<h2 class="label">Terms</h2>
<p>{{ invoice.payment_terms }}</p>
</div>
{% endif %}
</div>
<div>
<table class="totals">
<tbody>
<tr><th scope="row">Net total</th><td>{{ render.invoice.totals.line_total | format_currency(invoice.currency, "en-IE") }}</td></tr>
{% for vat in render.invoice.vat_breakdown %}
<tr><th scope="row">VAT {{ vat.rate | format_number("en-IE") }}% on {{ vat.basis | format_currency(invoice.currency, "en-IE") }}</th><td>{{ vat.tax | format_currency(invoice.currency, "en-IE") }}</td></tr>
{% endfor %}
<tr class="grand-total"><th scope="row">Total</th><td>{{ render.invoice.totals.grand_total | format_currency(invoice.currency, "en-IE") }}</td></tr>
</tbody>
</table>
<div class="amount-due">
<div>
<p class="label">Amount due</p>
<p class="due-date">by {{ invoice.due_date | format_date("long", "en-IE") }}</p>
</div>
<p class="amount-due-value">{{ render.invoice.totals.due_payable | format_currency(invoice.currency, "en-IE") }}</p>
</div>
</div>
</div>
<div class="confirmation">
<div>
<h2 class="label">Delivery confirmation</h2>
<p>Goods received in good order. Please report damage or shortages within 48 hours of delivery.</p>
</div>
<div class="signatures">
<p class="signature">Received by (name and signature)</p>
<p class="signature date">Date</p>
</div>
</div><title>Invoice {{ invoice.number }} – {{ invoice.seller.trading_name }}</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: "Source Sans 3", "Liberation Sans", Arial, sans-serif;
font-size: 10pt;
line-height: 1.38;
color: #2b1f25;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
h1, h2 {
margin: 0;
font-family: "Montserrat", "Liberation Sans", Arial, sans-serif;
font-weight: 700;
line-height: 1.25;
color: #4d0f2b;
}
p { margin: 0; }
table { width: 100%; border-collapse: collapse; }
td, th { padding: 0; text-align: left; vertical-align: top; }
.muted { color: #7b6a72; }
.label {
margin: 0 0 1.8mm;
font-family: "Montserrat", "Liberation Sans", Arial, sans-serif;
font-size: 7.5pt;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: #7d1d45;
}
/* Coloured letterhead with the invoice number and its barcode */
.letterhead {
display: grid;
grid-template-columns: 1.9fr 1fr;
gap: 8mm;
margin-bottom: 6mm;
padding: 6mm;
border-radius: 3mm;
background: #7d1d45;
color: #fff6e8;
}
.brand { display: flex; gap: 4mm; margin-bottom: 4.5mm; }
.logo { width: 14mm; height: 14mm; }
.brand h1 { margin: 0.3mm 0 0.6mm; font-size: 17pt; color: #fff6e8; }
.tagline { font-size: 9.5pt; color: #f5b335; }
.seller { font-size: 8.5pt; color: #f4d7e2; }
.doc-info { text-align: right; }
.doc-info .label { margin-bottom: 0.5mm; color: #f5b335; }
.doc-number { margin-bottom: 0.5mm; font-family: "Montserrat", "Liberation Sans", Arial, sans-serif; font-size: 16pt; font-weight: 700; }
.issued { margin-bottom: 3mm; font-size: 8.5pt; color: #f4d7e2; }
.barcode { line-height: 0; }
/* Bill to, delivery address and order details */
.parties { display: grid; grid-template-columns: 1fr 1fr 1.15fr; gap: 8mm; margin-bottom: 6mm; }
.facts td, .facts th { padding-bottom: 0.3em; }
.facts th { width: 23mm; padding-right: 1.2em; color: #7b6a72; white-space: nowrap; font-weight: inherit; }
/* Product lines */
.items { margin-bottom: 6mm; table-layout: fixed; }
.items thead { display: table-header-group; }
.items th {
padding: 2mm 1.5mm;
background: #7d1d45;
font-size: 7.5pt;
font-weight: 600;
text-transform: uppercase;
color: #fff6e8;
}
.items td { padding: 1.5mm; vertical-align: middle; }
.items tbody tr:nth-child(even) td { background: #fbf0f4; }
.items tr { break-inside: avoid; }
.items .sku { width: 14.9%; }
.items td.sku { font-family: "Montserrat", "Liberation Sans", Arial, sans-serif; font-size: 7.5pt; color: #7d1d45; }
.items .qty { width: 7.4%; text-align: right; }
.items .price { width: 13.4%; text-align: right; }
.items .vat { width: 8.2%; text-align: right; }
.items td.vat { color: #7b6a72; }
.items .amount { width: 14.1%; text-align: right; }
.items td.amount { font-weight: 700; }
.item-name { font-weight: 700; }
.item-note { font-size: 8.5pt; color: #7b6a72; }
/* Bank details, terms and totals */
.summary { display: grid; grid-template-columns: 1.1fr 1fr; align-items: start; gap: 12mm; margin-bottom: 6mm; break-inside: avoid; }
.summary .facts { margin-bottom: 2.5mm; }
.terms .label { margin-bottom: 0.8mm; }
.terms p { font-size: 8.5pt; color: #7b6a72; }
.totals { margin-bottom: 2.5mm; }
.totals td, .totals th { padding: 1.2mm; color: #7b6a72; }
.totals th { font-weight: inherit; }
.totals th + td { text-align: right; color: #2b1f25; }
.totals .grand-total td, .totals .grand-total th { font-weight: 700; color: #4d0f2b; }
.amount-due {
display: flex;
justify-content: space-between;
align-items: center;
gap: 3mm;
padding: 3.5mm;
border-radius: 2.5mm;
background: #f5b335;
color: #4d0f2b;
}
.amount-due .label { margin-bottom: 0.8mm; color: #4d0f2b; }
.due-date { font-size: 8.5pt; }
.amount-due-value { font-family: "Montserrat", "Liberation Sans", Arial, sans-serif; font-size: 17pt; font-weight: 700; }
/* Delivery confirmation with signature lines */
.confirmation {
display: grid;
grid-template-columns: 1.25fr 2fr;
gap: 8mm;
padding: 4.5mm;
border: 0.75pt solid #ecdce3;
border-radius: 3mm;
break-inside: avoid;
}
.confirmation p { font-size: 8.5pt; color: #7b6a72; }
.signatures { display: flex; align-items: flex-end; gap: 10mm; }
.signature { width: 48mm; margin-top: 11mm; padding-top: 0.35em; border-top: 0.75pt solid #2b1f25; }
.signature.date { width: 38mm; }
</style>Render it with the API
After adding the template to your workspace, render it by ID and pass your data. Arrays are shortened here.
curl -X POST https://api-eu.dynamicdocumentapi.com/v1/renders \
-H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"input": {
"type": "template",
"template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C"
},
"data": {
"invoice": {
"number": "MF-2026-0917",
"issue_date": "2026-09-17",
"due_date": "2026-10-01",
"currency": "EUR",
"order_reference": "BSC-PO-0482",
"payment_terms": "14 days net. Goods remain our property until paid in full.",
"delivery": {
"date": "2026-09-16",
"party_name": "Brambleside Café, Quay Street",
"address": {
"line1": "14 Coopers Quay",
"city": "Cork",
"postcode": "T12 R7XK",
"country": "IE"
}
},
"seller": {
"name": "Moonfield Coffee Roasters Ltd",
"trading_name": "Moonfield Coffee Roasters",
"vat_id": "IE1234567FA",
"electronic_address": {
"id": "orders@moonfield.example.com",
"scheme": "EM"
},
"address": {
"line1": "Unit 5, Ardkeen Craft Yard",
"city": "Galway",
"postcode": "H91 X4F2",
"country": "IE"
},
"contact": {
"name": "Orla Brennan",
"email": "orders@moonfield.example.com"
}
},
"buyer": {
"name": "Brambleside Café Ltd",
"vat_id": "IE7654321WA",
"electronic_address": {
"id": "accounts@brambleside.example.com",
"scheme": "EM"
},
"address": {
"line1": "9 Merchant'\''s Row",
"line2": "2nd floor",
"city": "Cork",
"postcode": "T12 K3PD",
"country": "IE"
},
"contact": {
"name": "Niamh Kearney"
}
},
"payment": {
"means_code": "58",
"remittance_information": "MF-2026-0917",
"credit_transfers": [
{
"account_id": "IE00EXMP99021512345678",
"account_name": "Moonfield Coffee Roasters Ltd",
"bic": "EXMPIE2D"
}
]
},
"lines": [
{
"quantity": "12",
"unit": "H87",
"net_amount": "268.80",
"price": {
"net": "22.40"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "House espresso blend, 1 kg",
"description": "Whole bean · Brazil and Colombia · roasted 12 Sept",
"seller_id": "MF-ESP-1000"
}
},
{
"quantity": "4",
"unit": "H87",
"net_amount": "118.40",
"price": {
"net": "29.60"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "Ethiopia Guji single origin, 1 kg",
"description": "Whole bean · washed · light roast",
"seller_id": "MF-ETH-1000"
}
}
]
},
"tagline": "Small-batch coffee, roasted in Galway",
"bank_name": "Westerly Mutual Bank"
},
"output": {
"format": "pdf",
"filename": "invoice-product-sales.pdf"
}
}'const response = await fetch("https://api-eu.dynamicdocumentapi.com/v1/renders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"input": {
"type": "template",
"template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C"
},
"data": {
"invoice": {
"number": "MF-2026-0917",
"issue_date": "2026-09-17",
"due_date": "2026-10-01",
"currency": "EUR",
"order_reference": "BSC-PO-0482",
"payment_terms": "14 days net. Goods remain our property until paid in full.",
"delivery": {
"date": "2026-09-16",
"party_name": "Brambleside Café, Quay Street",
"address": {
"line1": "14 Coopers Quay",
"city": "Cork",
"postcode": "T12 R7XK",
"country": "IE"
}
},
"seller": {
"name": "Moonfield Coffee Roasters Ltd",
"trading_name": "Moonfield Coffee Roasters",
"vat_id": "IE1234567FA",
"electronic_address": {
"id": "orders@moonfield.example.com",
"scheme": "EM"
},
"address": {
"line1": "Unit 5, Ardkeen Craft Yard",
"city": "Galway",
"postcode": "H91 X4F2",
"country": "IE"
},
"contact": {
"name": "Orla Brennan",
"email": "orders@moonfield.example.com"
}
},
"buyer": {
"name": "Brambleside Café Ltd",
"vat_id": "IE7654321WA",
"electronic_address": {
"id": "accounts@brambleside.example.com",
"scheme": "EM"
},
"address": {
"line1": "9 Merchant's Row",
"line2": "2nd floor",
"city": "Cork",
"postcode": "T12 K3PD",
"country": "IE"
},
"contact": {
"name": "Niamh Kearney"
}
},
"payment": {
"means_code": "58",
"remittance_information": "MF-2026-0917",
"credit_transfers": [
{
"account_id": "IE00EXMP99021512345678",
"account_name": "Moonfield Coffee Roasters Ltd",
"bic": "EXMPIE2D"
}
]
},
"lines": [
{
"quantity": "12",
"unit": "H87",
"net_amount": "268.80",
"price": {
"net": "22.40"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "House espresso blend, 1 kg",
"description": "Whole bean · Brazil and Colombia · roasted 12 Sept",
"seller_id": "MF-ESP-1000"
}
},
{
"quantity": "4",
"unit": "H87",
"net_amount": "118.40",
"price": {
"net": "29.60"
},
"tax": {
"category": "Z",
"rate": "0"
},
"item": {
"name": "Ethiopia Guji single origin, 1 kg",
"description": "Whole bean · washed · light roast",
"seller_id": "MF-ETH-1000"
}
}
]
},
"tagline": "Small-batch coffee, roasted in Galway",
"bank_name": "Westerly Mutual Bank"
},
"output": {
"format": "pdf",
"filename": "invoice-product-sales.pdf"
}
}),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const result = await response.json();
console.log(result);import os
import uuid
import requests
response = requests.post(
"https://api-eu.dynamicdocumentapi.com/v1/renders",
headers={
"Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"input": {
"type": "template",
"template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C",
},
"data": {
"invoice": {
"number": "MF-2026-0917",
"issue_date": "2026-09-17",
"due_date": "2026-10-01",
"currency": "EUR",
"order_reference": "BSC-PO-0482",
"payment_terms": "14 days net. Goods remain our property until paid in full.",
"delivery": {
"date": "2026-09-16",
"party_name": "Brambleside Café, Quay Street",
"address": {
"line1": "14 Coopers Quay",
"city": "Cork",
"postcode": "T12 R7XK",
"country": "IE",
},
},
"seller": {
"name": "Moonfield Coffee Roasters Ltd",
"trading_name": "Moonfield Coffee Roasters",
"vat_id": "IE1234567FA",
"electronic_address": {
"id": "orders@moonfield.example.com",
"scheme": "EM",
},
"address": {
"line1": "Unit 5, Ardkeen Craft Yard",
"city": "Galway",
"postcode": "H91 X4F2",
"country": "IE",
},
"contact": {
"name": "Orla Brennan",
"email": "orders@moonfield.example.com",
},
},
"buyer": {
"name": "Brambleside Café Ltd",
"vat_id": "IE7654321WA",
"electronic_address": {
"id": "accounts@brambleside.example.com",
"scheme": "EM",
},
"address": {
"line1": "9 Merchant's Row",
"line2": "2nd floor",
"city": "Cork",
"postcode": "T12 K3PD",
"country": "IE",
},
"contact": {
"name": "Niamh Kearney",
},
},
"payment": {
"means_code": "58",
"remittance_information": "MF-2026-0917",
"credit_transfers": [
{
"account_id": "IE00EXMP99021512345678",
"account_name": "Moonfield Coffee Roasters Ltd",
"bic": "EXMPIE2D",
},
],
},
"lines": [
{
"quantity": "12",
"unit": "H87",
"net_amount": "268.80",
"price": {
"net": "22.40",
},
"tax": {
"category": "Z",
"rate": "0",
},
"item": {
"name": "House espresso blend, 1 kg",
"description": "Whole bean · Brazil and Colombia · roasted 12 Sept",
"seller_id": "MF-ESP-1000",
},
},
{
"quantity": "4",
"unit": "H87",
"net_amount": "118.40",
"price": {
"net": "29.60",
},
"tax": {
"category": "Z",
"rate": "0",
},
"item": {
"name": "Ethiopia Guji single origin, 1 kg",
"description": "Whole bean · washed · light roast",
"seller_id": "MF-ETH-1000",
},
},
],
},
"tagline": "Small-batch coffee, roasted in Galway",
"bank_name": "Westerly Mutual Bank",
},
"output": {
"format": "pdf",
"filename": "invoice-product-sales.pdf",
},
},
timeout=90,
)
response.raise_for_status()
print(response.json())More invoices templates
- 210 × 297 mm
Bold brand invoice
A4A confident, colourful A4 invoice for studios and product companies: a brand-coloured hero with the amount due, brand colours you set from data, itemised EN 16931 lines, VAT, a pay-by-link QR code and the same data embedded as ZUGFeRD / Factur-X EN 16931 XML.
- 210 × 297 mm
E-Rechnung (ZUGFeRD / XRechnung)
A4A German A4 invoice rendered straight from the EN 16931 invoice model, so the same data produces the visible invoice and the embedded Factur-X / ZUGFeRD or XRechnung XML (output.einvoice.invoice_path = "invoice"). It prints the engine's computed amounts, lists VAT per rate, the Leitweg-ID and the bank details.
- 210 × 297 mm
EU reverse-charge invoice
A4An A4 invoice for cross-border B2B services within the EU, rendered from the EN 16931 invoice model: both VAT IDs, the date of supply, VAT category AE (reverse charge) with its exemption reason and notice, the total in words, bank transfer details and the same data embedded as ZUGFeRD / Factur-X EN 16931 XML.