Ein ZUGFeRD-Dokument ist ein PDF/A-3b, in das das CII-XML nach EN 16931 als benannte Datei eingebettet ist (bei ZUGFeRD 2.1+/Factur-X: factur-x.xml), mit einer Dokument-Zuordnung (AFRelationship) und einem XMP-Extension-Schema, das Profil und Dateinamen deklariert. Selbst gebaut ist das fehleranfällig — PDF/A-3b-Konformität, XMP und Beleg-XML-Konsistenz müssen exakt stimmen. Über eine API bekommst du das fertige PDF/A-3 aus einem Call.

Ein ZUGFeRD-Dokument sieht aus wie ein PDF — technisch ist es ein PDF/A-3b mit einer eingebetteten XML-Datei. Genau diese Einbettung ist der Teil, an dem selbstgebaute Lösungen scheitern: Die Bytes müssen an der richtigen Stelle stehen, richtig benannt und richtig zugeordnet sein, sonst lehnt der Empfänger die Datei ab. Dieser Beitrag zeigt, wie das XML ins PDF kommt — und wie du dir den Embedder sparst.

Was „ZUGFeRD-PDF/A-3“ konkret bedeutet

ZUGFeRD (bzw. Factur-X) ist ein hybrides Format: ein für Menschen lesbares PDF plus ein für Maschinen lesbares CII-XML nach EN 16931, beides in einer Datei. Damit das funktioniert, sind drei Dinge gleichzeitig wahr:

  1. Die Hülle ist ein PDF/A-3b. PDF/A ist das Archivprofil von PDF (eingebettete Schriften, definierter Farbraum, keine externen Abhängigkeiten). Nur die Version 3 erlaubt beliebige eingebettete Dateien — die Vorgänger PDF/A-1 und A-2 nicht. Die Stufe b (basic) verlangt visuelle Reproduzierbarkeit, nicht die volle Tag-Struktur von Stufe a.
  2. Das CII-XML liegt als eingebettete Datei drin. Nicht als Anhang „irgendwo“, sondern als EmbeddedFile mit einer Dokument-Zuordnung (AFRelationship, meist Data) auf Dokumentebene, damit ein Reader die Rechnung als das führende Nutzdatum erkennt.
  3. Der Metadaten-Stream deklariert das Format. Ein XMP-Extension-Schema im PDF-Metadaten-Block nennt DocumentType (INVOICE), DocumentFileName, Version und ConformanceLevel (also das ZUGFeRD-Profil).

Der Dateiname ist normiert — nicht frei wählbar

Die eingebettete XML-Datei muss exakt heißen, wie es der jeweilige Standard vorschreibt. Das ist ein häufiger, stiller Fehler:

StandardstandDateiname der eingebetteten XML
ZUGFeRD 1.0ZUGFeRD-invoice.xml
ZUGFeRD 2.0zugferd-invoice.xml
ZUGFeRD 2.1+ / Factur-Xfactur-x.xml

Weicht der Name ab, findet der Empfänger das strukturierte Original nicht — das PDF gilt dann als reines Bild-PDF und erfüllt die E-Rechnungspflicht nicht.

Warum der sichtbare Teil und das XML deckungsgleich sein müssen

Unter der E-Rechnungspflicht ist bei einem hybriden Beleg das XML der führende, maßgebliche Teil — das PDF ist die visuelle Kopie. Weichen Sichtbeleg und XML voneinander ab (andere Summe, anderes Datum), ist das ein echtes Problem, kein Schönheitsfehler. Deshalb sollten beide aus derselben Datenquelle entstehen und nicht getrennt gerendert werden.

Der pragmatische Weg: per API statt Embedder selbst bauen

Du kannst PDF/A-3b-Konformität, XMP-Extension-Schema, AFRelationship und die Namenskonvention mit einer PDF-Bibliothek selbst zusammensetzen — und jede Format-Aktualisierung selbst nachziehen. Oder du delegierst die Erzeugung an eine E-Rechnung API. Der Flow ist derselbe wie bei ZUGFeRD/Factur-X per API:

1) Rechnung anlegen — Kunde und Positionen; der Server rechnet Summen und USt.

HTTP
POST /invoices
Authorization: Bearer sk_test_…
Idempotency-Key: 6f1c2a…
Content-Type: application/json

{
  "currency": "EUR",
  "buyer": {
    "name": "Achsfeld Transporte GmbH",
    "addressLine1": "Gewerbestraße 8",
    "postalCode": "59192",
    "city": "Bergkamen",
    "countryCode": "DE"
  },
  "invoiceTypeCode": "380",
  "deliveryDate": "2026-07-31",
  "lineItems": [
    { "description": "Ladevorgänge Juli 2026", "quantity": "1",
      "unitCode": "C62", "unitPriceNet": "420.00", "taxRatePercent": "19" }
  ]
}

2) Ausstellen — die Nummer wird atomar vergeben; aus einem EN-16931-Datenmodell entsteht das ZUGFeRD-PDF/A-3 mit dem eingebetteten CII-XML — Sichtbeleg und strukturierte Daten stammen aus einer Quelle und sind deshalb deckungsgleich:

HTTP
PATCH /invoices/{id}/finalize
Authorization: Bearer sk_test_…

3) PDF/A-3 abholen — die fertige hybride Datei:

HTTP
GET /invoices/{id}/pdf
Authorization: Bearer sk_test_…
# → application/pdf: PDF/A-3b mit eingebettetem factur-x.xml

Brauchst du für die Vorschau ein Bild vor dem Ausstellen, liefert GET /invoices/{id}/preview.pdf einen nicht persistierten, gewässerzeichneten Entwurf mit demselben Renderer — die Vorschau ist byte-treu zu dem, was das Finalisieren erzeugt.

Woran du eine korrekte ZUGFeRD-PDF erkennst

  • PDF/A-3b, nicht A-2 oder ein „normales“ PDF (per Preflight prüfbar).
  • Genau eine eingebettete XML mit dem normkonformen Dateinamen (factur-x.xml bei aktuellen Profilen).
  • XMP-Extension-Schema vorhanden, mit passendem ConformanceLevel (Profil).
  • Das eingebettete XML ist valides CII nach EN 16931 — wie du das prüfst, steht unter KoSIT-Validierung erklärt.

Fortlauf erzeugt aktuelle ZUGFeRD-2.x-Profile als PDF/A-3b serverseitig und preflight-geprüft, aus demselben Datenmodell wie die XRechnung — kein zweiter Renderpfad, keine Divergenz zwischen PDF und XML.

Der gezeigte Code ist illustrativ: Die vollständige Dokumentation steht dir in der API-Referenz zur Verfügung. Base-URL und Test-Key bekommst du mit dem Sandbox-Zugang im Entwickler-Bereich.

Selbst ausprobieren? Der Zugang ist kostenlos und ohne Karte — Produkt-Einstieg für Entwickler →

Oder den eigenen Abrechnungsfluss konkret durchsprechen: 30 Min, technisch, mit dem Gründer →

Häufige Fragen

Wie kommt das XML in eine ZUGFeRD-PDF?
Das CII-XML wird als eingebettete Datei (EmbeddedFile) in ein PDF/A-3b gelegt und auf Dokumentebene über AFRelationship zugeordnet. Ein XMP-Extension-Schema im Metadaten-Stream deklariert Profil (ConformanceLevel), Version und Dateinamen. Der Dateiname folgt der Konvention: factur-x.xml ab ZUGFeRD 2.1/Factur-X, zugferd-invoice.xml bei ZUGFeRD 2.0.
Warum PDF/A-3 und nicht ein normales PDF?
Nur PDF/A-3 erlaubt beliebige eingebettete Dateien und garantiert zugleich die Langzeit-Reproduzierbarkeit (eingebettete Schriften, definierter Farbraum). PDF/A-2 lässt eingebettete Fremddateien nicht zu. ZUGFeRD verlangt konkret die Konformitätsstufe PDF/A-3b (visuell reproduzierbar), nicht A-3a.
Kann ich ZUGFeRD-PDF/A-3 mit einer Standard-PDF-Bibliothek erzeugen?
Technisch ja, aber du trägst dann die Fehlerquellen selbst: PDF/A-3b-Preflight, das korrekte XMP-Extension-Schema, die richtige AFRelationship, der normkonforme Dateiname und vor allem die Konsistenz zwischen sichtbarem PDF und eingebettetem XML. Eine API kapselt diese Regeln; du schickst die Rechnungsdaten und bekommst ein valides PDF/A-3 zurück.