XRechnung

XRechnung validation: the German rules, the fields they ask for, and what KoSIT said

XRechnung is a German CIUS — a narrowing — of EN 16931. The rules are the same whether you send UBL or CII: the syntax changes the file, not the rule set.

The rejection you are probably holding

A German portal answers with the rule id and the element, in German, and stops there:

what the portal sends back
[BR-DE-15]-Das Element "Buyer reference" (BT-10) muss übermittelt werden.

Here is the same failure from Attestwire. Same rule, plus the business term, what the regulation wants, the field to set and a page to read:

the finding you get instead
{
  "rule": "BR-DE-15",
  "field": "BT-10",
  "severity": "fatal",
  "message": "XRechnung requires a buyer reference (BT-10). For German public-sector buyers this is the Leitweg-ID; business buyers may supply any reference, but the field must be present.",
  "fix": "Ask your client for their Leitweg-ID (public sector) or an order/customer reference, and set buyerReference.",
  "example": "\"buyerReference\": \"04011000-1234512345-06\"",
  "xpath": "/ubl:Invoice/cbc:BuyerReference",
  "docsUrl": "https://attestwire.com/rules/BR-DE-15"
}

What XRechnung adds on top of core EN 16931

This is measured, not listed. Take an invoice that is conformant against core EN 16931 — it validates clean, no findings at any severity — change one field to profile: "xrechnung-ubl", and run it again. 3 rules now fail:

That is the German delta for this invoice, in fields you can go and set today: a buyer reference, payment instructions, and a complete seller contact. The same run also raises 2 Peppol warnings about the electronic address, which is the field a routing network needs and a German portal will ask about sooner or later.

Your own invoice will differ. The point is the shape: the CIUS does not change what an invoice means, it makes optional things mandatory.

Every BR-DE rule, with a page each

31 rules carry the BR-DE prefix in this build — 24 of them fatal, the rest warnings and advisories. Each id links a permanent page with the normative text, why the rule exists, the field to change and a passing example. It is the same page the docsUrl on a finding points at, so an error in your log gets you here in one click.

Rule Term Severity What it asks for
BR-DE-1 BG-16 fatal XRechnung requires payment instructions
BR-DE-2 BG-6 fatal XRechnung requires seller contact details — all three of them
BR-DE-3 BT-37 fatal XRechnung requires the element "Seller city" (BT-37)
BR-DE-4 BT-38 fatal XRechnung requires the element "Seller post code" (BT-38)
BR-DE-5 BT-41 fatal XRechnung requires the element "Seller contact point" (BT-41)
BR-DE-6 BT-42 fatal XRechnung requires a seller telephone number
BR-DE-7 BT-43 fatal XRechnung requires a seller email address
BR-DE-8 BT-52 fatal XRechnung requires the element "Buyer city" (BT-52)
BR-DE-9 BT-53 fatal XRechnung requires the element "Buyer post code" (BT-53)
BR-DE-10 BT-77 fatal XRechnung requires the element "Deliver to city" (BT-77) whenever the deliver-to address group (BG-15) is present
BR-DE-11 BT-78 fatal XRechnung requires the element "Deliver to post code" (BT-78) whenever the deliver-to address group (BG-15) is present
BR-DE-14 BT-119 fatal XRechnung requires a VAT rate on every breakdown group
BR-DE-15 BT-10 fatal XRechnung requires a buyer reference
BR-DE-16 BT-31 / BT-32 fatal XRechnung requires a seller tax identifier for almost every category
BR-DE-17 BT-3 warning XRechnung narrows the invoice type codes to eight
BR-DE-18 BT-20 fatal A line of the payment terms (BT-20) starts with "#", which marks it as a Skonto (early-payment discount) entry, but "#SKONTO#TAGE=14#PROZENT=2#" does not match the grammar XRechnung prescribes
BR-DE-19 BT-84 warning The IBAN on a SEPA credit transfer must check out
BR-DE-20 BT-91 warning The payment means type code (BT-81) is "59" (SEPA direct debit), so the debited account identifier (BT-91) should be a valid IBAN — but "DE98700500001234567891" fails the ISO 7064 MOD-97-10 check digits
BR-DE-22 BG-24 / BT-125 fatal Two embedded attachments carry the same filename "a.pdf" — supportingDocuments[0] and supportingDocuments[1]
BR-DE-23-a BG-17 / BT-84 fatal A credit transfer code obliges the credit transfer group
BR-DE-23-b BG-18 fatal The payment means type code (BT-81) is "58", which XRechnung treats as a credit transfer (codes 30 and 58), so the PAYMENT CARD INFORMATION (BG-18) group must not be present — but it is
BR-DE-24-a BG-18 fatal The payment means type code (BT-81) is "48", which XRechnung treats as a card payment, so exactly one PAYMENT CARD INFORMATION group (BG-18) must be present
BR-DE-24-b BG-17 / BG-19 fatal The payment means type code (BT-81) is "48", which XRechnung treats as a card payment (codes 48, 54 and 55), so the CREDIT TRANSFER (BG-17) and DIRECT DEBIT (BG-19) groups must not be present — but they are
BR-DE-25-a BG-19 fatal The payment means type code (BT-81) is "59" (SEPA direct debit), so exactly one DIRECT DEBIT group (BG-19) must be present
BR-DE-25-b BG-17 fatal The payment means type code (BT-81) is "59", which XRechnung treats as a direct debit (code 59), so the CREDIT TRANSFER (BG-17) group must not be present — but it is
BR-DE-26 BG-3 / BT-25 warning The invoice type code (BT-3) is "384" (corrected invoice), so the PRECEDING INVOICE REFERENCE group (BG-3) should be present at least once, carrying the number of the invoice being corrected (BT-25)
BR-DE-27 BT-42 warning The seller contact telephone number (BT-42) should contain at least three digits, but "call us" contains 0
BR-DE-28 BT-43 warning The seller contact email address (BT-43) must contain exactly one "@", flanked by at least two characters on each side and by neither a space nor a dot, and must not begin or end with a dot
BR-DE-30 BG-19 / BT-90 fatal The invoice carries a DIRECT DEBIT group (BG-19), so the bank assigned creditor identifier (BT-90) must be present
BR-DE-31 BG-19 / BT-91 fatal The invoice carries a DIRECT DEBIT group (BG-19), so the debited account identifier (BT-91) must be present
BR-DE-TMP-32 BT-72 / BG-14 information This invoice states no time of supply: it carries neither an actual delivery date (BT-72), nor an invoicing period (BG-14), nor a period on every invoice line (BG-26)

Severity is the reference validator's, not ours. fatal: Rejects the document. warning: Raised, and the document is still accepted. information: Advisory. Never blocks anything. The whole rule reference, all profiles →

What KoSIT said about our own output

11 committed release fixtures — 5 UBL and 6 CII — were acceptable to KoSIT 1.6.2 with the XRechnung 3.0.2 configuration on 13 August 2026, with zero findings.

That is evidence about those 11 generated fixtures. It is not a parity suite, and it is not a guarantee that any particular receiver will accept your document. Documents you upload are not run through KoSIT at request time.

The run in full: commands, versions, the per-fixture table → · How current the rule artefacts are →

UBL or CII?

XRechnung has two syntax bindings and this build writes and reads both: xrechnung-ubl and xrechnung-cii. Same rule set, same findings, different file. Send whichever your receiver asked for; if nobody said, UBL is the safer default in Germany.

One boundary to know before you pick xrechnung-cii: CII is also the syntax inside a ZUGFeRD or Factur-X PDF, and what we generate is the XML, never the PDF/A-3 container. The exact rule on PDF, in both directions →

How the two syntaxes differ, and how to tell which one you are holding →

Try it on an invoice

The sample in the playground is a real XRechnung with one field taken out. Fix the field, generate the XML, and watch the finding disappear — or switch tabs and paste your own file instead, which is checked in your browser and never uploaded.

Check an invoice in the playground

Questions people ask next

Is XRechnung mandatory in Germany?

For invoicing German public-sector buyers, yes — XRechnung is the standard those contracting authorities receive. For business-to-business invoices the picture is a calendar: receiving domestic B2B e-invoices has been mandatory since January 2025. Issuing starts 1 January 2027 above €800,000 prior-year turnover, 1 January 2028 for everyone else. XRechnung is one conformant way to meet that. The obligation is to EN 16931, not to this profile specifically. What we do and do not cover →

XRechnung or ZUGFeRD — which one do I need?

Ask your buyer, because they are different deliverables. XRechnung is a pure XML document, and it is what German public-sector buyers ask for. ZUGFeRD (and its French twin Factur-X) is a PDF/A-3 file with CII XML attached inside it, which suits a buyer who wants something a human can also read. Attestwire writes the XML for both and builds the PDF container for neither: for ZUGFeRD you take our CII payload to a PDF/A-3 library. Reading goes the other way — extractFacturX opens an existing ZUGFeRD or Factur-X PDF and hands back the XML inside it.

How do I validate an XRechnung file?

Paste it into the playground and you get findings in the browser, with no key and no upload. In code, read the file with parseUbl or parseCiiInvoice and pass the result to validateInput; over HTTP, POST it to the hosted API as application/xml. All three run the same rules and return the same findings. For a binding verdict you still want KoSIT's own validator, which is the German authority and which we run our fixtures through.

Can I validate XRechnung without uploading it?

Yes, and that is the default. The playground runs the engine as a module inside your browser tab, so no request carrying your document leaves the page. The npm package and the GitHub Action do the same thing on your own machine, offline and with no key. The hosted API is the one door that receives the document, and it processes payloads in memory without storing them.

What does the Leitweg-ID have to do with BR-DE-15?

BR-DE-15 requires a buyer reference (BT-10) on every XRechnung. For a German public-sector buyer that reference is the Leitweg-ID, the routing identifier the authority issues you — so a missing Leitweg-ID and a failed BR-DE-15 are usually the same problem. A business buyer may put any order or customer reference in the field; what the rule will not accept is the field being absent. The rule page has a passing example →

Next.

The full rule reference → · Generate XRechnung from TypeScript → · Check invoices in your pipeline → · What we don't do →