Origin and role
UBL is maintained by OASIS, a consortium for open standards, and describes not only invoices but a whole family of business documents — order, despatch advice, catalogue, credit note. The invoice is one document type within it.
In Europe UBL is ubiquitous mainly because Peppol builds on it. Wherever public procurement is handled electronically, UBL is almost always the syntax.
The structure
UBL lays its groups out flat rather than nesting them deeply:
1ubl:Invoice2├── cbc:CustomizationID which rule set applies (BT-24)3├── cbc:ID invoice number (BT-1)4├── cbc:IssueDate issue date (BT-2)5├── cbc:BuyerReference buyer reference (BT-10)6├── cac:AccountingSupplierParty seller (BG-4)7├── cac:AccountingCustomerParty buyer (BG-7)8├── cac:PaymentMeans payment instructions (BG-16)9├── cac:TaxTotal tax10├── cac:LegalMonetaryTotal totals11└── cac:InvoiceLine lines (BG-25)Anyone opening an invoice in XML for the first time usually finds their way around here faster than in CII: the order roughly follows that of a printed document.
cbc and cac
The two prefixes divide every element into two classes:
cbc— common basic components: single values. A number, a date, an amount.cac— common aggregate components: groups that in turn contain elements. A party, an address, a line.
The rule of thumb: what is a leaf on the tree is cbc. What forms a branch is
cac.
One field in its place
The same VAT identification number (BT-31) as in the CII article, here in UBL:
1<cac:AccountingSupplierParty>2 <cac:Party>3 <cac:PartyLegalEntity>4 <cbc:RegistrationName>Muster GmbH</cbc:RegistrationName>5 </cac:PartyLegalEntity>6 <cac:PartyTaxScheme>7 <cbc:CompanyID>DE811128135</cbc:CompanyID>8 <cac:TaxScheme>9 <cbc:ID>VAT</cbc:ID>10 </cac:TaxScheme>11 </cac:PartyTaxScheme>12 </cac:Party>13</cac:AccountingSupplierParty>The contrast with CII is easy to see: where CII distinguishes the kind of number
through an attribute (schemeID="VA"), UBL uses a dedicated sub-element
(cac:TaxScheme carrying VAT). Same statement, different mechanics.
The specification identifier
One element deserves particular attention, because it governs the entire validation:
1<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_3.0</cbc:CustomizationID>By this identifier (BT-24) a recipient recognises which rule set to check against. If it names only the European standard, they will not check the German add-on rules — and an invoice that was supposed to be an XRechnung arrives as a plain EN 16931 invoice.
🔴 A wrong CustomizationID produces no error. It produces a check against the
wrong rule set, and that only surfaces at the recipient.
When you meet UBL
When generating, whenever Peppol BIS is the target — there is no alternative there. For XRechnung, UBL is the more common of the two permitted variants.
When receiving, as unavoidably as CII. Anyone taking invoices from several sources gets both syntaxes, unannounced.
💡 So the same advice applies as for CII: syntax belongs at the outer boundary, not in your data model. Thinking internally in BT fields makes switching between UBL and CII a question of output — not a rebuild of business logic.