XRechnung XML Structure: UBL, CII, Namespaces and XSD
XRechnung XSD and XML structure explained for developers: UBL and CII root elements, namespaces, schema and Schematron validation, plus a BT-to-XPath table.
Key takeaways
- XRechnung 3.0.2 comes in two equivalent syntaxes: UBL 2.1 with the root element Invoice or CreditNote, and UN/CEFACT CII D16B with rsm:CrossIndustryInvoice.
- There is no separate XRechnung XSD; files are checked against UBL-Invoice-2.1.xsd, UBL-CreditNote-2.1.xsd or CrossIndustryInvoice_100pD16B.xsd, then against the EN 16931 and KoSIT Schematron rules.
- For every 3.0.x release, BT-24 is urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0, and BT-23 (business process) is mandatory under rule PEPPOL-EN16931-R001.
- UBL writes dates as 2026-09-28, CII as 20260928 with format code 102; invoice amounts use a dot as decimal separator and at most two decimal places.
- The buyer reference BT-10 sits in cbc:BuyerReference in UBL and in ram:ApplicableHeaderTradeAgreement/ram:BuyerReference in CII; if it is missing, the validator reports BR-DE-15.
On this page
There is no separate XRechnung XSD. An XRechnung is an XML file in UBL 2.1 (root element Invoice or CreditNote) or UN/CEFACT CII D16B (root rsm:CrossIndustryInvoice), and it is validated against the XSD of that syntax. After the schema check come the EN 16931 Schematron rules and KoSIT's XRechnung rules; only a file that passes all three is valid.
Last reviewed: September 2026 · Based on XRechnung 3.0.2
This guide is for developers who generate, parse or validate XRechnung files. It covers both document skeletons, the namespaces, a mapping of the key business terms to XPath, and the mistakes that most often get a file rejected. If you first need the business context (what XRechnung is and who has to use it), start with What is XRechnung?. More developer articles are collected under developer tools.
Which syntaxes does XRechnung allow?
XRechnung is Germany's Core Invoice Usage Specification (CIUS) of the European standard EN 16931. It is published by KoSIT, the German Coordination Office for IT Standards. The standard defines a semantic invoice model made of business terms such as BT-1 (invoice number) and business groups such as BG-25 (invoice line). A syntax binding defines which XML element carries which business term. There are two bindings: UBL 2.1 and CII version D16B. Both are equally valid forms of XRechnung.
| Property | UBL 2.1 | UN/CEFACT CII D16B |
|---|---|---|
| Root element | Invoice, or CreditNote for credit notes | rsm:CrossIndustryInvoice |
| Root namespace | urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 or …:CreditNote-2 | urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 |
| XSD file | UBL-Invoice-2.1.xsd, UBL-CreditNote-2.1.xsd | CrossIndustryInvoice_100pD16B.xsd |
| Credit note (code 381) | separate document type with cbc:CreditNoteTypeCode | same root, code in ram:TypeCode |
| Date format | 2026-09-28 | 20260928 with format="102" |
| Invoice lines | at the end of the document | at the start of rsm:SupplyChainTradeTransaction |
| Where you meet it | Peppol BIS Billing 3.0 is built on UBL | XML part of ZUGFeRD and Factur-X |
No law prescribes one or the other. If you send via Peppol, UBL is the usual choice. If you already produce ZUGFeRD, CII lets you reuse that structure. The comparison UBL vs. CII goes into the differences, and XRechnung vs. ZUGFeRD explains how the two formats relate.
The current version is XRechnung 3.0.2; the latest bundle, "3.0.2 Summer 2026 Bugfix", is dated 31 August 2026. Version 3.0 has applied since 1 February 2024 and remains in force until at least 31 July 2027. KoSIT published a pre-release of XRechnung 4.0 in September 2026, and the final version is expected in spring 2027. KoSIT keeps these dates on its versions and bundles page (opens in a new tab) (in German).
Which namespaces does an XRechnung need?
A namespace is a URI that names an XML vocabulary. The prefix in front of an element is only a local alias. A namespace-aware parser always compares the pair of URI and local name, so <Invoice xmlns="…Invoice-2"> and <ubl:Invoice xmlns:ubl="…Invoice-2"> are the same element to any validator. The reverse also holds: the right prefix does not help if the URI is off by a single character.
| Prefix | Namespace URI | Contains |
|---|---|---|
none or ubl | urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 | the UBL invoice root |
cac | urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2 | composite elements such as cac:AccountingSupplierParty, cac:InvoiceLine |
cbc | urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2 | simple values such as cbc:ID, cbc:IssueDate |
rsm | urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 | the CII root and its three main blocks |
ram | urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100 | almost all business elements in CII |
udt | urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100 | data types such as udt:DateTimeString, udt:Indicator |
qdt | urn:un:unece:uncefact:data:standard:QualifiedDataType:100 | qualified data types, e.g. formatted dates |
A typo in one of these URIs is easy to miss. The file stays well-formed, but no schema matches it any more. The KoSIT validator then finds no validation scenario and rejects the file. The error page SCHEMA-002 explains this case.
What does a UBL XRechnung look like?
UBL is flat. Header data comes first, followed by references, the parties, delivery and payment details, the VAT breakdown, the totals and finally the invoice lines. The XSD defines this order as a sequence. A correctly named element in the wrong position is a schema error: put cbc:IssueDate after cbc:InvoiceTypeCode and the file already fails the XSD.
<?xml version="1.0" encoding="UTF-8"?>
<ubl:Invoice xmlns:ubl="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> <!-- BT-24 -->
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <!-- BT-23 -->
<cbc:ID>RE-2026-0815</cbc:ID> <!-- BT-1 -->
<cbc:IssueDate>2026-09-28</cbc:IssueDate> <!-- BT-2 -->
<cbc:DueDate>2026-10-12</cbc:DueDate> <!-- BT-9 -->
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> <!-- BT-3 -->
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode> <!-- BT-5 -->
<cbc:BuyerReference>991-12345-73</cbc:BuyerReference> <!-- BT-10 -->
<cac:AccountingSupplierParty>…</cac:AccountingSupplierParty> <!-- BG-4 seller -->
<cac:AccountingCustomerParty>…</cac:AccountingCustomerParty> <!-- BG-7 buyer -->
<cac:PaymentMeans>…</cac:PaymentMeans> <!-- BG-16 -->
<cac:TaxTotal>…</cac:TaxTotal> <!-- BT-110, BG-23 -->
<cac:LegalMonetaryTotal> <!-- BG-22 -->
<cbc:LineExtensionAmount currencyID="EUR">1500.00</cbc:LineExtensionAmount> <!-- BT-106 -->
<cbc:TaxExclusiveAmount currencyID="EUR">1500.00</cbc:TaxExclusiveAmount> <!-- BT-109 -->
<cbc:TaxInclusiveAmount currencyID="EUR">1785.00</cbc:TaxInclusiveAmount> <!-- BT-112 -->
<cbc:PayableAmount currencyID="EUR">1785.00</cbc:PayableAmount> <!-- BT-115 -->
</cac:LegalMonetaryTotal>
<cac:InvoiceLine> <!-- BG-25 -->
<cbc:ID>1</cbc:ID> <!-- BT-126 -->
<cbc:InvoicedQuantity unitCode="HUR">15</cbc:InvoicedQuantity> <!-- BT-129, BT-130 -->
<cbc:LineExtensionAmount currencyID="EUR">1500.00</cbc:LineExtensionAmount> <!-- BT-131 -->
<cac:Item>
<cbc:Name>Consulting services September 2026</cbc:Name> <!-- BT-153 -->
<cac:ClassifiedTaxCategory>…</cac:ClassifiedTaxCategory> <!-- BG-30 -->
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <!-- BT-146 -->
</cac:Price>
</cac:InvoiceLine>
</ubl:Invoice>
Two details stand out. Every amount in UBL carries a currencyID attribute; leave it out and the XSD already complains. And a credit note is its own document type: CreditNote with cbc:CreditNoteTypeCode, cac:CreditNoteLine and cbc:CreditedQuantity. For a complete, valid file with parties and the tax block, see our xrechnung example.
What does a CII XRechnung look like?
CII splits the invoice into three blocks. rsm:ExchangedDocumentContext holds the identifiers BT-23 and BT-24. rsm:ExchangedDocument holds the invoice number, type and date. rsm:SupplyChainTradeTransaction holds everything else: first the invoice lines, then the agreement (parties, buyer reference, referenced documents), the delivery and the settlement. Developers coming from UBL are often surprised that the lines come before the header details, but the schema requires this order.
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
<rsm:ExchangedDocumentContext>
<ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID> <!-- BT-23 -->
</ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID> <!-- BT-24 -->
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>RE-2026-0815</ram:ID> <!-- BT-1 -->
<ram:TypeCode>380</ram:TypeCode> <!-- BT-3 -->
<ram:IssueDateTime>
<udt:DateTimeString format="102">20260928</udt:DateTimeString> <!-- BT-2 -->
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>…</ram:IncludedSupplyChainTradeLineItem> <!-- BG-25 -->
<ram:ApplicableHeaderTradeAgreement>
<ram:BuyerReference>991-12345-73</ram:BuyerReference> <!-- BT-10 -->
<ram:SellerTradeParty>…</ram:SellerTradeParty> <!-- BG-4 -->
<ram:BuyerTradeParty>…</ram:BuyerTradeParty> <!-- BG-7 -->
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery>…</ram:ApplicableHeaderTradeDelivery> <!-- BG-13 -->
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode> <!-- BT-5 -->
<ram:SpecifiedTradeSettlementPaymentMeans>…</ram:SpecifiedTradeSettlementPaymentMeans> <!-- BG-16 -->
<ram:ApplicableTradeTax>…</ram:ApplicableTradeTax> <!-- BG-23 -->
<ram:SpecifiedTradePaymentTerms>…</ram:SpecifiedTradePaymentTerms> <!-- BT-9, BT-20 -->
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>1500.00</ram:LineTotalAmount> <!-- BT-106 -->
<ram:TaxBasisTotalAmount>1500.00</ram:TaxBasisTotalAmount> <!-- BT-109 -->
<ram:TaxTotalAmount currencyID="EUR">285.00</ram:TaxTotalAmount> <!-- BT-110 -->
<ram:GrandTotalAmount>1785.00</ram:GrandTotalAmount> <!-- BT-112 -->
<ram:DuePayableAmount>1785.00</ram:DuePayableAmount> <!-- BT-115 -->
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
Unlike UBL, CII normally puts currencyID only on ram:TaxTotalAmount; all other amounts refer to the invoice currency in BT-5. If you have a ZUGFeRD invoice, you can extract XML from PDF files with our extractor and compare the embedded CII with this skeleton.
Where is each field? Business terms mapped to XPath
The table maps the most important business terms to both syntaxes. The paths are XPath expressions relative to the root element. Three abbreviations keep the CII column readable:
HAmeansrsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreementHSmeansrsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlementMSmeansHS/ram:SpecifiedTradeSettlementHeaderMonetarySummation
| BT | Meaning | UBL | CII |
|---|---|---|---|
| BT-1 | Invoice number | cbc:ID | rsm:ExchangedDocument/ram:ID |
| BT-2 | Issue date | cbc:IssueDate | rsm:ExchangedDocument/ram:IssueDateTime/udt:DateTimeString |
| BT-3 | Invoice type code | cbc:InvoiceTypeCode | rsm:ExchangedDocument/ram:TypeCode |
| BT-5 | Invoice currency | cbc:DocumentCurrencyCode | HS/ram:InvoiceCurrencyCode |
| BT-9 | Due date | cbc:DueDate | HS/ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime/udt:DateTimeString |
| BT-10 | Buyer reference (the Leitweg-ID for public buyers) | cbc:BuyerReference | HA/ram:BuyerReference |
| BT-24 | Specification identifier | cbc:CustomizationID | rsm:ExchangedDocumentContext/ram:GuidelineSpecifiedDocumentContextParameter/ram:ID |
| BT-27 | Seller name | cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cbc:RegistrationName | HA/ram:SellerTradeParty/ram:Name |
| BT-31 | Seller VAT ID | cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[cac:TaxScheme/cbc:ID='VAT']/cbc:CompanyID | HA/ram:SellerTradeParty/ram:SpecifiedTaxRegistration/ram:ID[@schemeID='VA'] |
| BT-44 | Buyer name | cac:AccountingCustomerParty/cac:Party/cac:PartyLegalEntity/cbc:RegistrationName | HA/ram:BuyerTradeParty/ram:Name |
| BT-109 | Total without VAT | cac:LegalMonetaryTotal/cbc:TaxExclusiveAmount | MS/ram:TaxBasisTotalAmount |
| BT-110 | Total VAT | cac:TaxTotal/cbc:TaxAmount | MS/ram:TaxTotalAmount |
| BT-112 | Total with VAT | cac:LegalMonetaryTotal/cbc:TaxInclusiveAmount | MS/ram:GrandTotalAmount |
| BT-115 | Amount due | cac:LegalMonetaryTotal/cbc:PayableAmount | MS/ram:DuePayableAmount |
| BT-129 | Invoiced quantity per line | cac:InvoiceLine/cbc:InvoicedQuantity | rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity |
How BT-10 is filled for public-sector buyers is covered in What is a Leitweg-ID?. If your code has to read both syntaxes, check the root element first and pick the paths from there. This Python example uses only the standard library and reads BT-10 and BT-112 from either variant:
import sys
import xml.etree.ElementTree as ET
NS = {
"ubl": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
"cac": "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
"cbc": "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
"rsm": "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100",
"ram": "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100",
}
root = ET.parse(sys.argv[1]).getroot()
if root.tag == "{%s}Invoice" % NS["ubl"]:
bt10 = root.findtext("cbc:BuyerReference", namespaces=NS)
bt112 = root.findtext("cac:LegalMonetaryTotal/cbc:TaxInclusiveAmount", namespaces=NS)
elif root.tag == "{%s}CrossIndustryInvoice" % NS["rsm"]:
tx = "rsm:SupplyChainTradeTransaction/"
bt10 = root.findtext(tx + "ram:ApplicableHeaderTradeAgreement/ram:BuyerReference", namespaces=NS)
bt112 = root.findtext(tx + "ram:ApplicableHeaderTradeSettlement/"
"ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:GrandTotalAmount", namespaces=NS)
else:
sys.exit("Not an XRechnung: " + root.tag)
print("BT-10:", bt10, "| BT-112:", bt112)
The script works whatever prefix the file uses, because it looks elements up by namespace URI.
In what order is an XRechnung validated?
Validation runs in four stages. When one stage fails, the results of the later stages are often meaningless.
- Well-formedness. The file must be valid XML 1.0. An unescaped
&in "Miller & Sons Ltd" makes it unreadable; write&instead. See SCHEMA-001. - XSD. The XSD schema of the syntax checks element names, order, mandatory elements and data types. A comma as decimal separator, a missing
currencyIDor broken Base64 content in an attachment fail here. See SCHEMA-003. - EN 16931 Schematron. The standard's rules check mandatory fields (BR-…), calculations (BR-CO-…), code lists (BR-CL-…) and decimal places (BR-DEC-…), plus syntax-specific rules such as UBL-DT-01 (amounts with at most two decimals) or CII-DT-097 (date format). A typical hit is BR-CO-15: net plus VAT does not equal gross.
- KoSIT's XRechnung Schematron. The national BR-DE-… rules add to the standard, for example BR-DE-15 for a missing buyer reference BT-10. Some are "should" rules that only raise a warning; in version 3.0.2 this applies to BR-DE-17 (invoice type code) and BR-DE-21 (specification identifier).
The reference implementation for all four stages is the open-source KoSIT validator (opens in a new tab), written in Java, used together with the XRechnung validator configuration (opens in a new tab). The configuration bundles the XSD files and the Schematron rules compiled to XSLT. The validator picks a scenario based on the root element and BT-24. If none matches, it rejects the file without running the business rules at all.
java -jar validator-<version>-standalone.jar \
-s validator-configuration-xrechnung/scenarios.xml \
-r validator-configuration-xrechnung \
-o reports -h \
invoice.xml
The reports folder then contains an XML report whose verdict is accept or reject; -h also writes an HTML version. If you do not want to install Java, our e-invoice validator checks UBL and CII files against the official KoSIT rules and explains every message. All codes are listed under xrechnung validation errors, and the ten most common cases are covered in How to fix XRechnung validation errors.
What goes into BT-24 and BT-23?
BT-24 (cbc:CustomizationID or ram:GuidelineSpecifiedDocumentContextParameter/ram:ID) states which specification the file follows. For every 3.0.x release the identifier is urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0. If you use the Extension XRechnung, for example for sub-lines or XML attachments in construction, append #conformant#urn:xeinkauf.de:kosit:extension:xrechnung_3.0.
Older identifiers such as urn:xoev-de:kosit:standard:xrechnung_2.x are a common reason for rejection. BR-DE-21 only reports them as a warning, but the current validator configuration has no scenario for an expired version, so the file is rejected as a whole. The identifier is tied to the version; XRechnung 4.0 will use whatever identifier its final specification defines.
BT-23 (cbc:ProfileID or ram:BusinessProcessSpecifiedDocumentContextParameter/ram:ID) is optional in EN 16931 but mandatory in XRechnung 3.0.2: KoSIT's rules include the Peppol rule PEPPOL-EN16931-R001, "Business process MUST be provided". The usual value is urn:fdc:peppol.eu:2017:poacc:billing:01:1.0.
Which code lists and data formats apply?
- Units of measure (BT-130) come from UN/ECE Recommendations 20 and 21, e.g.
C62(one),H87(piece),HUR(hour),DAY(day),KGM(kilogram) andLS(lump sum). - VAT category codes (BT-118, BT-151) include
S(standard rate),Z(zero rated),E(exempt),AE(reverse charge) andK(intra-community supply). The glossary entry VAT category code has the full list. - Invoice type codes (BT-3) come from UNTDID 1001. Under BR-DE-17, XRechnung expects 326, 380, 381, 384, 389, 875, 876 or 877; see invoice type code.
- Currencies follow ISO 4217 (
EUR), country codes ISO 3166-1 alpha-2 (DE). - Dates: UBL
2026-09-28, CII20260928withformat="102". - Amounts use a dot as decimal separator and no thousands separator. Invoice amounts have at most two decimal places; unit prices may have more.
- Encoding: UTF-8. The declaration in the prolog must match the actual bytes, otherwise "Straße" turns into "Straße" when the file is read.
What mistakes do developers make most often?
We reproduced each of the following cases with KoSIT validator 1.5.0 and the XRechnung 3.0.2 validator configuration.
| Mistake | What the report says | Fix |
|---|---|---|
| Typo in a namespace URI | no matching scenario, rejected | copy the URI exactly from the table above |
| Element in the wrong position | XSD error | follow the order defined in the schema |
CII date 2026-09-28 | CII-DT-097 | 20260928 with format="102" |
CII date without format | BR-03, issue date missing | add the attribute |
| Comma as decimal separator | XSD error | 1785.00, not 1785,00 |
| Three decimals in the amount due | BR-DEC-18, UBL-DT-01 | round to two places, recalculate totals |
currencyID missing in UBL | XSD error, BR-CL-03 | set the attribute on every amount |
Unescaped & in a company name | file not well-formed | write & or let a serializer do it |
| Outdated identifier in BT-24 | BR-DE-21, no scenario | use the 3.0 identifier |
cbc:ProfileID missing | PEPPOL-EN16931-R001 | add BT-23 |
cbc:BuyerReference missing | BR-DE-15 | enter the Leitweg-ID or another buyer reference |
Most of these errors disappear once the file is written by an XML library that handles namespaces, escaping and encoding, rather than assembled by string concatenation.
Which tools help you read and check the XML?
For a quick look at the structure, the XML viewer opens any XML file as a collapsible tree. The xrechnung viewer renders UBL and CII invoices in readable form and validates them with the KoSIT rules. If you need a reference for your own output, create a UBL file with the xrechnung generator and compare it element by element. To test a parser, use the sample invoice and the deliberately broken test file. How attachments end up in the XML as Base64 is shown in XRechnung attachments, and the business side of producing a file is covered in how to create an XRechnung step by step.
Tools for this article
- XML ViewerPaste or upload any XML — collapsible tree view, syntax highlighting, XPath queries.Open tool →
- XRechnung ViewerParse, validate & repair German e-invoices with GoBD-compliant audit trail.Open tool →
- KoSIT Error HubSearchable reference for all XRechnung validation error codes with fix guides.Open tool →
Frequently asked questions
Is there an official XRechnung XSD?
No. XRechnung reuses the schemas of its two syntaxes: UBL 2.1 with UBL-Invoice-2.1.xsd and UBL-CreditNote-2.1.xsd, and UN/CEFACT CII D16B with CrossIndustryInvoice_100pD16B.xsd. KoSIT ships these files together with the Schematron rules in the validator-configuration-xrechnung package on GitHub. A schema check alone is not enough, because the business rules are only tested in the Schematron stage.
Is XRechnung UBL or CII?
Both. XRechnung is a semantic standard based on EN 16931 and may be expressed in UBL 2.1 or in UN/CEFACT CII D16B. Both variants carry the same identifier in BT-24 and run through the same business rules. UBL is common on the Peppol network, while CII is the XML part of every ZUGFeRD invoice. Your choice of syntax does not affect whether the invoice is valid.
What namespaces does a UBL XRechnung use?
A UBL XRechnung declares the document namespace urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 (CreditNote-2 for credit notes), plus CommonAggregateComponents-2 for cac elements and CommonBasicComponents-2 for cbc elements. The prefixes are arbitrary; only the URI counts. A single typo in a URI means the KoSIT validator finds no matching validation scenario and rejects the file.
What date format does XRechnung use?
It depends on the syntax. UBL uses the XML Schema date format YYYY-MM-DD, for example 2026-09-28 in cbc:IssueDate. CII writes the date without separators as 20260928 in udt:DateTimeString, with format code 102 in the format attribute. A hyphenated date in CII triggers CII-DT-097. Without the format attribute, the rules do not recognise the issue date at all and report BR-03.
What validation steps does an XRechnung have to pass?
Four stages. The file must be well-formed XML, match the XSD of its syntax, satisfy the EN 16931 Schematron rules (for example BR-CO-15: net plus VAT equals gross) and comply with KoSIT's XRechnung rules (for example BR-DE-15 for the buyer reference BT-10). The KoSIT validator runs all stages in order and writes a report that ends in accept or reject.