Invoir
  1. Home
  2. Guides
  3. ZUGFeRD

ZUGFeRD: the hybrid PDF e-invoice, explained for developers

A ZUGFeRD invoice looks like any PDF invoice, but it carries the full invoice data as XML inside the file. People read the PDF, software reads the XML. This page covers what is in the file, which profile to pick, and how to check one.

Updated 19 October 2026

What a ZUGFeRD file is

ZUGFeRD is published by FeRD, the Forum elektronische Rechnung Deutschland, together with the French FNFE-MPE, which publishes the same format as Factur-X. The two are technically identical: a valid Factur-X file is a valid ZUGFeRD file of the same profile.

For invoices between German businesses the XML is the part that counts. The German Federal Ministry of Finance (BMF) states that if the PDF and the XML of a hybrid invoice differ, the data in the XML prevails (BMF FAQ, question 12a). A pretty PDF with a sloppy XML is a wrong invoice.

Versions

ZUGFeRDFactur-XStatus
2.5.21.09.2Current. Published 4 August 2026, to be used from 1 September 2026 (FeRD).
2.41.08Published 4 December 2025, in the FeRD version archive.
2.0.1 – 2.3.x1.0 – 1.0.07Older 2.x releases; minor versions are backward compatible.
1.0–2014, different XML. Not accepted as an e-invoice under German VAT law.

The BMF accepts ZUGFeRD from version 2.0.1 as an e-invoice. New releases mostly follow the EN 16931 code-list updates, which the European Commission publishes twice a year, so plan for a version bump every six months or so.

Profiles

The profile decides how much data the XML carries. It is declared in the XML's guideline identifier and repeated in the PDF metadata.

ProfileWhat it carriesE-invoice in Germany?
MINIMUMHeader totals and parties, no invoice lines. Guideline ID urn:factur-x.eu:1p0:minimum.No
BASIC WLDocument-level data, no invoice lines ("without lines"). urn:factur-x.eu:1p0:basicwl.No
BASICInvoice lines, a subset of EN 16931. urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic.Yes
EN 16931The full EN 16931 core invoice (formerly called COMFORT). urn:cen.eu:en16931:2017.Yes
EXTENDEDEN 16931 plus extra fields, such as sub-lines for kits and bundles. urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended.Yes
XRECHNUNGA ZUGFeRD PDF whose XML follows the XRechnung rules.Yes

The "No" entries come straight from the BMF: XRechnung and ZUGFeRD from 2.0.1 meet the requirements, "with the exception of the profiles MINIMUM and BASIC-WL" (BMF FAQ, question 7). A validator will still say a MINIMUM file is valid, because it is valid for its profile; it just isn't an e-invoice in the legal sense.

Which profile to use: EN 16931. It carries everything the European standard defines, every receiving system understands it, and it is accepted in Germany and France. Use EXTENDED only when you need a field EN 16931 does not have, and XRECHNUNG when a German public-sector customer asks for it.

ZUGFeRD and the German mandate

Since 1 January 2025 every German business must be able to receive e-invoices; issuing them becomes mandatory in 2027 and 2028, depending on turnover. ZUGFeRD and XRechnung are both accepted for invoices between businesses. Dates, exceptions and sources are on the German e-invoicing mandate page, and the format choice is on ZUGFeRD vs XRechnung vs Factur-X vs Peppol BIS.

Checking a ZUGFeRD file

A complete check has four layers, and an error in any of them makes the file invalid:

  1. PDF/A-3: the PDF itself conforms (fonts embedded, colour profile present, no forbidden features). Checked with veraPDF.
  2. Metadata: the XMP block declares the attachment and the profile, and they match the XML.
  3. Schema: the XML matches the XSD of its profile.
  4. Business rules: the Schematron rules of the profile and of EN 16931, such as BR-CO-15 (total with VAT = total without VAT + VAT).

The typical failures and their fixes are on Validate a ZUGFeRD or Factur-X file. To see the XML inside a PDF, use the embedded XML viewer.

ZUGFeRD API

Invoir's validation API is live: POST the PDF and get a JSON report with every finding, its rule ID and its location in the XML.

curl https://validate.invoir.dev/api/v1/validate \
  -H "Authorization: Bearer inv_YOUR_KEY" \
  -F [email protected]

POST /api/v1/extract returns the embedded XML. Both are in the API docs with examples in Node, Python, PHP and Go. Generating ZUGFeRD PDFs from JSON, with your logo and template and validated before they are returned, is in development; see pricing for the plans.

If you'd rather build it yourself, the open-source libraries are good: Mustang (Java), horstoeko/zugferd (PHP) and factur-x (Python). Invoir runs Mustang and veraPDF itself. What you take on is keeping the rule sets current and making the PDF/A-3 part pass.

Check a file in your browser, or over the API. The free validator runs the official rules (KoSIT, CEN and Peppol Schematron, Mustang, veraPDF) and lists every error with its rule ID. Nothing is stored. The same check is one HTTP call with a free API key: 25 documents a month, no credit card.

Sources

More guides