Ratgeber für Entwickler

ZUGFeRD erstellen: Profile, Unterschiede und API-Beispiel

ZUGFeRD kombiniert ein maschinenlesbares XML mit einer PDF-Datei in einem einzigen Dokument. Dieser Artikel erklärt die Profile, den Unterschied zu XRechnung UBL und wie du ZUGFeRD-Rechnungen direkt über eine REST-API erzeugst.

Nur eine Rechnung prüfen?

Nutze den Web-Validator für schnelle Browser-Tests mit XML oder ZUGFeRD-PDF.

Zum Validator

E-Rechnungen automatisieren?

Nutze die API für wiederkehrende Validierung, Erzeugung und Abruf in deiner Software.

Zur Entwicklerseite

Was ist ZUGFeRD?

ZUGFeRD (Zentraler User Guide des Forums elektronische Rechnung Deutschland) ist ein Hybridformat: Eine PDF/A-3-Datei enthält eingebettet eine XML-Datei nach dem Cross Industry Invoice (CII) Standard. Das Ergebnis ist für Menschen lesbar (PDF) und gleichzeitig maschinell verarbeitbar (XML).

Das Format basiert auf dem europäischen Standard EN 16931 und ist damit grenzüberschreitend einsetzbar. Factur-X, das französische Äquivalent, ist technisch identisch – nur der Name unterscheidet sich.

ZUGFeRD-Profile im Überblick

ZUGFeRD 2.x kennt mehrere Profile mit steigenden Datenanforderungen:

  • MINIMUM – Nur gesetzlich vorgeschriebene Pflichtfelder. Nicht EN-16931-konform, aber für viele interne Zwecke ausreichend.
  • BASIC WL – Erweitertes Minimum, noch ohne Positionsdaten. Geeignet für Sammelrechnungen.
  • BASIC – Positionsebene vorhanden, EN-16931-konform. Empfehlenswert für den Einstieg.
  • EN 16931 (Comfort) – Vollständige Umsetzung des europäischen Standards mit optionalen Erweiterungen.
  • EXTENDED – Zusätzliche Felder über EN 16931 hinaus, z. B. für Logistik oder Baugewerbe.
  • XRECHNUNG – Entspricht dem deutschen XRechnung-Standard, aber im CII-Format statt UBL.

Für den deutschen B2G-Bereich (Rechnungen an Behörden) ist das Profil XRECHNUNG oder die separate XRechnung UBL-Variante vorgeschrieben.

Die API von xinvoice.net erzeugt Rechnungen wahlweise im Profil EN16931 oder XRECHNUNG.

ZUGFeRD vs. XRechnung UBL – was nehmen?

XRechnung UBL ist ein reines XML-Format ohne PDF. ZUGFeRD XRECHNUNG-Profil liefert dasselbe XML, aber als eingebettetes Dokument in einem PDF. Beide Varianten sind für B2G in Deutschland zugelassen.

Für B2B ist ZUGFeRD die flexiblere Wahl: Der Empfänger kann das Dokument wie eine normale PDF-Rechnung verarbeiten, ohne zwingend eine Software zur XML-Verarbeitung zu benötigen. Die XML-Daten sind trotzdem vorhanden und können verarbeitet werden, wenn die Gegenseite dazu in der Lage ist.

ZUGFeRD per API erzeugen – Beispiel

Die XInvoice API erzeugt ZUGFeRD-Rechnungen über einen einzigen POST-Request. Die Rechnungsdaten werden als JSON übergeben, das Format und (optional) das Profil werden ebenfalls im Body angegeben:

curl -X POST https://api.xinvoice.net/v1/invoices/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "format": "zugferd",
    "profile": "EN16931",
    "seller": {
      "name": "Muster GmbH",
      "address": { "street": "Musterstraße 1", "city": "Berlin", "zip": "10115", "country": "DE" },
      "tax_number": "12/345/67890",
      "vat_id": "DE123456789"
    },
    "buyer": {
      "name": "Kunde AG",
      "address": { "street": "Kundenweg 5", "city": "Hamburg", "zip": "20095", "country": "DE" }
    },
    "invoice_number": "2025-0042",
    "issue_date": "2025-04-01",
    "due_date": "2025-04-30",
    "lines": [
      { "description": "Beratungsleistung April", "quantity": 8, "unit_price": 150.00, "tax_rate": 19 }
    ]
  }'
ZUGFeRD EN16931-Rechnung per API erzeugen

Die API gibt eine invoice_id zurück. Das fertige PDF mit eingebettetem ZUGFeRD-XML kannst du anschließend unter GET /v1/invoices/{id}/download abrufen.

Alternativ kannst du auch beim Prüfen des Status' den URL-Parameter ?include_pdf_data=1 an den Endpunkt /v1/invoices/{id} anhängen. Dann enthält der JSON-Response bereits die PDF-Datei als base64-encoded String, sobald die Rechnung fertig ist.

Asynchrone Erzeugung für hohe Volumina

Bei großen Rechnungsmengen nutzt du die asynchrone API: Der POST-Request liefert sofort eine invoice_id zurück, ohne auf die PDF-Erzeugung zu warten. Du pollst den Status per GET /v1/invoices/{id} und lädst das Dokument herunter, sobald status: "completed" zurückkommt.

Das entkoppelt die Rechnungserzeugung von deinem Request-Response-Zyklus und macht den Prozess skalierbar.