Skip to content

210 × 297 mm

Invoices

Bold brand invoice

A 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.

A4 portraitLocale en-IEHTML + JinjaHeader & footer

Opens Dynamic Document API with this template preloaded in a free workspace.

Template language features

  • Loops
  • Conditionals
  • Macros
  • Filters
  • Currency formatting
  • Date formatting
  • Number formatting
  • QR code
  • Repeating table headers
  • Header & footer
  • Page numbers

Filters such as format_currency and qrcode are described in the template language reference.

Variables

Derived from the sample data: 5 top-level fields, 70 paths in total. Send the same shape as data.

PathTypeExample
invoiceobject
invoice.numberstring"FQ-2026-0419"
invoice.issue_datedate"2026-09-18"
invoice.due_datedate"2026-10-18"
invoice.currencystring"EUR"
invoice.buyer_referencestring"LNF-APP-2026"
invoice.order_referencestring"PO-40277"
invoice.payment_termsstring"Net 30 days"
invoice.deliveryobject
invoice.delivery.datedate"2026-09-16"
invoice.sellerobject
invoice.seller.namestring"Ferrow & Quay Studio Ltd"
invoice.seller.trading_namestring"Ferrow & Quay"
invoice.seller.vat_idstring"IE1234567FA"
invoice.seller.legal_registrationobject
invoice.seller.legal_registration.idstring"700419"
invoice.seller.electronic_addressobject
invoice.seller.electronic_address.idstring"accounts@ferrowquay.example.com"
invoice.seller.electronic_address.schemestring"EM"
invoice.seller.addressobject
invoice.seller.address.line1string"Studio 3, The Ropeworks"
invoice.seller.address.line2string"14 Marsh Quay Lane"
invoice.seller.address.citystring"Cork"
invoice.seller.address.postcodestring"T12 X7Q4"
invoice.seller.address.countrystring"IE"
invoice.seller.contactobject
invoice.seller.contact.namestring"Studio accounts"
invoice.seller.contact.emailstring"accounts@ferrowquay.example.com"
invoice.buyerobject
invoice.buyer.namestring"Lanternfield Health DAC"
invoice.buyer.vat_idstring"IE7654321KA"
invoice.buyer.electronic_addressobject
invoice.buyer.electronic_address.idstring"payables@lanternfield.example.com"
invoice.buyer.electronic_address.schemestring"EM"
invoice.buyer.addressobject
invoice.buyer.address.line1string"Level 4, Weavers Hall"
invoice.buyer.address.line2string"61 Canal Terrace"
invoice.buyer.address.citystring"Dublin"
invoice.buyer.address.postcodestring"D08 R2Y6"
invoice.buyer.address.countrystring"IE"
invoice.buyer.contactobject
invoice.buyer.contact.namestring"Niamh Corrigan"
invoice.paymentobject
invoice.payment.means_codestring"58"
invoice.payment.remittance_informationstring"FQ-2026-0419"
invoice.payment.credit_transfersarray<object> · 1
invoice.payment.credit_transfers[].account_idstring"IE00EXMP99000012345678"
invoice.payment.credit_transfers[].account_namestring"Ferrow & Quay Studio Ltd"
invoice.payment.credit_transfers[].bicstring"EXMPIE2D"
invoice.linesarray<object> · 6
invoice.lines[].quantitystring"5"
invoice.lines[].unitstring"DAY"
invoice.lines[].priceobject
invoice.lines[].price.netstring"1150.00"
invoice.lines[].taxobject
invoice.lines[].tax.categorystring"S"
invoice.lines[].tax.ratestring"23"
invoice.lines[].itemobject
invoice.lines[].item.namestring"Product design sprint"
invoice.lines[].item.descriptionstring"Workshops, journey maps and a tested concept"
invoice.notesarray<object> · 2
invoice.notes[].textstring"Thank you for building the Lanternfield patien…"
brandobject
brand.taglinestring"Product design & engineering"
brand.primarystring"#2b1a3d"
brand.accentstring"#ff8a5c"
brand.accent_textstring"#2b1a3d"
websitestring"ferrowquay.example.com"
bank_namestring"Harbourline Bank"
payment_linkstring"https://pay.example.com/i/FQ-2026-0419"

Sample data

Fictional records used for previews. Replace them with your own data when you call the API.

data.json
{
  "invoice": {
    "number": "FQ-2026-0419",
    "issue_date": "2026-09-18",
    "due_date": "2026-10-18",
    "currency": "EUR",
    "buyer_reference": "LNF-APP-2026",
    "order_reference": "PO-40277",
    "payment_terms": "Net 30 days",
    "delivery": {
      "date": "2026-09-16"
    },
    "seller": {
      "name": "Ferrow & Quay Studio Ltd",
      "trading_name": "Ferrow & Quay",
      "vat_id": "IE1234567FA",
      "legal_registration": { "id": "700419" },
      "electronic_address": {
        "id": "accounts@ferrowquay.example.com",
        "scheme": "EM"
      },
      "address": {
        "line1": "Studio 3, The Ropeworks",
        "line2": "14 Marsh Quay Lane",
        "city": "Cork",
        "postcode": "T12 X7Q4",
        "country": "IE"
      },
      "contact": {
        "name": "Studio accounts",
        "email": "accounts@ferrowquay.example.com"
      }
    },
    "buyer": {
      "name": "Lanternfield Health DAC",
      "vat_id": "IE7654321KA",
      "electronic_address": {
        "id": "payables@lanternfield.example.com",
        "scheme": "EM"
      },
      "address": {
        "line1": "Level 4, Weavers Hall",
        "line2": "61 Canal Terrace",
        "city": "Dublin",
        "postcode": "D08 R2Y6",
        "country": "IE"
      },
      "contact": {
        "name": "Niamh Corrigan"
      }
    },
    "payment": {
      "means_code": "58",
      "remittance_information": "FQ-2026-0419",
      "credit_transfers": [
        {
          "account_id": "IE00EXMP99000012345678",
          "account_name": "Ferrow & Quay Studio Ltd",
          "bic": "EXMPIE2D"
        }
      ]
    },
    "lines": [
      {
        "quantity": "5",
        "unit": "DAY",
        "price": { "net": "1150.00" },
        "tax": { "category": "S", "rate": "23" },
        "item": {
          "name": "Product design sprint",
          "description": "Workshops, journey maps and a tested concept"
        }
      },
      {
        "quantity": "24",
        "unit": "C62",
        "price": { "net": "265.00" },
        "tax": { "category": "S", "rate": "23" },
        "item": {
          "name": "App UI screens",
          "description": "High-fidelity iOS and Android, light and dark"
        }
      },
      {
        "quantity": "1",
        "unit": "LS",
        "price": { "net": "4800.00" },
        "tax": { "category": "S", "rate": "23" },
        "item": {
          "name": "Design-system components",
          "description": "Tokens, 38 components and a shared library"
        }
      },
      {
        "quantity": "9",
        "unit": "HUR",
        "price": { "net": "140.00" },
        "tax": { "category": "S", "rate": "23" },
        "item": {
          "name": "Usability test sessions",
          "description": "Six moderated sessions and a findings report"
        }
      },
      {
        "quantity": "2.5",
        "unit": "DAY",
        "price": { "net": "1150.00" },
        "tax": { "category": "S", "rate": "23" },
        "item": {
          "name": "Motion prototypes",
          "description": "Onboarding and booking micro-interactions"
        }
      },
      {
        "quantity": "14.5",
        "unit": "HUR",
        "price": { "net": "110.00" },
        "tax": { "category": "S", "rate": "23" },
        "item": {
          "name": "Engineering handoff and QA",
          "description": "Front-end pairing and visual QA, release 14"
        }
      }
    ],
    "notes": [
      { "text": "Thank you for building the Lanternfield patient app with us." },
      { "text": "Questions about this invoice? Write to accounts@ferrowquay.example.com." }
    ]
  },
  "brand": {
    "tagline": "Product design & engineering",
    "primary": "#2b1a3d",
    "accent": "#ff8a5c",
    "accent_text": "#2b1a3d"
  },
  "website": "ferrowquay.example.com",
  "bank_name": "Harbourline Bank",
  "payment_link": "https://pay.example.com/i/FQ-2026-0419"
}

Source

The body markup with Jinja, the stylesheet placed in <head> and the header and footer settings.

{#- Bold brand invoice rendered from the EN 16931 invoice model (`invoice`, proto/einvoice/invoice.schema.json).
    With `output.einvoice.invoice_path = "invoice"` (this template's default) the renderer embeds the same data as
    Factur-X / ZUGFeRD XML; the platform computes the amounts as `render.invoice` for every render of it (with or
    without the XML, proto/README.md §20.7), so the page prints exactly the amounts of the XML. `render.einvoice`
    only tells whether the XML is embedded. Without either (e.g. an HTML render of the file) the template applies
    the same rules itself.
    `brand` (tagline and colours, used by head.html and the footer too), `website`, `bank_name` and `payment_link`
    are display-only extras outside the invoice model. -#}
{%- set inv = invoice -%}
{%- set cur = inv.currency -%}
{%- set loc = "en-IE" -%}
{%- set b = brand if (brand is defined and brand) else {} -%}
{%- set embedded = render.einvoice if (render is defined and render.einvoice is defined and render.einvoice) else none -%}
{%- set computed = render.invoice if (render is defined and render.invoice is defined and render.invoice) else embedded -%}
{%- set units = {"HUR": ["hour", "hours"], "DAY": ["day", "days"], "WEE": ["week", "weeks"], "MON": ["month", "months"], "C62": ["item", "items"], "H87": ["piece", "pieces"], "LS": ["lump sum", "lump sums"], "E48": ["service", "services"], "D68": ["word", "words"], "ZP": ["page", "pages"], "KGM": ["kg", "kg"], "MTR": ["m", "m"], "LTR": ["l", "l"]} -%}
{%- set countries = {"IE": "Ireland", "GB": "United Kingdom", "DE": "Germany", "FR": "France", "NL": "Netherlands", "BE": "Belgium", "ES": "Spain", "IT": "Italy", "AT": "Austria", "PT": "Portugal", "US": "United States"} -%}
{%- set profiles = {"MINIMUM": "Factur-X MINIMUM", "BASIC_WL": "Factur-X BASIC WL", "BASIC": "Factur-X BASIC", "EN16931": "Factur-X EN 16931", "EXTENDED": "Factur-X EXTENDED", "XRECHNUNG": "XRechnung"} -%}
{%- set exemptions = {"Z": "Zero rated", "E": "Exempt from VAT", "AE": "Reverse charge", "K": "Intra-community supply", "G": "Export outside the EU", "O": "Outside the scope of VAT"} -%}

{#- Line net amounts and VAT groups (EN 16931: line net = quantity × price ÷ base quantity − allowances + charges) -#}
{%- set ns = namespace(rows=[], nets=[], line_total=0.0, allowance_total=0.0, charge_total=0.0) -%}
{%- for line in inv.lines -%}
  {%- set base = (line.price.base_quantity | default(1)) | float -%}
  {%- set lns = namespace(net=((line.quantity | float) * (line.price.net | float) / base) | round(2)) -%}
  {%- for a in line.allowances | default([]) -%}{%- set lns.net = lns.net - (a.amount | float) -%}{%- endfor -%}
  {%- for c in line.charges | default([]) -%}{%- set lns.net = lns.net + (c.amount | float) -%}{%- endfor -%}
  {%- set net = (computed.lines[loop.index0].net_amount | float) if computed else (lns.net | round(2)) -%}
  {%- set rate = (line.tax.rate | default(0)) | float -%}
  {%- set ns.nets = ns.nets + [net] -%}
  {%- set ns.rows = ns.rows + [{"key": line.tax.category ~ "|" ~ rate, "category": line.tax.category, "rate": rate, "net": net}] -%}
  {%- set ns.line_total = ns.line_total + net -%}
{%- endfor -%}
{%- for a in inv.allowances | default([]) -%}
  {%- set rate = (a.tax_rate | default(0)) | float -%}
  {%- set ns.rows = ns.rows + [{"key": a.tax_category ~ "|" ~ rate, "category": a.tax_category, "rate": rate, "net": 0 - (a.amount | float)}] -%}
  {%- set ns.allowance_total = ns.allowance_total + (a.amount | float) -%}
{%- endfor -%}
{%- for c in inv.charges | default([]) -%}
  {%- set rate = (c.tax_rate | default(0)) | float -%}
  {%- set ns.rows = ns.rows + [{"key": c.tax_category ~ "|" ~ rate, "category": c.tax_category, "rate": rate, "net": c.amount | float}] -%}
  {%- set ns.charge_total = ns.charge_total + (c.amount | float) -%}
{%- endfor -%}
{%- if computed -%}
  {%- set breakdown = computed.vat_breakdown -%}
  {%- set totals = computed.totals -%}
{%- else -%}
  {%- set bns = namespace(items=[], tax=0.0) -%}
  {%- for group in ns.rows | groupby("key") -%}
    {%- set first = group.list | first -%}
    {%- set basis = (group.list | sum_by("net")) | round(2) -%}
    {%- set tax = (basis * first.rate / 100) | round(2) -%}
    {%- set bns.items = bns.items + [{"category": first.category, "rate": first.rate, "basis": basis, "tax": tax}] -%}
    {%- set bns.tax = bns.tax + tax -%}
  {%- endfor -%}
  {%- set tax_basis = (ns.line_total - ns.allowance_total + ns.charge_total) | round(2) -%}
  {%- set grand = (tax_basis + bns.tax) | round(2) -%}
  {%- set prepaid = (inv.prepaid_amount | default(0)) | float -%}
  {%- set rounding = (inv.rounding_amount | default(0)) | float -%}
  {%- set breakdown = bns.items -%}
  {%- set totals = {"line_total": ns.line_total | round(2), "allowance_total": ns.allowance_total | round(2), "charge_total": ns.charge_total | round(2), "tax_basis_total": tax_basis, "tax_total": bns.tax | round(2), "grand_total": grand, "prepaid": prepaid, "rounding": rounding, "due_payable": (grand - prepaid + rounding) | round(2)} -%}
{%- endif -%}
{%- set several_rates = breakdown | length > 1 -%}
{%- set adjusted = (totals.prepaid | float) != 0 or (totals.rounding | float) != 0 -%}
{%- set is_credit = inv.type_code in ["381", "261"] -%}

{%- macro money(value) -%}{{ value | format_currency(cur, loc) }}{%- endmacro -%}
{%- macro day(value) -%}{{ value | format_date("long", loc) }}{%- endmacro -%}
{%- macro rate_label(vb) -%}
  {%- if vb.category in exemptions -%}{{ exemptions[vb.category] }}{%- else -%}VAT {{ (vb.rate | float) | format_number(loc) }}%{%- endif -%}
{%- endmacro -%}
{%- macro quantity(line) -%}
  {%- set names = units[line.unit or "C62"] -%}
  {{ line.quantity | format_number(loc) }} <span class="unit">{% if names %}{{ names[0] if (line.quantity | float) == 1 else names[1] }}{% else %}{{ line.unit }}{% endif %}</span>
{%- endmacro -%}
{%- macro address(party) -%}
  {% if party.address.line1 %}<p>{{ party.address.line1 }}</p>{% endif %}
  {% if party.address.line2 %}<p>{{ party.address.line2 }}</p>{% endif %}
  {% if party.address.line3 %}<p>{{ party.address.line3 }}</p>{% endif %}
  <p>{% if party.address.country in ["GB", "IE", "US"] %}{{ party.address.city }} {{ party.address.postcode }}{% else %}{{ party.address.postcode }} {{ party.address.city }}{% endif %}, {{ countries[party.address.country] or party.address.country }}</p>
{%- endmacro -%}
{%- macro grouped(value) -%}
  {%- for i in range(0, value | length, 4) -%}{{ value[i:i + 4] }}{{ " " if not loop.last }}{%- endfor -%}
{%- endmacro -%}

<section class="hero">
  {#- Motif: stepped tones and rings around the amount due, with an accent dot rising along its orbit
      (1 unit = 1 mm, anchored to the hero's bottom-left corner) -#}
  <svg class="hero-motif" viewBox="0 0 182 70" aria-hidden="true">
    <defs>
      <linearGradient id="hero-trail" gradientUnits="userSpaceOnUse" x1="91.3" y1="66.6" x2="102.4" y2="31.5">
        <stop offset="0" class="trail-start"/>
        <stop offset="1" class="trail-end"/>
      </linearGradient>
    </defs>
    {%- for r in [118, 96, 74, 52] %}
    <circle class="tone" cx="176" cy="74" r="{{ r }}"/>
    {%- endfor %}
    {%- for r in [129, 107, 85, 63, 41] %}
    <circle class="ring" cx="176" cy="74" r="{{ r }}"/>
    {%- endfor %}
    <path class="trail" d="M 91.32 66.59 A 85 85 0 0 1 102.39 31.5"/>
    <circle class="orbit" cx="102.39" cy="31.5" r="1.6"/>
  </svg>
  <div class="hero-top">
    <div class="brand">
      <svg class="mark" viewBox="0 0 48 48" aria-hidden="true">
        <rect class="mark-bg" width="48" height="48" rx="13"/>
        <path class="mark-ink" d="M13 35 A22 22 0 0 1 35 13"/>
        <circle class="mark-dot" cx="32" cy="32" r="4.6"/>
      </svg>
      <div>
        <div class="brand-name">{{ inv.seller.trading_name or inv.seller.name }}</div>
        {% if b.tagline %}<div class="brand-tag">{{ b.tagline }}</div>{% endif %}
      </div>
    </div>
    <div class="hero-contact">
      {% if website is defined and website %}{{ website }}<br>{% endif %}
      {% if inv.seller.contact and inv.seller.contact.email %}{{ inv.seller.contact.email }}{% endif %}
    </div>
  </div>
  <div class="hero-main">
    <div>
      <h1>{{ "Credit note" if is_credit else "Invoice" }}</h1>
      <div class="doc-number"><span>No.</span>{{ inv.number }}</div>
    </div>
    <div class="due">
      <div class="kicker">{{ "Amount credited" if is_credit else "Amount due" }}</div>
      <div class="due-amount">{{ money(totals.due_payable) }}</div>
      {% if inv.due_date %}<div class="due-date"><span>Due</span> {{ day(inv.due_date) }}</div>
      {% elif inv.payment_terms %}<div class="due-date">{{ inv.payment_terms }}</div>{% endif %}
    </div>
  </div>
</section>

<section class="strip">
  <div>
    <p class="kicker">Billed to</p>
    <p class="party-name">{{ inv.buyer.name }}</p>
    {% if inv.buyer.contact and inv.buyer.contact.name %}<p>Attn. {{ inv.buyer.contact.name }}</p>{% endif %}
    <div class="muted">{{ address(inv.buyer) }}</div>
    {% if inv.buyer.vat_id %}<p class="muted">VAT {{ inv.buyer.vat_id }}</p>{% endif %}
  </div>
  <div>
    <p class="kicker">From</p>
    <p class="party-name">{{ inv.seller.name }}</p>
    <div class="muted">{{ address(inv.seller) }}</div>
    {% if inv.seller.vat_id %}<p class="muted">VAT {{ inv.seller.vat_id }}</p>{% endif %}
    {% if inv.seller.legal_registration %}<p class="muted">Company no. {{ inv.seller.legal_registration.id }}</p>{% endif %}
  </div>
  <div>
    <p class="kicker">Details</p>
    <table class="facts">
      <tr><th scope="row">Issue date</th><td>{{ day(inv.issue_date) }}</td></tr>
      {% if inv.delivery and inv.delivery.date %}<tr><th scope="row">Supply date</th><td>{{ day(inv.delivery.date) }}</td></tr>{% endif %}
      {% if inv.invoice_period %}<tr><th scope="row">Period</th><td>{{ inv.invoice_period.start | format_date("medium", loc) }} – {{ inv.invoice_period.end | format_date("medium", loc) }}</td></tr>{% endif %}
      {% if inv.payment_terms %}<tr><th scope="row">Terms</th><td>{{ inv.payment_terms }}</td></tr>{% endif %}
      {% if inv.order_reference %}<tr><th scope="row">PO number</th><td>{{ inv.order_reference }}</td></tr>{% endif %}
      {% if inv.buyer_reference %}<tr><th scope="row">Your reference</th><td>{{ inv.buyer_reference }}</td></tr>{% endif %}
      {% if embedded %}<tr><th scope="row">E-invoice</th><td>{{ profiles[embedded.profile] or embedded.profile }}</td></tr>{% endif %}
    </table>
  </div>
</section>

<table class="items">
  <thead>
    <tr>
      <th class="index" scope="col">No.</th>
      <th scope="col">Item</th>
      <th class="num col-qty" scope="col">Qty</th>
      <th class="num col-price" scope="col">Unit price</th>
      {% if several_rates %}<th class="num col-vat" scope="col">VAT</th>{% endif %}
      <th class="num col-amount" scope="col">Amount</th>
    </tr>
  </thead>
  <tbody>
    {% for line in inv.lines %}
    <tr>
      <td class="index">{% if line.id %}{{ line.id }}{% else %}{{ "0" if loop.index < 10 }}{{ loop.index }}{% endif %}</td>
      <td>
        <span class="item-name">{{ line.item.name }}</span>
        {% if line.item.description %}<span class="details">{{ line.item.description }}</span>{% endif %}
        {% if line.note %}<span class="details">{{ line.note }}</span>{% endif %}
        {% for a in line.allowances | default([]) %}<span class="details">Less {{ a.reason or "discount" }}: {{ money(a.amount | float) }}</span>{% endfor %}
        {% for c in line.charges | default([]) %}<span class="details">Plus {{ c.reason or "charge" }}: {{ money(c.amount | float) }}</span>{% endfor %}
      </td>
      <td class="num">{{ quantity(line) }}</td>
      <td class="num">{{ money(line.price.net) }}</td>
      {% if several_rates %}<td class="num">{% if line.tax.category in exemptions %}{{ line.tax.category }}{% else %}{{ (line.tax.rate | float) | format_number(loc) }}%{% endif %}</td>{% endif %}
      <td class="num amount">{{ money(ns.nets[loop.index0]) }}</td>
    </tr>
    {% endfor %}
  </tbody>
</table>

<section class="summary">
  <div>
    {% if inv.payment %}
    <div class="payment">
      <div class="pay-details">
        <h2>How to pay</h2>
        <table class="pay-table">
          {% for account in inv.payment.credit_transfers | default([]) %}
          <tr><th scope="row">Account name</th><td>{{ account.account_name or inv.seller.name }}</td></tr>
          <tr><th scope="row">{{ "IBAN" if (account.account_id | length) >= 15 else "Account" }}</th><td>{{ grouped(account.account_id) }}</td></tr>
          {% if account.bic %}<tr><th scope="row">BIC</th><td>{{ account.bic }}</td></tr>{% endif %}
          {% if bank_name is defined and bank_name and loop.first %}<tr><th scope="row">Bank</th><td>{{ bank_name }}</td></tr>{% endif %}
          {% endfor %}
          <tr><th scope="row">Reference</th><td><strong>{{ inv.payment.remittance_information or inv.number }}</strong></td></tr>
        </table>
      </div>
      {% if payment_link is defined and payment_link %}
      <div class="qr">
        <div class="qr-tile">{{ payment_link | qrcode(size=240, margin=0, ecc="M", color=(b.primary or "#2b1a3d"), alt="QR code linking to the online payment page") }}</div>
        <p class="qr-caption">Scan to pay</p>
      </div>
      {% endif %}
    </div>
    {% endif %}
  </div>
  <div class="totals-block">
    <table class="totals">
      <tr><th scope="row">Subtotal</th><td class="num">{{ money(totals.line_total) }}</td></tr>
      {% if (totals.allowance_total | float) != 0 %}<tr><th scope="row">Discounts</th><td class="num">−{{ money(totals.allowance_total) }}</td></tr>{% endif %}
      {% if (totals.charge_total | float) != 0 %}<tr><th scope="row">Charges</th><td class="num">{{ money(totals.charge_total) }}</td></tr>{% endif %}
      {% if (totals.allowance_total | float) != 0 or (totals.charge_total | float) != 0 %}<tr><th scope="row">Net total</th><td class="num">{{ money(totals.tax_basis_total) }}</td></tr>{% endif %}
      {% for vb in breakdown %}
      <tr><th scope="row">{{ rate_label(vb) }}{% if several_rates %} on {{ money(vb.basis) }}{% endif %}</th><td class="num">{{ money(vb.tax) }}</td></tr>
      {% endfor %}
      {% if adjusted %}
      <tr class="strong"><th scope="row">Invoice total</th><td class="num">{{ money(totals.grand_total) }}</td></tr>
      {% if (totals.prepaid | float) != 0 %}<tr><th scope="row">Paid</th><td class="num">−{{ money(totals.prepaid) }}</td></tr>{% endif %}
      {% if (totals.rounding | float) != 0 %}<tr><th scope="row">Rounding</th><td class="num">{{ money(totals.rounding) }}</td></tr>{% endif %}
      {% endif %}
    </table>
    <div class="total-bar">
      <div class="label">{{ "Total credit" if is_credit else ("Amount due" if adjusted else "Total due") }}<small>{{ cur }}, incl. VAT</small></div>
      <div class="value">{{ money(totals.due_payable) }}</div>
    </div>
  </div>
</section>

{%- set notes = inv.notes | default([]) -%}
{%- set ens = namespace(items=[]) -%}
{%- for vb in breakdown -%}
  {%- if vb.category in exemptions and inv.vat_exemptions and inv.vat_exemptions[vb.category] and inv.vat_exemptions[vb.category].reason -%}
    {%- set ens.items = ens.items + [exemptions[vb.category] ~ ": " ~ inv.vat_exemptions[vb.category].reason] -%}
  {%- endif -%}
{%- endfor %}
{% if notes or ens.items %}
<section class="closing">
  {% if notes %}<p class="thanks">{{ (notes | first).text }}</p>{% endif %}
  <div class="notes">
    {% for note in notes[1:] %}<p>{{ note.text }}</p>{% endfor %}
    {% for text in ens.items %}<p>{{ text }}</p>{% endfor %}
  </div>
</section>
{% endif %}

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": "FQ-2026-0419",
      "issue_date": "2026-09-18",
      "due_date": "2026-10-18",
      "currency": "EUR",
      "buyer_reference": "LNF-APP-2026",
      "order_reference": "PO-40277",
      "payment_terms": "Net 30 days",
      "delivery": {
        "date": "2026-09-16"
      },
      "seller": {
        "name": "Ferrow & Quay Studio Ltd",
        "trading_name": "Ferrow & Quay",
        "vat_id": "IE1234567FA",
        "legal_registration": {
          "id": "700419"
        },
        "electronic_address": {
          "id": "accounts@ferrowquay.example.com",
          "scheme": "EM"
        },
        "address": {
          "line1": "Studio 3, The Ropeworks",
          "line2": "14 Marsh Quay Lane",
          "city": "Cork",
          "postcode": "T12 X7Q4",
          "country": "IE"
        },
        "contact": {
          "name": "Studio accounts",
          "email": "accounts@ferrowquay.example.com"
        }
      },
      "buyer": {
        "name": "Lanternfield Health DAC",
        "vat_id": "IE7654321KA",
        "electronic_address": {
          "id": "payables@lanternfield.example.com",
          "scheme": "EM"
        },
        "address": {
          "line1": "Level 4, Weavers Hall",
          "line2": "61 Canal Terrace",
          "city": "Dublin",
          "postcode": "D08 R2Y6",
          "country": "IE"
        },
        "contact": {
          "name": "Niamh Corrigan"
        }
      },
      "payment": {
        "means_code": "58",
        "remittance_information": "FQ-2026-0419",
        "credit_transfers": [
          {
            "account_id": "IE00EXMP99000012345678",
            "account_name": "Ferrow & Quay Studio Ltd",
            "bic": "EXMPIE2D"
          }
        ]
      },
      "lines": [
        {
          "quantity": "5",
          "unit": "DAY",
          "price": {
            "net": "1150.00"
          },
          "tax": {
            "category": "S",
            "rate": "23"
          },
          "item": {
            "name": "Product design sprint",
            "description": "Workshops, journey maps and a tested concept"
          }
        },
        {
          "quantity": "24",
          "unit": "C62",
          "price": {
            "net": "265.00"
          },
          "tax": {
            "category": "S",
            "rate": "23"
          },
          "item": {
            "name": "App UI screens",
            "description": "High-fidelity iOS and Android, light and dark"
          }
        }
      ],
      "notes": [
        {
          "text": "Thank you for building the Lanternfield patient app with us."
        },
        {
          "text": "Questions about this invoice? Write to accounts@ferrowquay.example.com."
        }
      ]
    },
    "brand": {
      "tagline": "Product design & engineering",
      "primary": "#2b1a3d",
      "accent": "#ff8a5c",
      "accent_text": "#2b1a3d"
    },
    "website": "ferrowquay.example.com",
    "bank_name": "Harbourline Bank",
    "payment_link": "https://pay.example.com/i/FQ-2026-0419"
  },
  "output": {
    "format": "pdf",
    "filename": "invoice-bold-brand.pdf"
  }
}'