Was ist eine Vorlage?
Eine Rechnungsvorlage ist ein JSON-Dokument mit den Feldern version, name, page, body (Pflicht) sowie optional header, footer, styles. Beim/generate-Aufruf werden Invoice-Daten in die Platzhalter eingefügt und ein PDF (oder PDF/A-3 mit eingebettetem ZUGFeRD-XML) erzeugt.
9 Block-Typen
text, table, keyvalue, summary, image, spacer, line, qrcode, columns — alles mit {type, data}-Envelope, verschachtelbar über columns.
Platzhalter & Bedingungen
Flache Mustache-Syntax: {{invoiceNumber}}, {{seller.name}}. Suffix {{feld?}} = optional. condition-Property rendert Blöcke nur bei vorhandenen Werten.
Design-Tokens
page.colorScheme und page.fontSizes definieren benannte Tokens. Blöcke referenzieren sie via { token: 'primaryColor' } statt Hex-Werte — ein Mandant, ein Farbwechsel.
Hybrid-konform
Template liefert die visuelle Ebene; bei ZUGFeRD wird die strukturierte EN-16931-XML automatisch in das PDF/A-3 eingebettet. § 14 UStG-Pflichtangaben werden vor dem Render validiert.
Die 9 Block-Typen
Jeder Block folgt dem Envelope { type, data } und kann optional eine condition tragen, die den Block bei leeren Platzhaltern ausblendet.
| type | Zweck | Pflichtfelder in data |
|---|---|---|
text | Textabschnitt mit Platzhaltern, Style, Farbe, Ausrichtung | content |
table | Datengebundene Tabelle über Listen (Positionen, Steuerzeilen) | dataSource, columns |
keyvalue | Label-Wert-Paare — Rechnungskopf, Kundendaten, Zahlungsinfos | items[] |
summary | Summenblock mit dynamischen USt-Zeilen und Footer-Total | — (typisch: rows oder dynamicRows) |
image | Logo oder Grafik (URL, Base64 oder Platzhalter) | src |
spacer | Vertikaler Abstand in Punkten | height |
line | Horizontale Trennlinie mit Dicke und Farbe | — |
qrcode | QR-Code z. B. für SEPA-Girocode oder Zahlungslink | content |
columns | Mehrspaltiges Layout, verschachtelbare Blöcke | columns[] |
Platzhalter-Referenz
Alle Felder des Creator-Payloads sind im Template verfügbar. Optionalität markierst du mit {{feld?}}. Listen werden per dataSource an table oder summary gebunden.
Rechnungskopf
| Platzhalter | Typ | Beispiel | Beschreibung |
|---|---|---|---|
{{invoiceNumber}} | string | INV-2026-042 | Rechnungsnummer (§ 14 UStG) |
{{issueDate}} | date | 2026-04-14 | Ausstellungsdatum |
{{dueDate}} | date | 2026-05-14 | Zahlungsziel |
{{currency}} | string | EUR | ISO 4217 |
{{subtotal}} / {{total}} | number | 1500.00 / 1785.00 | Netto- bzw. Brutto-Summe |
Seller / Buyer (identische Struktur)
| Platzhalter | Typ | Beispiel | Beschreibung |
|---|---|---|---|
{{seller.name}}, {{buyer.name}} | string | ACME GmbH / Kunde AG | Firmenname (Pflicht) |
{{seller.street}}, {{buyer.street}} | string | Hauptstr. 1 | Straße (Pflicht) |
{{seller.postalCode}}, {{buyer.postalCode}} | string | 10115 | PLZ (Pflicht) |
{{seller.city}}, {{buyer.city}} | string | Berlin | Ort (Pflicht) |
{{seller.countryCode}}, {{buyer.countryCode}} | string | DE | ISO 3166-1 alpha-2 (Pflicht) |
{{seller.vatId?}}, {{buyer.vatId?}} | string | DE123456789 | EU-USt-IdNr., optional |
{{seller.taxId?}}, {{buyer.taxId?}} | string | 12/345/67890 | Nationale Steuernummer, optional |
{{seller.bankAccount.iban?}}, {{buyer.bankAccount.iban?}} | string | DE89… | IBAN (seller: Pflicht bei SEPA-Überweisung; buyer: Pflicht bei SEPA-Lastschrift) |
… | — | — | Weitere Felder beide Seiten: tradingName, additionalStreet, state, email, phone, website, bankAccount.bic/bankName/accountHolder — siehe Platzhalter-Referenz. |
Datenquellen für table / summary
| Platzhalter | Typ | Beispiel | Beschreibung |
|---|---|---|---|
{{items}} | array | — | Rechnungspositionen (dataSource für table-Block) |
{{taxSummary}} | array | — | Steuerzeilen (dataSource für summary.dynamicRows) |
item.field | any | description, quantity, netAmount, … | Spaltenbindung über field-Prop in table.columns |
Vorlage verwenden
Templates werden direkt am /api/v1/invoice/{countryCode}/{format}/generate übergeben — entweder per templateId (UUID einer gespeicherten Vorlage) oder inline via formatOptions.template. Priorität: templateId > formatOptions.template> Default.
Per templateId
Einmal in der Konsole oder via pdf.templateCreate anlegen, dann nur die UUID pro Request mitsenden.
1curl -X POST \2 https://service.invoice-api.xhub.io/api/v1/invoice/de/zugferd/generate \3 -H "Authorization: Bearer $XHUB_API_KEY" \4 -H "Content-Type: application/json" \5 -d '{6 "templateId": "b3c9a0d8-4f2e-4a1c-9e87-0d2f1a5b6c7d",7 "invoice": { /* ... Invoice-Payload (Creator-API) ... */ }8 }'Inline BlockTemplate
Template-JSON direkt mitsenden — nützlich für Tests, CI-Pipelines oder dynamisch generierte Layouts.
1curl -X POST \2 https://service.invoice-api.xhub.io/api/v1/invoice/de/zugferd/generate \3 -H "Authorization: Bearer $XHUB_API_KEY" \4 -H "Content-Type: application/json" \5 -d '{6 "invoice": { /* ... */ },7 "formatOptions": {8 "template": { /* inline BlockTemplate JSON */ }9 }10 }'Vertiefen
Detail-Referenzen, Branding-Rezepte und Compliance-Leitfaden.
Platzhalter-Referenz
Alle Felder aus dem Creator-Payload — Rechnungskopf, Seller, Buyer, Positionen, Steuerzeilen.
Branding
Logo, Farben via Design-Tokens, Header/Footer, benannte Styles.
Compliance
§ 14 UStG Pflichtangaben, Format-Matrix für XRechnung / ZUGFeRD / Peppol.
Cookbook
SEPA-QR, Rabatt-Spalte, Seitenzahlen, dynamische USt-Zeilen — kopierfertig.
