XRechnung for developers: the UBL format in detail
XRechnung is the German standard for electronic invoices to the public sector – and, since the German B2B e-invoicing mandate, relevant well beyond it. This article explains the format from a developer's perspective: we dissect a complete example invoice in the UBL syntax and explain the most important fields.
What is an XRechnung?
An XRechnung is not a PDF file but a structured, machine-readable XML file. The standard is operated by the Koordinierungsstelle für IT-Standards (KoSIT) on behalf of the German IT Planning Council. The currently valid version is 3.0.2 (since July 2024, most recently updated with the "Winter 2025/26" bugfix release).
Technically, XRechnung is a CIUS (Core Invoice Usage Specification) of the European standard EN 16931: a national specialization that supplements the European requirements with German business rules. Like EN 16931, XRechnung permits two XML syntaxes:
- UBL 2.1 (Universal Business Language, an OASIS standard, ISO/IEC 19845)
- UN/CEFACT Cross Industry Invoice (CII)
This article uses UBL. The CII syntax is primarily used by ZUGFeRD.
Legal framework
- B2G: EU Directive 2014/55/EU obliges public-sector bodies to receive and process EN 16931 compliant e-invoices. Suppliers to the German federal government have had to submit their invoices electronically since 2020-11-27 (§ 3 E-Rechnungsverordnung); the Leitweg-ID is a mandatory field (§ 5 ERechV).
- B2B: Since 2025-01-01, e-invoicing under § 14 UStG has been the standard for transactions between domestic German businesses. Every business must be able to receive e-invoices; transition periods under § 27(38) UStG apply to issuing them (with the recipient's consent: other invoice formats until the end of 2026, or until the end of 2027 for businesses with a previous-year turnover of up to €800,000).
- The Federal Ministry of Finance guidance of 2024-10-15 (amended by the guidance of 2025-10-15) explicitly confirms XRechnung as a permissible format.
Anatomy of an XRechnung
1. Header and metadata
<?xml version="1.0" encoding="utf-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>RE-2026-001</cbc:ID>
<cbc:IssueDate>2026-06-15</cbc:IssueDate>
<cbc:DueDate>2026-07-15</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>Notiz für die XRechnung</cbc:Note>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>PROJEKT-2026-XR</cbc:BuyerReference>
</Invoice>
CustomizationID: The specification identifier. It declares the invoice as compliant with EN 16931 and the XRechnung 3.0 standard.ProfileID: The business process identifier; the default value is the Peppol billing processurn:fdc:peppol.eu:2017:poacc:billing:01:1.0.ID(BT-1): The unique invoice number.IssueDate(BT-2) /DueDate(BT-9): Issue and due dates in the formatYYYY-MM-DD.InvoiceTypeCode(BT-3): The invoice type according to UNTDID 1001; "380" is the commercial invoice.DocumentCurrencyCode(BT-5): The currency according to ISO 4217.BuyerReference(BT-10): The buyer reference. In invoices to German authorities this carries the Leitweg-ID, which addresses the recipient within the administration.
2. The supplier
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="EM">info@example.com</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Muster GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Musterstraße 55a</cbc:StreetName>
<cbc:CityName>Hamburg</cbc:CityName>
<cbc:PostalZone>12345</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE123456789</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Muster GmbH</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Max Mustermann</cbc:Name>
<cbc:Telephone>+49123456789</cbc:Telephone>
<cbc:ElectronicMail>max.mustermann@example.com</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
EndpointID(BT-34): The electronic address. TheschemeIDattribute qualifies the address type according to the EAS code list – "EM" stands for an email address.PartyTaxScheme/CompanyID(BT-31): The VAT identification number.PartyLegalEntity/RegistrationName(BT-27): The official company name.Contact: A contact person with phone and email.
3. The customer
The cac:AccountingCustomerParty block is structured analogously and contains the buyer's data – electronic address (BT-49), postal address and VAT ID.
4. Payment details
<cac:PaymentMeans>
<cbc:PaymentMeansCode>58</cbc:PaymentMeansCode>
<cac:PayeeFinancialAccount>
<cbc:ID>DE12345678901234567890</cbc:ID>
<cbc:Name>Muster GmbH</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>MUSTDE12XXX</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>Zahlbar innerhalb von 30 Tagen netto</cbc:Note>
</cac:PaymentTerms>
PaymentMeansCode(BT-81): The payment means according to UNTDID 4461. Code "58" is the SEPA credit transfer, "30" the generic credit transfer.PayeeFinancialAccount: IBAN (BT-84), account holder (BT-85) and BIC (BT-86).PaymentTerms/Note(BT-20): Free text for payment terms such as the payment deadline or an early payment discount.
5. Tax and document totals
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">149.15</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">785.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">149.15</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">785.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">785.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">934.15</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">934.15</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
TaxSubtotal: A breakdown per tax rate with the taxable amount (BT-116) and the tax amount (BT-117).TaxCategory/ID(BT-118): The tax category according to UNTDID 5305. "S" stands for transactions taxed at the standard rate – the reduced German rate of 7 % is also encoded as "S" with the corresponding percentage.LegalMonetaryTotal: Sum of the line net amounts (BT-106), net total (BT-109), gross total (BT-112) and amount due (BT-115). These totals must add up exactly – validators check this strictly.
6. The invoice lines
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">3</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">285.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description>Analyse und Erarbeitung eines Konzepts für die Digitalisierung</cbc:Description>
<cbc:Name>Beratung und Konzeption</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">95.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
InvoicedQuantity(BT-129): The quantity. TheunitCodeattribute (BT-130) carries the unit of measure according to UN/ECE Recommendation N°20 or N°21 – "HUR" is the hour, "H87" the piece.LineExtensionAmount(BT-131): The net amount of the line (quantity × unit price).ClassifiedTaxCategory(BT-151/BT-152): The tax category and rate of the line.Price/PriceAmount(BT-146): The net unit price.
The complete example
<?xml version="1.0" encoding="utf-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>RE-2026-001</cbc:ID>
<cbc:IssueDate>2026-06-15</cbc:IssueDate>
<cbc:DueDate>2026-07-15</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>Notiz für die XRechnung</cbc:Note>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>PROJEKT-2026-XR</cbc:BuyerReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="EM">info@example.com</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Muster GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Musterstraße 55a</cbc:StreetName>
<cbc:CityName>Hamburg</cbc:CityName>
<cbc:PostalZone>12345</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE123456789</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Muster GmbH</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Max Mustermann</cbc:Name>
<cbc:Telephone>+49123456789</cbc:Telephone>
<cbc:ElectronicMail>max.mustermann@example.com</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="EM">buchhaltung@beispiel-ug.de</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Beispiel UG (haftungsbeschränkt)</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Musterweg 3c</cbc:StreetName>
<cbc:CityName>Berlin</cbc:CityName>
<cbc:PostalZone>54321</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE987654321</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Beispiel UG (haftungsbeschränkt)</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Erika Musterfrau</cbc:Name>
<cbc:Telephone>+49987654321</cbc:Telephone>
<cbc:ElectronicMail>erika.musterfrau@beispiel-ug.de</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:PaymentMeans>
<cbc:PaymentMeansCode>58</cbc:PaymentMeansCode>
<cac:PayeeFinancialAccount>
<cbc:ID>DE12345678901234567890</cbc:ID>
<cbc:Name>Muster GmbH</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>MUSTDE12XXX</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>Zahlbar innerhalb von 30 Tagen netto</cbc:Note>
</cac:PaymentTerms>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">149.15</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">785.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">149.15</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">785.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">785.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">934.15</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">934.15</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">3</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">285.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description>Analyse und Erarbeitung eines Konzepts für die Digitalisierung</cbc:Description>
<cbc:Name>Beratung und Konzeption</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">95.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>2</cbc:ID>
<cbc:InvoicedQuantity unitCode="H87">1</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">500.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description>Entwicklung eines Corporate Designs inkl. Logo</cbc:Description>
<cbc:Name>Logo-Design</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">500.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</Invoice>
Validation
Every generated XRechnung should be validated before productive use. KoSIT provides open-source tools for this: the generic validator and the official validation configuration for XRechnung, which contains the XML schema and the Schematron business rules for both syntaxes.
The easier way: creating XRechnung invoices via API
Building the XML by hand is laborious and error-prone – every field has defined semantics, and the EN 16931 business rules (for example on totals) are checked strictly. RechnungsAPI abstracts the entire process behind a JSON REST API and produces validated XRechnung invoices from it, including an optional PDF rendering. Our tutorial on creating XRechnung invoices via API shows how.