Factur-X and ZUGFeRD: effectively the same format, with two small differences
A useful starting point that saves a lot of confusion: Factur-X and ZUGFeRD are, for almost all practical purposes, the same specification under two national names. ZUGFeRD is the German designation, maintained by FeRD (Forum elektronische Rechnung Deutschland). Factur-X is the French designation, maintained by FNFE-MPE (Forum National de la Facture Électronique). The two bodies coordinate, the data model is identical, the profiles are the same, and the versions align: ZUGFeRD 2.4 corresponds to Factur-X 1.08, for example.
They are not quite byte-identical, though, and the differences are worth knowing because they trip people up. There are two of them. First, the embedded XML file has a different name: Factur-X expects the attachment to be named factur-x.xml, while ZUGFeRD expects zugferd-invoice.xml (earlier ZUGFeRD versions used ZUGFeRD-invoice.xml). Second, the XMP metadata block that declares the format identifies it differently, using the respective namespace and document-type identifier for Factur-X or ZUGFeRD. The actual invoice payload, the CII XML inside, is the same in both cases.
So the practical position is this: everything technical in this article applies equally to both, and the same generation pipeline produces both. You are simply setting the correct attachment filename and the correct XMP identifier depending on which label the recipient expects. Get those two details right and a ZUGFeRD pipeline produces Factur-X and vice versa.
The hybrid concept: a PDF that is also data
Factur-X is a hybrid invoice. To a human, it is an ordinary PDF that opens and prints like any invoice. To a machine, it carries a structured XML representation of every invoice field, embedded inside the PDF itself. One file serves both the human reader and the automated system. That dual nature is the source of most of the technical complexity, because the container is not a normal PDF.
What a PDF/A-3b container actually is
The carrier for Factur-X is not a regular PDF but a PDF/A-3b file. It is worth unpacking what that means, because each part imposes requirements.
PDF/A is an ISO-standardised subset of PDF (ISO 19005) designed for long-term archival. The whole point is that the file must render identically decades from now, so it forbids anything that depends on external resources or future-uncertain behaviour. The "3" refers to the third part of the standard, which is the version that permits embedding arbitrary files (earlier PDF/A versions did not allow this). The "b" is the conformance level, "basic," meaning the file must reliably preserve visual appearance.
In practice, producing a valid PDF/A-3b container means satisfying a list of constraints that a normally-generated PDF will usually violate:
- All fonts must be fully embedded, no relying on the reader's system fonts.
- Colour must be unambiguous, which means an ICC colour profile has to be embedded to define the colour space.
- The document must carry XMP metadata (an XML metadata block) declaring its PDF/A conformance.
- Factur-X requires an additional XMP extension schema that declares the Factur-X version and the profile in use, so that a receiving system knows how to interpret the embedded data.
The embedded XML itself must be attached as an associated file with the correct relationship marker (AFRelationship set to Alternative), signalling that the XML is an alternative representation of the same invoice the PDF displays. Accounting systems that ingest these files check for exactly this relationship, and a file that embeds the XML without it, or with the wrong marker, may be visually perfect and still rejected on import.
The takeaway is that a file can look completely correct in any PDF viewer and still fail conformance, because the failures live in metadata, colour profiles, font embedding, and attachment relationships that are invisible on screen.
The embedded XML and the EN 16931 semantic model
The data side is governed by EN 16931, the European standard that defines the semantic model for an electronic invoice: what fields exist, what they mean, and how they relate. Factur-X uses the CII (Cross Industry Invoice) syntax to express this model in XML.
EN 16931 is not just a schema. Beyond structural validity, it defines a large set of business rules, over 200 of them, that encode the logic an invoice must satisfy. These cover things like the relationship between line totals, document totals, and VAT breakdowns, the conditional presence of fields depending on VAT category, and the correct use of code lists for currencies, units, tax categories, and payment means. An invoice can be structurally valid XML, pass schema validation cleanly, and still violate a dozen business rules.
Validation: where most rejections actually happen
Those business rules are published as Schematron, a rule-based validation language. Running them is a non-trivial technical requirement because the official Schematron artefacts are implemented in XSLT 2.0. Many common programming environments only support XSLT 1.0 out of the box, which means teams either need a specialised processor (Saxon is the usual choice) or have to find another way to execute the rules. Skipping Schematron and relying on schema-only validation is a frequent shortcut, and it is also the most common reason invoices pass internal checks and then get rejected downstream, because schema validation cannot catch business-rule violations.
There are also national variations layered on top. XRechnung, the German public-sector profile, adds its own rules. Other countries and Peppol add theirs. The same base standard, EN 16931, branches into multiple compliance overlays depending on where the invoice is going.
The part that is easy to underestimate: it is a moving target
Producing one compliant file is a solvable engineering problem. The harder, ongoing problem is that the specifications change, and you have to keep up.
ZUGFeRD and Factur-X release new versions periodically, and each can introduce new mandatory fields, new or revised profiles (MINIMUM, BASIC WL, BASIC, EN 16931, EXTENDED), deprecated elements, and adjusted validation rules. Each profile is declared inside the embedded XML through the guideline identifier (ram:GuidelineSpecifiedDocumentContextParameter), and the five profile URNs are:
MINIMUM urn:factur-x.eu:1p0:minimum
BASIC WL urn:factur-x.eu:1p0:basicwl
BASIC urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic
EN 16931 urn:cen.eu:en16931:2017
EXTENDED urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended
Only BASIC, EN 16931, and EXTENDED are fully EN 16931 compliant; MINIMUM and BASIC WL carry less than the standard requires. The underlying EN 16931 standard and its code lists are themselves revised. XRechnung publishes a new version on roughly an annual cadence. Peppol, if you touch it, updates its rule sets on a regular release cycle. Each of these changes ships as a set of technical assets, updated schemas, updated Schematron files, updated code lists, that you have to obtain, integrate, and test against your existing output.
Knowing where to get authoritative assets is part of the work. The canonical sources are the standards bodies themselves: FeRD for ZUGFeRD, FNFE-MPE for Factur-X, KoSIT for XRechnung, CEN for EN 16931, and OpenPeppol for Peppol. Tracking their release announcements is an ongoing responsibility, not a one-time setup.
And crucially, these changes have effective dates. A new version is published in advance and becomes applicable on a specific date. You cannot deploy it whenever convenient. You have to have the updated logic tested and live by the date it takes effect, which means monitoring upcoming changes, scheduling the work, and rolling out new versions on the regulator's timeline rather than your own. Our e-invoicing mandate deadlines by country page tracks the dates that matter.
What automating this looks like in practice
Putting it together, automating Factur-X or ZUGFeRD compliance means owning all of the following on a continuing basis: generating conformant PDF/A-3b containers with correct font embedding, colour profiles, and XMP metadata; producing valid EN 16931 CII XML; embedding it with the correct associated-file relationship; running full Schematron validation including any national overlays; and maintaining all of the above as the standards evolve, deploying updates by their effective dates.
Teams generally choose one of three integration approaches:
- A direct REST API call from their existing system, which suits custom-built billing and ERP software.
- A language SDK or library embedded into their codebase, which keeps processing in-house but means they also own the maintenance of that library against spec changes.
- A no-code automation route through platforms like Zapier or Make, which suits organisations that want to wire up invoicing without writing code.
The right choice depends on where invoice data originates and how much engineering capacity the organisation wants to dedicate to a compliance function that is not its core business.
If you would rather not own the technical headache
The build-it-yourself path is entirely viable, and for organisations with the engineering capacity and a desire for full control, it can be the right call. But it is worth being clear-eyed that the cost is not just the initial build, it is the indefinite maintenance: the monitoring, the asset updates, the regression testing, and the deadline-driven rollouts, format after format, year after year.
The alternative is to delegate the compliance layer to a service that handles it as a managed function. InvoiceXML produces compliant Factur-X and ZUGFeRD (and XRechnung, Peppol UBL, and CII) out of the box, so the PDF/A-3b conformance, the EN 16931 XML, and the Schematron validation are taken care of without you maintaining any of it. It can be reached however suits the workflow: a REST API for direct system integration, no-code automation through Zapier or Make, or, for teams building AI-driven and agentic workflows, an MCP interface so an AI agent can generate and validate invoices as a tool. The practical advantage of this model is that when the standards change, the updates are deployed on their effective dates automatically. There is no version to track, no Schematron package to integrate, and no maintenance window to schedule on your side. Compliance stays current without anyone watching the standards bodies.
Neither path is universally correct. The point of this overview is simply to make the technical reality legible, so that the choice between building and delegating is an informed one rather than a surprise discovered halfway through implementation.