Factur-X: The Technical Reference (XML, Profiles, EN 16931 Mapping)
A complete developer reference for Factur-X — the hybrid PDF/A-3 + CII XML format used across France, Germany, and Luxembourg. XML anatomy, profile hierarchy, EN 16931 rule mapping, validation errors, and code samples.
Factur-X is a hybrid invoice format: a PDF/A-3 document with a structured CII XML file embedded as an attachment. One artifact, two representations — a human-readable PDF and a machine-readable XML — bound by the same source of truth.
If you build ERP integrations, you already know the visible surface. This reference is the layer underneath: how the XML sits inside the PDF, which profile does what, how the EN 16931 semantic model maps to Factur-X elements, and where the validators trip.
This is a companion to our Factur-X vs ZUGFeRD comparison, EN 16931 rules guide, and France ERP integration guide. Where those tackle strategy, this tackles bytes.
What Factur-X Actually Is
Factur-X is the French half of a single Franco-German specification. The German half is called ZUGFeRD. Since ZUGFeRD 2.1 (2020), the two are technically identical — same XML schema, same PDF/A-3 container, same profile hierarchy. Factur-X 1.08 and ZUGFeRD 2.4 (both applicable January 15, 2026) are the same document with two covers.
The specification is jointly maintained by:
- FNFE-MPE — Forum National de la Facture Électronique et des Marchés Publics Électroniques (France)
- FeRD — Forum elektronische Rechnung Deutschland (Germany)
Both organizations publish the same technical artifact. When a French vendor sends "a Factur-X" and a German receiver expects "a ZUGFeRD" — they are exchanging the exact same file.
The container is PDF/A-3, an ISO-standardized archival PDF variant that allows embedded file attachments (unlike PDF/A-1 and PDF/A-2, which forbid them). The attachment is a single XML file — always named factur-x.xml for the French flavor, zugferd-invoice.xml for the German flavor. Otherwise identical.
The XML syntax is UN/CEFACT Cross Industry Invoice (CII), one of the two syntaxes EN 16931 permits — the other being UBL 2.1. Factur-X is CII-only. If you need UBL, you're not building Factur-X.
The Profile Hierarchy
Factur-X defines five cumulative profiles. Each profile is a superset of the previous one, containing more mandatory fields:
| Profile | Data richness | EN 16931 compliant? | Legal for FR B2B mandate? |
|---|---|---|---|
| MINIMUM | 20 fields — buyer, seller, totals, VAT | No | No |
| BASIC WL (Without Lines) | + payment terms, references | No | No |
| BASIC | + one aggregated line item | No | No |
| EN 16931 | + full line items, discounts, allowances | Yes | Yes (minimum) |
| EXTENDED | + logistics, project references, contract data | Yes | Yes |
For France's September 2026 B2B mandate, only EN 16931 and EXTENDED are legal. Everything below fails the CIUS-FR overlay. Many PDF libraries default to MINIMUM or BASIC because those require the least data — this is one of the top three integration failures we see on the Invoice Navigator validator.
France additionally publishes EXTENDED-CTC-FR, an EXTENDED variant carrying the extra fields the Plateforme Agréée (formerly PDP) needs for lifecycle reporting to the DGFiP. If you're serving French customers, EXTENDED-CTC-FR is the safer emit target — see the France ERP integration guide for the specifics.
Anatomy of a Factur-X File
The outer container is a PDF/A-3 document. Inside the PDF's /Names/EmbeddedFiles name tree, a single /EmbeddedFile stream holds the XML. The PDF's XMP metadata block advertises the file to processors that never crack the PDF open.
XMP metadata block
The XMP block sits inside the PDF's document catalog and declares Factur-X presence:
<rdf:Description rdf:about=""
xmlns:fx="urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#">
<fx:DocumentType>INVOICE</fx:DocumentType>
<fx:DocumentFileName>factur-x.xml</fx:DocumentFileName>
<fx:Version>1.0</fx:Version>
<fx:ConformanceLevel>EN 16931</fx:ConformanceLevel>
</rdf:Description>
ConformanceLevel is the profile name in CamelCase — MINIMUM, BASIC_WL, BASIC, EN 16931, or EXTENDED. A validator reads this before parsing the XML and rejects mismatches between the declared profile and the actual XML content.
The embedded XML
The XML root is <rsm:CrossIndustryInvoice>, with three prefix namespaces:
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<rsm:ExchangedDocumentContext>...</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>...</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>...</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
Three top-level sections:
ExchangedDocumentContext— declares the profile via a URN. This is the single most common source of validation failure: the URN and the XMPConformanceLevelmust agree.ExchangedDocument— invoice header (ID, type code 380 for invoice, issue date, notes).SupplyChainTradeTransaction— the invoice body: line items, agreement (seller/buyer parties), delivery, and settlement (totals, VAT breakdown, payment terms).
Minimum viable EN 16931 body
The following is the smallest legal EN 16931 Factur-X body — a single line item, one VAT category, one payment term:
<rsm:CrossIndustryInvoice xmlns:rsm="..." xmlns:ram="..." xmlns:udt="...">
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>2026-INV-000123</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20260707</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:Name>Consulting services — June 2026</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>100.00</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="HUR">10</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>20.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:Name>ACME SAS</ram:Name>
<ram:SpecifiedLegalOrganization>
<ram:ID schemeID="0009">78467169500035</ram:ID>
</ram:SpecifiedLegalOrganization>
<ram:PostalTradeAddress>
<ram:PostcodeCode>75002</ram:PostcodeCode>
<ram:CityName>Paris</ram:CityName>
<ram:CountryID>FR</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">FR12345678901</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:Name>Client SARL</ram:Name>
<ram:PostalTradeAddress>
<ram:CountryID>FR</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery/>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>200.00</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>1000.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>20.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
<ram:TaxBasisTotalAmount>1000.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">200.00</ram:TaxTotalAmount>
<ram:GrandTotalAmount>1200.00</ram:GrandTotalAmount>
<ram:DuePayableAmount>1200.00</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
That is a valid EN 16931 profile Factur-X body. Add <ram:SpecifiedTaxRegistration> for the buyer if the buyer is VAT-registered. Add a bank account for cross-border SEPA. Everything else in EN 16931 is optional.
EN 16931 Business Terms → Factur-X XPath
The EN 16931 semantic model uses BT-* (Business Term) and BG-* (Business Group) identifiers. Every Factur-X element maps to one BT or BG. The most common ones:
| EN 16931 BT | Meaning | Factur-X XPath (relative to root) |
|---|---|---|
| BT-1 | Invoice number | ExchangedDocument/ID |
| BT-2 | Issue date | ExchangedDocument/IssueDateTime/DateTimeString |
| BT-3 | Invoice type code | ExchangedDocument/TypeCode |
| BT-5 | Currency code | SupplyChainTradeTransaction/ApplicableHeaderTradeSettlement/InvoiceCurrencyCode |
| BT-27 | Seller name | .../ApplicableHeaderTradeAgreement/SellerTradeParty/Name |
| BT-31 | Seller VAT | .../SellerTradeParty/SpecifiedTaxRegistration/ID[@schemeID='VA'] |
| BT-44 | Buyer name | .../BuyerTradeParty/Name |
| BT-48 | Buyer VAT | .../BuyerTradeParty/SpecifiedTaxRegistration/ID[@schemeID='VA'] |
| BT-106 | Sum of line net amounts | .../SpecifiedTradeSettlementHeaderMonetarySummation/LineTotalAmount |
| BT-109 | Invoice total without VAT | .../TaxBasisTotalAmount |
| BT-110 | Total VAT amount | .../TaxTotalAmount |
| BT-112 | Invoice total with VAT | .../GrandTotalAmount |
| BT-115 | Amount due for payment | .../DuePayableAmount |
For the full 164-BT map, see the EN 16931 rules guide — this is a working developer subset.
Validation Layers and Common Failures
A Factur-X invoice gets validated at four progressively stricter layers. Each layer rejects for different reasons.
1. PDF/A-3 conformance. Fails when the outer PDF is PDF/A-1, PDF/A-2, or a plain PDF. Symptom: veraPDF or similar rejects with pdfa1a violations. Fix at the PDF generation library level.
2. XML Schema (XSD). The CII schemas from UN/CEFACT enforce structure and datatypes. Fails when required elements are missing, cardinality is wrong (too many <ApplicableTradeTax> for the profile), or datatypes are wrong (a string in a decimal field). Symptom: cvc-complex-type, cvc-datatype-valid.
3. EN 16931 Schematron. 155 rules covering semantic correctness — totals must reconcile, VAT categories must be consistent, dates must be plausible. The common failures:
| Rule | Meaning | Typical cause |
|---|---|---|
| BR-CO-10 | Sum of line amounts must equal BT-106 | Rounding drift, wrong line count |
| BR-CO-13 | BT-109 = BT-106 − allowances + charges | Missing header-level allowances |
| BR-CO-15 | BT-112 = BT-109 + BT-110 | Off-by-one on rounding half-up vs half-even |
| BR-S-08 | Standard VAT category needs rate > 0 | Emitting CategoryCode = S with 0% |
| BR-CL-04 | Currency code must be ISO 4217 | Lowercase "eur" or "€" symbol |
BR-CO-* rules are consistency rules. If your total won't reconcile, it's almost always rounding — see the most common e-invoice errors guide for the half-up vs banker's rounding trap.
4. Country CIUS Schematron. France layers CIUS-FR on top of EN 16931 for its mandate — extra mandatory fields (SIRET, French tax codes), stricter cardinalities. Germany's public sector uses XRechnung's CIUS with its own rule set (BR-DE-*). A Factur-X invoice can pass the EN 16931 layer and still fail CIUS. This is where most cross-border ERP integrations break.
Country Support Matrix
| Country | Accepts Factur-X? | CIUS layer | Notes |
|---|---|---|---|
| France | Yes | CIUS-FR | Mandatory for B2B from Sept 1, 2026. See France guide |
| Germany | Yes | XRechnung (public sector); none (B2B) | Factur-X and XRechnung are both EN 16931 formats; both accepted |
| Luxembourg | Yes | None | Factur-X and XRechnung accepted equally via Peppol |
| Netherlands | Via Peppol only | None | UBL preferred; Factur-X converted server-side |
| Belgium | Via Peppol only | None | Peppol BIS 3.0 (UBL) is the native format |
| Italy | No | FatturaPA | SDI accepts only FatturaPA XML; Factur-X must be converted |
| Poland | No | KSeF FA(3) | KSeF has its own XML; Factur-X not accepted |
For a country-by-country map of formats and mandates, see the country pages.
Generating Factur-X — What Your Pipeline Needs
An emission pipeline has three stages:
1. Build the CII XML. From your invoice domain model, populate the CII structure. Any XML serializer works; there are also higher-level libraries (factur-x on PyPI, mustangproject for Java/Maven, Sylius/FacturX for PHP) that generate the XML from a typed domain object.
2. Build the PDF/A-3. Generate the visual invoice as a PDF/A-3-conformant document. The most common cause of PDF/A-3 failure is a color profile mismatch — embed sRGB IEC61966-2.1 or an equivalent OutputIntent. Do not embed non-embedded fonts.
3. Attach and stamp. Add the CII XML as a /EmbeddedFile stream. Set the /AFRelationship key to /Alternative for Factur-X 1.0.06+. Write the XMP metadata block. Re-serialize the PDF (many libraries need a save-optimize pass to fix the file offset table).
Before you ship, validate on all four layers. The public FNFE-MPE validator and the KoSIT XRechnung validator are the reference implementations. Both are useful for spot checks; neither is engineered for pipeline throughput. If you need per-invoice validation in a build pipeline or CI, Invoice Navigator's fixer API is designed for that path.
FAQ
What is the difference between Factur-X and ZUGFeRD?
Since ZUGFeRD 2.1 they are technically identical — same specification, same profiles, same XML schema. The only differences are the naming (Factur-X for France, ZUGFeRD for Germany), the internal XML filename (factur-x.xml vs zugferd-invoice.xml), and the maintaining organization. See the full breakdown in Factur-X vs ZUGFeRD.
Is Factur-X mandatory in France in 2026?
Factur-X itself is not mandatory — France's B2B mandate accepts three formats: Factur-X, UBL 2.1, and pure CII. Factur-X is the format the French market expects and where PA pilot traffic concentrates. The mandate starts September 1, 2026 for receiving; issuing follows a phased large-then-mid-then-small enterprise ramp.
Which Factur-X profile should I emit?
For the French B2B mandate, minimum is EN 16931. Recommended is EXTENDED-CTC-FR (or EXTENDED if you're not going through a French PA). Never emit MINIMUM, BASIC WL, or BASIC — they're not EN 16931 compliant and the PA will reject them.
Can I use Factur-X for Peppol?
Not directly. Peppol BIS Billing 3.0 uses UBL 2.1, not CII. Some Peppol Access Points transparently convert CII ↔ UBL at the network edge, but the on-wire format inside Peppol is UBL. If you're sending via Peppol, generate UBL; if you're going through a French PA outside Peppol, generate Factur-X.
What's the difference between Factur-X and e-Invoicing?
E-invoicing is the umbrella term — any structured, machine-readable invoice format. Factur-X is one specific format within e-invoicing. Others include XRechnung (Germany), UBL (Peppol, Netherlands), FatturaPA (Italy), and KSeF FA(3) (Poland). All of them can be "e-invoices"; only Factur-X uses the hybrid PDF/A-3 + CII XML approach.
How do I validate a Factur-X file?
Four layers: PDF/A-3 (veraPDF), XML Schema (any XSD validator), EN 16931 Schematron (KoSIT or FNFE-MPE reference implementation), and country CIUS Schematron (CIUS-FR for France, XRechnung for German public sector). Public web validators cover all four but with a rate-limited, interactive interface. See how to validate e-invoices via API for pipeline-grade options.
What is a Factur-X XML example?
The minimum viable EN 16931 body is above. For a full working file with attached PDF, the FNFE-MPE reference implementation on GitHub carries current example files for every profile. Do not reuse example files from before January 2026 — Factur-X 1.08 introduced small breaking changes in the XMP block.
Does Factur-X work with SAP?
Yes. SAP S/4HANA supports Factur-X natively via the Document and Reporting Compliance (DRC) framework from release 2023 onwards. For older SAP releases, third-party add-ons (SEEBURGER, Basware, Comarch) provide Factur-X emission on top of standard SAP output management. The XML mapping is the same either way — SAP just needs the right output type configured.
Is Factur-X free to use?
Yes. Both the Factur-X specification and the underlying UN/CEFACT CII schema are freely available. The FNFE-MPE and FeRD publish the full technical documentation without licensing fees. Commercial libraries and validators exist, but the format itself is open.
Further Reading
Internal references:
- Factur-X vs ZUGFeRD — the differences
- France Factur-X ERP Integration Guide
- EN 16931 Validation Rules — Complete Guide
- The Most Common E-Invoice Errors in 2026
- UBL vs CII — Which XML Syntax?
- Invoice Navigator validator
- Country pages
External references:
- FNFE-MPE Factur-X specification (fnfe-mpe.org)
- FeRD ZUGFeRD documentation (ferd-net.de)
- UN/CEFACT Cross Industry Invoice schema
- KoSIT XRechnung validator (xeinkauf.de)
Invoice Navigator is a compliance safety layer for EU e-invoicing pipelines. If you build Factur-X in an ERP context and want per-invoice validation with automatic fixes for the top rounding, VAT-category, and CIUS-FR failures, see how the fixer works.
Check Your Compliance Status
Find out exactly what your business needs to do for e-invoicing compliance.
Use Obligation Finder