Skip to content

210 × 297 mm

Invoices

EU reverse-charge invoice

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

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
  • 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: 4 top-level fields, 68 paths in total. Send the same shape as data.

PathTypeExample
invoiceobject
invoice.numberstring"SLS-2026-0412"
invoice.issue_datedate"2026-09-04"
invoice.due_datedate"2026-10-04"
invoice.currencystring"EUR"
invoice.buyer_referencestring"PO 4500-2291"
invoice.payment_termsstring"Payment within 30 days of the invoice date by …"
invoice.deliveryobject
invoice.delivery.datedate"2026-08-31"
invoice.sellerobject
invoice.seller.namestring"Saltmarsh Language Services Ltd"
invoice.seller.trading_namestring"Saltmarsh Language Services"
invoice.seller.vat_idstring"IE1234567T"
invoice.seller.legal_registrationobject
invoice.seller.legal_registration.idstring"123456"
invoice.seller.legal_infostring"Registered in Ireland, company no. 123456"
invoice.seller.electronic_addressobject
invoice.seller.electronic_address.idstring"accounts@saltmarsh.example.com"
invoice.seller.electronic_address.schemestring"EM"
invoice.seller.addressobject
invoice.seller.address.line1string"Unit 7, Claddagh Quay Business Park"
invoice.seller.address.citystring"Galway"
invoice.seller.address.postcodestring"H91 X2Y3"
invoice.seller.address.countrystring"IE"
invoice.seller.contactobject
invoice.seller.contact.namestring"Accounts"
invoice.seller.contact.emailstring"accounts@saltmarsh.example.com"
invoice.buyerobject
invoice.buyer.namestring"Lindgrün Gartenmöbel GmbH"
invoice.buyer.vat_idstring"DE123456789"
invoice.buyer.electronic_addressobject
invoice.buyer.electronic_address.idstring"rechnungen@lindgruen.example.com"
invoice.buyer.electronic_address.schemestring"EM"
invoice.buyer.addressobject
invoice.buyer.address.line1string"Hafenstraße 12"
invoice.buyer.address.citystring"Hamburg"
invoice.buyer.address.postcodestring"20457"
invoice.buyer.address.countrystring"DE"
invoice.buyer.contactobject
invoice.buyer.contact.namestring"Katrin Vogelsang, Marketing & E-Commerce"
invoice.paymentobject
invoice.payment.means_codestring"58"
invoice.payment.remittance_informationstring"SLS-2026-0412"
invoice.payment.credit_transfersarray<object> · 1
invoice.payment.credit_transfers[].account_idstring"IE74EXMP99000012345678"
invoice.payment.credit_transfers[].account_namestring"Saltmarsh Language Services Ltd"
invoice.payment.credit_transfers[].bicstring"EXMPIE2D"
invoice.vat_exemptionsobject
invoice.vat_exemptions.AEobject
invoice.vat_exemptions.AE.reasonstring"Reverse charge (Article 196, Council Directive…"
invoice.vat_exemptions.AE.reason_codestring"VATEX-EU-AE"
invoice.linesarray<object> · 6
invoice.lines[].quantitystring"18400"
invoice.lines[].unitstring"D68"
invoice.lines[].priceobject
invoice.lines[].price.netstring"0.12"
invoice.lines[].taxobject
invoice.lines[].tax.categorystring"AE"
invoice.lines[].tax.ratestring"0"
invoice.lines[].itemobject
invoice.lines[].item.namestring"Product catalogue translation, German to Engli…"
invoice.lines[].item.descriptionstring"Autumn/winter range, 412 product pages"
invoice.notesarray<object> · 2
invoice.notes[].textstring"Supply of services to a business customer esta…"
invoice.notes[].subject_code?string"TXD"
servicesstring"Translation · Localisation · Typesetting"
websitestring"saltmarsh.example.com"
bank_namestring"Corrib Mutual Bank"

Sample data

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

data.json
{
  "invoice": {
    "number": "SLS-2026-0412",
    "issue_date": "2026-09-04",
    "due_date": "2026-10-04",
    "currency": "EUR",
    "buyer_reference": "PO 4500-2291",
    "payment_terms": "Payment within 30 days of the invoice date by SEPA credit transfer. Bank charges on international transfers are paid by the sender.",
    "delivery": {
      "date": "2026-08-31"
    },
    "seller": {
      "name": "Saltmarsh Language Services Ltd",
      "trading_name": "Saltmarsh Language Services",
      "vat_id": "IE1234567T",
      "legal_registration": {
        "id": "123456"
      },
      "legal_info": "Registered in Ireland, company no. 123456",
      "electronic_address": {
        "id": "accounts@saltmarsh.example.com",
        "scheme": "EM"
      },
      "address": {
        "line1": "Unit 7, Claddagh Quay Business Park",
        "city": "Galway",
        "postcode": "H91 X2Y3",
        "country": "IE"
      },
      "contact": {
        "name": "Accounts",
        "email": "accounts@saltmarsh.example.com"
      }
    },
    "buyer": {
      "name": "Lindgrün Gartenmöbel GmbH",
      "vat_id": "DE123456789",
      "electronic_address": {
        "id": "rechnungen@lindgruen.example.com",
        "scheme": "EM"
      },
      "address": {
        "line1": "Hafenstraße 12",
        "city": "Hamburg",
        "postcode": "20457",
        "country": "DE"
      },
      "contact": {
        "name": "Katrin Vogelsang, Marketing & E-Commerce"
      }
    },
    "payment": {
      "means_code": "58",
      "remittance_information": "SLS-2026-0412",
      "credit_transfers": [
        {
          "account_id": "IE74EXMP99000012345678",
          "account_name": "Saltmarsh Language Services Ltd",
          "bic": "EXMPIE2D"
        }
      ]
    },
    "vat_exemptions": {
      "AE": {
        "reason": "Reverse charge (Article 196, Council Directive 2006/112/EC)",
        "reason_code": "VATEX-EU-AE"
      }
    },
    "lines": [
      {
        "quantity": "18400",
        "unit": "D68",
        "price": { "net": "0.12" },
        "tax": { "category": "AE", "rate": "0" },
        "item": {
          "name": "Product catalogue translation, German to English",
          "description": "Autumn/winter range, 412 product pages"
        }
      },
      {
        "quantity": "3250",
        "unit": "D68",
        "price": { "net": "0.14" },
        "tax": { "category": "AE", "rate": "0" },
        "item": {
          "name": "Web shop interface localisation, German to English",
          "description": "Checkout, customer account area and transactional e-mails"
        }
      },
      {
        "quantity": "1",
        "unit": "LS",
        "price": { "net": "450.00" },
        "tax": { "category": "AE", "rate": "0" },
        "item": {
          "name": "Terminology glossary",
          "description": "420 approved garden furniture terms with definitions and usage notes"
        }
      },
      {
        "quantity": "12.5",
        "unit": "HUR",
        "price": { "net": "58.50" },
        "tax": { "category": "AE", "rate": "0" },
        "item": {
          "name": "In-context linguistic review",
          "description": "Review on the staging shop, 38 corrections logged and verified"
        }
      },
      {
        "quantity": "24",
        "unit": "ZP",
        "price": { "net": "18.50" },
        "tax": { "category": "AE", "rate": "0" },
        "item": {
          "name": "Brochure typesetting, English edition",
          "description": "24-page printed brochure, print-ready PDF with bleed"
        }
      },
      {
        "quantity": "6",
        "unit": "HUR",
        "price": { "net": "65.00" },
        "tax": { "category": "AE", "rate": "0" },
        "item": {
          "name": "Project management"
        }
      }
    ],
    "notes": [
      {
        "text": "Supply of services to a business customer established in another EU Member State. No Irish VAT has been charged: the customer is responsible for accounting for VAT under the reverse-charge rules in their own country.",
        "subject_code": "TXD"
      },
      {
        "text": "Thank you for choosing Saltmarsh for the autumn/winter launch."
      }
    ]
  },
  "services": "Translation · Localisation · Typesetting",
  "website": "saltmarsh.example.com",
  "bank_name": "Corrib Mutual Bank"
}

Source

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

{#- Cross-border EU B2B invoice rendered from the EN 16931 invoice model (`invoice`, proto/einvoice/invoice.schema.json).
    Lines in VAT category AE (reverse charge, rate 0) print the reverse-charge notice: the invoice notes with subject
    code TXD plus the exemption reason from `vat_exemptions.AE`; lines in category S are charged at their rate.
    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) and `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. The amount in words is built from whole euro and cents of
    the amount due, so the words always match the figure. `services`, `website` and `bank_name` are display-only
    extras outside the invoice model. -#}
{%- set inv = invoice -%}
{%- set cur = inv.currency -%}
{%- set loc = "en-IE" -%}
{%- 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"]} -%}
{%- set countries = {"IE": "Ireland", "DE": "Germany", "FR": "France", "NL": "Netherlands", "BE": "Belgium", "AT": "Austria", "ES": "Spain", "IT": "Italy", "PL": "Poland", "PT": "Portugal", "DK": "Denmark", "SE": "Sweden", "FI": "Finland", "LU": "Luxembourg"} -%}
{%- set profiles = {"MINIMUM": "Factur-X MINIMUM", "BASIC_WL": "Factur-X BASIC WL", "BASIC": "ZUGFeRD / Factur-X BASIC", "EN16931": "ZUGFeRD / Factur-X EN 16931", "EXTENDED": "ZUGFeRD / Factur-X EXTENDED", "XRECHNUNG": "XRechnung"} -%}
{%- set exemptions = {"Z": "zero rated", "E": "exempt", "AE": "reverse charge", "K": "intra-community supply", "G": "export", "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 reverse_charge = breakdown | selectattr("category", "equalto", "AE") | list | length > 0 -%}
{%- set supply_date = (inv.delivery.date if (inv.delivery and inv.delivery.date) else none) or inv.tax_point_date or (inv.invoice_period.end if inv.invoice_period else none) -%}
{%- set total_cents = ((totals.due_payable | float) * 100) | round | int -%}
{%- set whole_units = total_cents // 100 -%}
{%- set cents = total_cents % 100 -%}

{%- macro money(value) -%}{{ value | format_currency(cur, loc) }}{%- endmacro -%}
{%- macro day(value) -%}{{ value | format_date("long", loc) }}{%- endmacro -%}
{%- macro vat_chip(vat_id) -%}
<span class="vat-chip"><span class="cc">{{ vat_id[:2] }}</span>{{ vat_id[2:] }}</span>
{%- endmacro -%}
{%- macro address(party) -%}
  {% if party.address.line1 %}{{ party.address.line1 }}<br>{% endif %}
  {% if party.address.line2 %}{{ party.address.line2 }}<br>{% endif %}
  {% if party.address.country in ["IE", "GB"] %}{{ party.address.city }} {{ party.address.postcode }}{% else %}{{ party.address.postcode }} {{ party.address.city }}{% endif %}<br>
  {{ countries[party.address.country] or party.address.country }}
{%- endmacro -%}
{%- macro grouped(value) -%}
  {%- for i in range(0, value | length, 4) -%}{{ value[i:i + 4] }}{{ " " if not loop.last }}{%- endfor -%}
{%- endmacro -%}

<header class="top">
  <div class="brand">
    <svg class="mark" viewBox="0 0 48 48" aria-hidden="true">
      <circle cx="24" cy="24" r="22" fill="#1d5c52"/>
      <path d="M9 27c4-4 8-4 11 0s7 4 10 0 7-4 9-1" fill="none" stroke="#ffffff" stroke-width="2.6" stroke-linecap="round"/>
      <path d="M11 33c3.5-3 7-3 9.5 0s6.5 3 9 0 6-3 8 -0.5" fill="none" stroke="#9cc8bd" stroke-width="2.2" stroke-linecap="round"/>
      <circle cx="31" cy="15.5" r="3.2" fill="#e8c26a"/>
    </svg>
    <div>
      <div class="brand-name">{{ inv.seller.trading_name or inv.seller.name }}</div>
      {% if services is defined and services %}<div class="brand-sub">{{ services }}</div>{% endif %}
    </div>
  </div>
  <div class="title">
    <h1>{{ "Credit note" if inv.type_code in ["381", "261"] else "Invoice" }}</h1>
    <div class="title-no">No. {{ inv.number }}</div>
  </div>
</header>

<table class="facts" role="presentation">
  <tr>
    <td><span class="k">Invoice date</span><span class="v">{{ day(inv.issue_date) }}</span></td>
    <td><span class="k">Date of supply</span><span class="v">{{ day(supply_date) if supply_date else "—" }}</span></td>
    <td><span class="k">Payment due</span><span class="v">{{ day(inv.due_date) if inv.due_date else "—" }}</span></td>
    <td><span class="k">Your reference</span><span class="v">{{ inv.buyer_reference or inv.order_reference or "—" }}</span></td>
  </tr>
</table>

<section class="parties">
  <div class="party">
    <h2>Supplier</h2>
    <p class="party-name">{{ inv.seller.name }}</p>
    <p>{{ address(inv.seller) }}</p>
    {% if inv.seller.vat_id %}<p class="ids">VAT ID {{ vat_chip(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 class="party">
    <h2>Customer</h2>
    <p class="party-name">{{ inv.buyer.name }}</p>
    {% if inv.buyer.contact and inv.buyer.contact.name %}<p class="muted">{{ inv.buyer.contact.name }}</p>{% endif %}
    <p>{{ address(inv.buyer) }}</p>
    {% if inv.buyer.vat_id %}<p class="ids">VAT ID {{ vat_chip(inv.buyer.vat_id) }}</p>{% endif %}
  </div>
</section>

<table class="lines">
  <thead>
    <tr>
      <th class="idx" scope="col">#</th>
      <th scope="col">Description</th>
      <th class="num" scope="col">Quantity</th>
      <th class="num" scope="col">Unit price</th>
      <th class="num" scope="col">VAT</th>
      <th class="num" scope="col">Net amount</th>
    </tr>
  </thead>
  <tbody>
    {% for line in inv.lines %}
    {%- set q = line.quantity | float -%}
    {%- set names = units[line.unit or "C62"] -%}
    <tr>
      <td class="idx">{{ "%02d" | format(loop.index) }}</td>
      <td>
        <span class="desc">{{ line.item.name }}</span>
        {% if line.item.description %}<span class="details">{{ line.item.description }}</span>{% endif %}
        {% for a in line.allowances | default([]) %}<span class="details">Less {{ a.reason or "discount" }}: {{ money(a.amount) }}</span>{% endfor %}
        {% for c in line.charges | default([]) %}<span class="details">Plus {{ c.reason or "charge" }}: {{ money(c.amount) }}</span>{% endfor %}
      </td>
      <td class="num">
        {{ q | format_number(loc, 0 if q == q | int else 2) }}
        <span class="unit">{% if names %}{{ names[0] if q == 1 else names[1] }}{% else %}{{ line.unit }}{% endif %}</span>
      </td>
      <td class="num">{{ money(line.price.net) }}</td>
      <td class="num">{{ (line.tax.rate | default(0) | float) | format_number(loc) }}%</td>
      <td class="num">{{ money(ns.nets[loop.index0]) }}</td>
    </tr>
    {% endfor %}
  </tbody>
</table>

<section class="summary">
  <div class="in-words">
    <h2>Amount due in words</h2>
    <p>
      {{ whole_units | number_to_words("en") | capitalize }} {{ "euro" if cur == "EUR" else cur }}{% if cents %} and {{ cents | number_to_words("en") }} {{ "cent" if cur == "EUR" else "hundredths" }}{% endif %}
    </p>
  </div>
  <table class="totals">
    {% if (totals.allowance_total | float) != 0 or (totals.charge_total | float) != 0 %}
    <tr><th scope="row">Sum of lines</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 %}
    {% endif %}
    <tr><th scope="row">Net total</th><td class="num">{{ money(totals.tax_basis_total) }}</td></tr>
    {% for b in breakdown %}
    <tr>
      <th scope="row">VAT {{ (b.rate | float) | format_number(loc) }}%{% if b.category in exemptions %} · {{ exemptions[b.category] }}{% endif %}{% if breakdown | length > 1 %} on {{ money(b.basis) }}{% endif %}</th>
      <td class="num">{{ money(b.tax) }}</td>
    </tr>
    {% endfor %}
    {% if (totals.prepaid | float) != 0 %}
    <tr><th scope="row">Total</th><td class="num">{{ money(totals.grand_total) }}</td></tr>
    <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 %}
    <tr class="grand"><th scope="row">Total due ({{ cur }})</th><td class="num">{{ money(totals.due_payable) }}</td></tr>
  </table>
</section>

{% if reverse_charge %}
{%- set exemption = inv.vat_exemptions.AE if (inv.vat_exemptions and inv.vat_exemptions.AE) else none -%}
<aside class="notice">
  <svg class="notice-icon" viewBox="0 0 24 24" aria-hidden="true">
    <path d="M4 9h13l-3.5-3.5M20 15H7l3.5 3.5" fill="none" stroke="#1d5c52" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
  </svg>
  <div>
    <p class="notice-title">Reverse charge</p>
    {% for note in inv.notes | default([]) if note.subject_code == "TXD" %}<p>{{ note.text }}</p>{% endfor %}
    {% if exemption and exemption.reason %}<p class="notice-basis">{{ exemption.reason }}</p>{% endif %}
    <p class="notice-ids">Supplier VAT ID {{ inv.seller.vat_id }} · Customer VAT ID {{ inv.buyer.vat_id }}</p>
  </div>
</aside>
{% endif %}

{% if inv.payment %}
<section class="payment">
  <div class="pay-head">
    <h2>Bank transfer</h2>
    <p>Pay {{ money(totals.due_payable) }}{% if inv.due_date %} by {{ day(inv.due_date) }}{% endif %}</p>
  </div>
  <dl>
    {% for account in inv.payment.credit_transfers | default([]) %}
    <div><dt>Account name</dt><dd>{{ account.account_name or inv.seller.name }}</dd></div>
    {% if loop.first and bank_name is defined and bank_name %}<div><dt>Bank</dt><dd>{{ bank_name }}</dd></div>{% endif %}
    <div><dt>{{ "IBAN" if (account.account_id | length) >= 15 else "Account" }}</dt><dd class="mono">{{ grouped(account.account_id) }}</dd></div>
    {% if account.bic %}<div><dt>BIC</dt><dd class="mono">{{ account.bic }}</dd></div>{% endif %}
    {% endfor %}
    <div><dt>Payment reference</dt><dd class="mono">{{ inv.payment.remittance_information or inv.number }}</dd></div>
  </dl>
</section>
{% endif %}

<section class="notes">
  {% if inv.payment_terms %}<p>{{ inv.payment_terms }}</p>{% endif %}
  {% for note in inv.notes | default([]) if note.subject_code != "TXD" %}<p>{{ note.text }}</p>{% endfor %}
  {% if embedded %}<p class="einvoice-hint">This PDF carries an embedded e-invoice ({{ profiles[embedded.profile] or embedded.profile }} XML).</p>{% endif %}
</section>

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": "SLS-2026-0412",
      "issue_date": "2026-09-04",
      "due_date": "2026-10-04",
      "currency": "EUR",
      "buyer_reference": "PO 4500-2291",
      "payment_terms": "Payment within 30 days of the invoice date by SEPA credit transfer. Bank charges on international transfers are paid by the sender.",
      "delivery": {
        "date": "2026-08-31"
      },
      "seller": {
        "name": "Saltmarsh Language Services Ltd",
        "trading_name": "Saltmarsh Language Services",
        "vat_id": "IE1234567T",
        "legal_registration": {
          "id": "123456"
        },
        "legal_info": "Registered in Ireland, company no. 123456",
        "electronic_address": {
          "id": "accounts@saltmarsh.example.com",
          "scheme": "EM"
        },
        "address": {
          "line1": "Unit 7, Claddagh Quay Business Park",
          "city": "Galway",
          "postcode": "H91 X2Y3",
          "country": "IE"
        },
        "contact": {
          "name": "Accounts",
          "email": "accounts@saltmarsh.example.com"
        }
      },
      "buyer": {
        "name": "Lindgrün Gartenmöbel GmbH",
        "vat_id": "DE123456789",
        "electronic_address": {
          "id": "rechnungen@lindgruen.example.com",
          "scheme": "EM"
        },
        "address": {
          "line1": "Hafenstraße 12",
          "city": "Hamburg",
          "postcode": "20457",
          "country": "DE"
        },
        "contact": {
          "name": "Katrin Vogelsang, Marketing & E-Commerce"
        }
      },
      "payment": {
        "means_code": "58",
        "remittance_information": "SLS-2026-0412",
        "credit_transfers": [
          {
            "account_id": "IE74EXMP99000012345678",
            "account_name": "Saltmarsh Language Services Ltd",
            "bic": "EXMPIE2D"
          }
        ]
      },
      "vat_exemptions": {
        "AE": {
          "reason": "Reverse charge (Article 196, Council Directive 2006/112/EC)",
          "reason_code": "VATEX-EU-AE"
        }
      },
      "lines": [
        {
          "quantity": "18400",
          "unit": "D68",
          "price": {
            "net": "0.12"
          },
          "tax": {
            "category": "AE",
            "rate": "0"
          },
          "item": {
            "name": "Product catalogue translation, German to English",
            "description": "Autumn/winter range, 412 product pages"
          }
        },
        {
          "quantity": "3250",
          "unit": "D68",
          "price": {
            "net": "0.14"
          },
          "tax": {
            "category": "AE",
            "rate": "0"
          },
          "item": {
            "name": "Web shop interface localisation, German to English",
            "description": "Checkout, customer account area and transactional e-mails"
          }
        }
      ],
      "notes": [
        {
          "text": "Supply of services to a business customer established in another EU Member State. No Irish VAT has been charged: the customer is responsible for accounting for VAT under the reverse-charge rules in their own country.",
          "subject_code": "TXD"
        },
        {
          "text": "Thank you for choosing Saltmarsh for the autumn/winter launch."
        }
      ]
    },
    "services": "Translation · Localisation · Typesetting",
    "website": "saltmarsh.example.com",
    "bank_name": "Corrib Mutual Bank"
  },
  "output": {
    "format": "pdf",
    "filename": "invoice-eu-reverse-charge.pdf"
  }
}'