InvoiceKit

Validate an XRechnung without sending it to anyone

Paste or drop a CII invoice and get the German report back: every EN 16931 assertion plus the national rules KoSIT adds on top, each finding with its rule id, the message the artefact itself writes, and the place in the document where it bit. The check runs in this tab, so your invoice is never uploaded — there is no account, no queue and no watermark, and the page keeps working with the network unplugged.

862 assertions against a CII invoice and 1,038 against a UBL one, of which 52 and 56 are XRechnung's own · the artefacts are 2.6.0, for XRechnung 3.0.2 · counted by the engine that does the checking, not by a summary

Who needs this. Every business in Germany has had to be able to receive an electronic invoice since January 2025, and sending becomes mandatory in stages from 2027. For the public sector the format is XRechnung: EN 16931 with a German layer on top, and that layer is where most rejected invoices actually fail — the Leitweg-ID, the seller contact, the payment groups. This page checks that layer, and says so rule by rule.

Got the invoice as a ZUGFeRD or Factur-X PDF? Audit the PDF itself — same engine, same XRechnung rule set, plus the PDF/A-3 and attachment checks. Building an invoice from scratch? Write one from a form.

Check an invoice

or drag a file onto the box, or paste below.

the engine starts on your first check

The rule set is already on XRechnung — that is what this page is for. Switch it to EN 16931 only to see which findings are German and which are the norm, and every report says out loud which rule set produced it. The XRechnung sample is a real CII invoice that passes with no violations and three warnings: the specification identifier (BR-DE-21), the seller's phone number (BR-DE-27) and the seller's email address (BR-DE-28). Those three are what most first attempts fail on.

Report

Nothing to report yet. The engine loads once, then every check is local.

What the invoice says

The same bytes read back as an invoice rather than as a rule report: the number, the parties, the Leitweg-ID, the amounts and the lines exactly as the document states them. Nothing is recomputed here, so a total that disagrees with its lines stays on the page next to the rule that says so.

The same document read back as an invoice: number, parties, amounts and lines exactly as written.

Converted document

Nothing converted yet. A CII XRechnung can be rewritten as UBL here, in this tab, and the result is checked against the rule set in the dropdown — which is how you find out whether the German invoice a Peppol supplier will accept.

What the check runs

XRechnung does not replace EN 16931 — it runs the whole norm and then its own rules on top, which is why “how many rules does XRechnung have?” has two answers. The German artefacts are 2.6.0, for XRechnung 3.0.2, on EN 16931 Schematron 1.3.17 (updated 2026-10-09).
LayerGrammarAssertions runof which XRechnung's
EN 16931 aloneCII810—
EN 16931 aloneUBL982—
XRechnung on topCII862+52
XRechnung on topUBL1038+56

Counts are per grammar because the two are validated by different artefacts, and they are assertions, not rule ids: one id is usually two assertions, one written against CII and one against UBL. Numbers quoted elsewhere are often ids, or one grammar only, which is how “XRechnung has 205 rules” and “XRechnung has 862 rules” both circulate.

Order matters, and so does severity. The engine checks the document's XML structure first — an element where the grammar does not allow one, an element in the wrong place, an attribute the schema does not permit — and reports those as SCHEMA findings rather than as rule ids. Only then does it run the Schematron rules, and it runs them in their artefacts' own phases: EN16931-model-phase, codelist_phase, syntax_phase and xrechnung-model. Of the 862 assertions it applies to a CII invoice, 379 are fatal, 482 are warnings and exactly 1 is informational.

The severity comes from the artefact's own wording: a rule that says muss is fatal and one that says soll is a warning. Almost all of XRechnung's additions are muss; the warnings are the ones people argue about, and both this page and the command-line tool still call the invoice not valid when only warnings fire, because that is how the buyers' gates treat them. The one informational assertion is BR-DE-TMP-32, a should about stating a delivery date or an invoicing period, which is reported without failing anything.

Every rule XRechnung adds

XRechnung's 52 CII and 56 UBL additions over EN 16931 — the BR-DE-* family and its sub-families BR-DEX-*, BR-DE-CVD-*, BR-TMP-* and BR-DE-TMP-*. One row per wording, so an id the two grammars state differently appears twice; the message is the artefact's own, quoted unmodified.
RuleAdded byApplies toSeverityWhat the rule says
BR-DE-1XRechnungCII and UBLfatalEine Rechnung (INVOICE) muss Angaben zu "PAYMENT INSTRUCTIONS" (BG-16) enthalten.
BR-DE-2XRechnungCII and UBLfatalDie Gruppe "SELLER CONTACT" (BG-6) muss übermittelt werden.
BR-DE-3XRechnungCII and UBLfatalDas Element "Seller city" (BT-37) muss übermittelt werden.
BR-DE-4XRechnungCII and UBLfatalDas Element "Seller post code" (BT-38) muss übermittelt werden.
BR-DE-5XRechnungCII and UBLfatalDas Element "Seller contact point" (BT-41) muss übermittelt werden.
BR-DE-6XRechnungCII and UBLfatalDas Element "Seller contact telephone number" (BT-42) muss übermittelt werden.
BR-DE-7XRechnungCII and UBLfatalDas Element "Seller contact email address" (BT-43) muss übermittelt werden.
BR-DE-8XRechnungCII and UBLfatalDas Element "Buyer city" (BT-52) muss übermittelt werden.
BR-DE-9XRechnungCII and UBLfatalDas Element "Buyer post code" (BT-53) muss übermittelt werden.
BR-DE-10XRechnungCII and UBLfatalDas Element "Deliver to city" (BT-77) muss übermittelt werden, wenn die Gruppe "DELIVER TO ADDRESS" (BG-15) übermittelt wird.
BR-DE-11XRechnungCII and UBLfatalDas Element "Deliver to post code" (BT-78) muss übermittelt werden, wenn die Gruppe "DELIVER TO ADDRESS" (BG-15) übermittelt wird.
BR-DE-14XRechnungCII and UBLfatalDas Element "VAT category rate" (BT-119) muss übermittelt werden.
BR-DE-15XRechnungCII and UBLfatalDas Element "Buyer reference" (BT-10) muss übermittelt werden.
BR-DE-16XRechnungCII and UBLfatalWenn in einer Rechnung die Steuercodes S, Z, E, AE, K, G, L oder M verwendet werden, muss mindestens eines der Elemente "Seller VAT identifier" (BT-31), "Seller tax registration identifier" (BT-32) oder "SELLER TAX REPRESENTATIVE PARTY" (BG-11) übermittelt werden.
BR-DE-17XRechnungCII and UBLwarningMit dem Element "Invoice type code" (BT-3) sollen ausschließlich folgende Codes aus der Codeliste UNTDID 1001 übermittelt werden: 326 (Partial invoice), 380 (Commercial invoice), 384 (Corrected invoice), 389 (Self-billed invoice) und 381 (Credit note),875 (Partial construction invoice), 876 (Partial final construction invoice), 877 (Final construction invoice).
BR-DE-18XRechnungCIIfatalSkonto Zeilen in muessen diesem regulärem Ausdruck entsprechen: . Die Informationen zur Gewährung von Skonto müssen wie folgt im Element "Payment terms" (BT-20) übermittelt werden: Anzugeben ist im ersten Segment "SKONTO", im zweiten "TAGE=n", im dritten "PROZENT=n". Prozentzahlen sind ohne Vorzeichen sowie mit Punkt getrennt von zwei Nachkommastellen anzugeben. Liegt dem zu berechnenden Betrag nicht BT-115, "fälliger Betrag" zugrunde, sondern nur ein Teil des fälligen Betrags der Rechnung, ist der Grundwert zur Berechnung von Skonto als viertes Segment "BASISBETRAG=n" gemäß dem semantischen Datentypen Amount anzugeben. Jeder Eintrag beginnt mit einer #, die Segmente sind mit einer # getrennt und eine Zeile schließt mit einer # ab. Am Ende einer vollständigen Skontoangabe muss ein XML-konformer Zeilenumbruch folgen. Alle Angaben zur Gewährung von Skonto müssen in Großbuchstaben gemacht werden. Zusätzliches Whitespace (Leerzeichen, Tabulatoren oder Zeilenumbrüche) ist nicht zulässig. Andere Zeichen oder Texte als in den oberen Vorgaben genannt sind nicht zulässig.
BR-DE-18XRechnungUBLfatalSkonto Zeilen in müssen diesem regulärem Ausdruck entsprechen: . Die Informationen zur Gewährung von Skonto müssen wie folgt im Element "Payment terms" (BT-20) übermittelt werden: Anzugeben ist im ersten Segment "SKONTO", im zweiten "TAGE=n", im dritten "PROZENT=n". Prozentzahlen sind ohne Vorzeichen sowie mit Punkt getrennt von zwei Nachkommastellen anzugeben. Liegt dem zu berechnenden Betrag nicht BT-115, "fälliger Betrag" zugrunde, sondern nur ein Teil des fälligen Betrags der Rechnung, ist der Grundwert zur Berechnung von Skonto als viertes Segment "BASISBETRAG=n" gemäß dem semantischen Datentypen Amount anzugeben. Jeder Eintrag beginnt mit einer #, die Segmente sind mit einer # getrennt und eine Zeile schließt mit einer # ab. Am Ende einer vollständigen Skontoangabe muss ein XML-konformer Zeilenumbruch folgen. Alle Angaben zur Gewährung von Skonto müssen in Großbuchstaben gemacht werden. Zusätzliches Whitespace (Leerzeichen, Tabulatoren oder Zeilenumbrüche) ist nicht zulässig. Andere Zeichen oder Texte als in den oberen Vorgaben genannt sind nicht zulässig.
BR-DE-19XRechnungCII and UBLwarning"Payment account identifier" (BT-84) soll eine korrekte IBAN enthalten, wenn in "Payment means type code" (BT-81) mit dem Code 58 SEPA als Zahlungsmittel gefordert wird.
BR-DE-20XRechnungCII and UBLwarning"Debited account identifier" (BT-91) soll eine korrekte IBAN enthalten, wenn in "Payment means type code" (BT-81) mit dem Code 59 SEPA als Zahlungsmittel gefordert wird.
BR-DE-21XRechnungCII and UBLwarningDas Element "Specification identifier" (BT-24) soll syntaktisch der Kennung des Standards XRechnung entsprechen.
BR-DE-22XRechnungCIIfatalNot all filename attributes of the embeddedDocumentBinaryObject elements are unique
BR-DE-22XRechnungUBLfatalDas "filename"-Attribut aller "EmbeddedDocumentBinaryObject"-Elemente muss eindeutig sein
BR-DE-23-aXRechnungCII and UBLfatalWenn BT-81 "Payment means type code" einen Schlüssel für Überweisungen enthält (30, 58), muss BG-17 "CREDIT TRANSFER" übermittelt werden.
BR-DE-23-bXRechnungCII and UBLfatalWenn BT-81 "Payment means type code" einen Schlüssel für Überweisungen enthält (30, 58), dürfen BG-18 und BG-19 nicht übermittelt werden.
BR-DE-24-aXRechnungCII and UBLfatalWenn BT-81 "Payment means type code" einen Schlüssel für Kartenzahlungen enthält (48, 54, 55), muss genau BG-18 "PAYMENT CARD INFORMATION" übermittelt werden.
BR-DE-24-bXRechnungCII and UBLfatalWenn BT-81 "Payment means type code" einen Schlüssel für Kartenzahlungen enthält (48, 54, 55), dürfen BG-17 und BG-19 nicht übermittelt werden.
BR-DE-25-aXRechnungCII and UBLfatalWenn BT-81 "Payment means type code" einen Schlüssel für Lastschriften enthält (59), muss genau BG-19 "DIRECT DEBIT" übermittelt werden.
BR-DE-25-bXRechnungCII and UBLfatalWenn BT-81 "Payment means type code" einen Schlüssel für Lastschriften enthält (59), dürfen BG-17 und BG-18 nicht übermittelt werden.
BR-DE-26XRechnungCIIwarningWenn im Element Invoice type code (BT-3) der Code 384 (Corrected invoice) übergeben wird, soll PRECEDING INVOICE REFERENCE BG-3 mind. einmal vorhanden sein.
BR-DE-26XRechnungUBLwarningWenn im Element "Invoice type code" (BT-3) der Code 384 (Corrected invoice) übergeben wird, soll PRECEDING INVOICE REFERENCE BG-3 mind. einmal vorhanden sein.
BR-DE-27XRechnungCII and UBLwarningIn BT-42 sollen mindestens drei Ziffern enthalten sein.
BR-DE-28XRechnungCII and UBLwarningIn BT-43 soll genau ein @-Zeichen enthalten sein, welches nicht von einem Leerzeichen, einem Punkt, aber mindestens zwei Zeichen auf beiden Seiten flankiert werden soll. Ein Punkt sollte nicht am Anfang oder am Ende stehen.
BR-DE-30XRechnungCII and UBLfatalWenn "DIRECT DEBIT" BG-19 vorhanden ist, dann muss "Bank assigned creditor identifier" BT-90 übermittelt werden.
BR-DE-31XRechnungCII and UBLfatalWenn "DIRECT DEBIT" BG-19 vorhanden ist, dann muss "Debited account identifier" BT-91 übermittelt werden.
BR-DE-CVD-01XRechnungCII and UBLfatalDas Element "Contract reference" (BT-12) muss übermittelt werden.
BR-DE-CVD-02XRechnungCII and UBLfatalDas Element "Tender or lot reference" (BT-17) muss übermittelt werden.
BR-DE-CVD-03XRechnungCII and UBLfatalIn einer Rechnung muss mindestens eine INVOICE LINE (BG-25) enthalten sein, in der der Scheme identifier von "Item classification identifier" (BT-158) den Wert 'CVD' und der "Item attribute name" (BT-160) den Wert 'cva' enthält.
BR-DE-CVD-04XRechnungCII and UBLfatalEin "Item classification identifier" (BT-158) mit dem Scheme identifier 'CVD' muss einen Wert aus der Liste der zulässigen Fahrzeugkategorien enthalten.
BR-DE-CVD-05XRechnungCII and UBLfatalWenn innerhalb von ITEM ATTRIBUTES (BG-32) der "Item attribute name" (BT-160) den Wert 'cva' hat, muss der "Item attribute value" (BT-161) einen der zulässigen Werte enthalten.
BR-DE-CVD-06-aXRechnungCII and UBLfatalWenn der Scheme identifier von "Item classification identifier" (BT-158) mit dem Wert 'CVD' angegeben ist, muss in derselben Rechnungszeile genau ein "Item attribute name" (BT-160) mit dem Wert 'cva' vorhanden sein.
BR-DE-CVD-06-bXRechnungCII and UBLfatalWenn "Item attribute name" (BT-160) mit dem Wert 'cva' angegeben ist, muss in derselben Rechnungszeile genau ein "Item classification identifier" (BT-158) mit dem Scheme identifier 'CVD' vorhanden sein.
BR-DE-TMP-32XRechnungCII and UBLinformationEine Rechnung sollte zur Angabe des Liefer-/Leistungsdatums entweder BT-72 "Actual delivery date", BG-14 "Invoicing period" oder in jeder Rechnungsposition BG-26 "Invoice line period" enthalten.
BR-DEX-01XRechnungCII and UBLfatalDas Element "Attached Document" (BT-125) benutzt einen nicht zulässigen MIME-Code: . Im Falle einer Extension darf zusätzlich zu der Liste der mime codes (definiert in Abschnitt 8.2, "Binary Object") der MIME-Code application/xml genutzt werden.
BR-DEX-02XRechnungUBLwarningDer Wert von "Invoice line net amount" (BT-131) einer "INVOICE LINE" (BG-25) oder einer "SUB INVOICE LINE" (BG-DEX-01) soll der Summe der "Invoice line net amount" (BT-131) der direkt darunterliegenden "SUB INVOICE LINE" (BG-DEX-01) entsprechen.
BR-DEX-03XRechnungUBLfatalEine Sub Invoice Line (BG-DEX-01) muss genau eine "SUB INVOICE LINE VAT INFORMATION" (BG-DEX-06) enthalten.
BR-DEX-04XRechnungCII and UBLfatalAny scheme identifier in MUST be coded using one of the ISO 6523 ICD list.
BR-DEX-05XRechnungCII and UBLfatalAny scheme identifier in MUST be coded using one of the ISO 6523 ICD list.
BR-DEX-06XRechnungCII and UBLfatalAny scheme identifier in MUST be coded using one of the ISO 6523 ICD list.
BR-DEX-07XRechnungCII and UBLfatalAny scheme identifier for an Endpoint Identifier in MUST belong to the CEF EAS code list.
BR-DEX-08XRechnungCII and UBLfatalAny scheme identifier for a Delivery location identifier in MUST be coded using one of the ISO 6523 ICD list.
BR-DEX-09XRechnungUBLfatalAmount due for payment (BT-115) = Invoice total amount with VAT (BT-112) - Paid amount (BT-113) + Rounding amount (BT-114) + Σ Third party payment amount (BT-DEX-002).
BR-DEX-10XRechnungUBLfatalDas Element "Third party payment type" BT-DEX-001 muss übermittelt werden, wenn die Gruppe "THIRD PARTY PAYMENT" (BG-DEX-09) übermittelt wird.
BR-DEX-11XRechnungUBLfatalDas Element "Third party payment amount" BT-DEX-002 muss übermittelt werden, wenn die Gruppe "THIRD PARTY PAYMENT" (BG-DEX-09) übermittelt wird.
BR-DEX-12XRechnungUBLfatalDas Element "Third party payment description" BT-DEX-003 muss übermittelt werden, wenn die Gruppe "THIRD PARTY PAYMENT" (BG-DEX-09) übermittelt wird.
BR-DEX-13XRechnungUBLfatalDie maximale Anzahl zulässiger Nachkommastellen für das Element "Third party payment amount" (BT-DEX-002) ist 2.
BR-DEX-14XRechnungUBLfatalDie Währungsangabe von "Third party payment amount" BT-DEX-002 muss BT-5 ("Invoice currency code") entsprechen.
BR-DEX-15XRechnungCIIwarningThis CII file might use the concept of Sub Invoice Lines. However XRechnung does not support this.
BR-TMP-2XRechnungCII and UBLfatalBT-124 "External document location" muss eine absolute URL mit gültigem Schema enthalten.
BR-TMP-3XRechnungCIIfatalWenn BT-149 (Item price base quantity) sowohl in GrossPriceProductTradePrice als auch in NetPriceProductTradePrice vorhanden ist, müssen die Werte identisch sein. Wenn BT-150 (unit of measure code) auf dem NetPrice-Pfad vorhanden ist, muss es auch auf dem GrossPrice-Pfad vorhanden und identisch sein.
BR-TMP-4XRechnungCIIwarningBT-123 "Supporting document description" (ram:Name) darf innerhalb von "Additional supporting documents" (BG-24) höchstens einmal vorkommen.
BR-TMP-5XRechnungCIIwarningBT-125 "Attached document" (ram:AttachmentBinaryObject) darf innerhalb von "Additional Supporting documents" (BG-24) höchstens einmal vorkommen.
BR-TMP-6XRechnungUBLwarningDatumsangaben in UBL müssen im Format JJJJ-MM-TT (YYYY-MM-DD) übermittelt werden.
BR-TMP-7XRechnungCIIwarningDatumsangaben in UNCEFACT/CII müssen das Attribut format="102" tragen und im Format JJJJMMTT (YYYYMMDD) übermittelt werden.
BR-TMP-CVD-01XRechnungCII and UBLfatalDas Bildungsschema für "Item classification identifier" (BT-158) ist aus der Codeliste UNTDID 7143 zu wählen.

The rules that catch people out

Rejections are not spread evenly over the rule set. These are the ones that turn up most in practice, in plain English — the table above has each id's own wording, and the search box finds it.

Warnings are the cheap fixes and the ones people leave: BR-DE-21 wants BT-24 to state the XRechnung specification identifier, BR-DE-26 wants a corrected invoice (BT-3 = 384) to reference the invoice it corrects, and BR-DE-19 and BR-DE-20 check the IBAN you put in when you said the payment was SEPA credit transfer or direct debit.

XRechnung, ZUGFeRD and Peppol: what actually runs

XRechnung is a CIUS: a national tightening of EN 16931 that may add rules and may not relax any. ZUGFeRD and Factur-X are a different axis — they are the same invoice embedded in a PDF/A-3 file, so a ZUGFeRD invoice destined for a German public buyer is normally checked as Factur-X envelope plus XRechnung business rules. Peppol BIS Billing 3.0 is a network profile with its own copy of the norm's artefacts, and Germany's participation in Peppol adds the DE-R country rules on top of that.

Pick the rule set you are being judged by, not the one that sounds closest: the validator on this page, the Factur-X checker, the CLI and the API all take the same choice, and the rule-set comparison counts exactly what each one adds.

The same check in a pipeline

The browser is for looking at one invoice. For checking a thousand, or for a rule that must fail a build, the engine is also a static binary with the rule sets embedded — no Java, no Saxon, no rule files to install beside it:

einv validate -cius xrechnung invoice.xml
einv validate -json -cius xrechnung invoice.xml | jq '.findings[].id'
einv artefacts -cius xrechnung
einv rules -json -syntax cii -cius xrechnung | wc -l

Exit status is non-zero when a document fails, so einv drops into CI as-is, and the JSON is the same findings the page shows. It is the same library that runs in this tab and behind the hosted API: see the command-line and Go library page for the library API and the batch mode.

The data behind this page

These figures get wrong when somebody retypes them into a tender response or a procurement policy, so the files the page is built from are published beside it:

Every number on this page is generated at build time from the artefacts the pinned engine loads, and the build stops if that data was counted from a different engine than the one the site ships — a stale figure here is a failed build rather than a paragraph nobody remembered to edit. The version they were counted under is v0.2.9.

The rules themselves are other people's publications: the norm's Schematron artefacts from the Connecting Europe Facility (EUPL 1.2) and XRechnung's from KoSIT (Apache 2.0), embedded unmodified. What is published here is the counting and the runner; sources and licences are spelled out in the engine repository's NOTICE.md.

Frequently asked

Is my invoice uploaded, stored or logged?

No. The validator is a WebAssembly binary that runs in this tab; there is no backend for your XML to travel to, and the page keeps working after it has loaded with the network unplugged. The hosted API is a separate product, and you only use it if you send documents to it deliberately.

Which XRechnung version does this check against?

The German artefacts the pinned engine loads: 2.6.0, for XRechnung 3.0.2 on EN 16931 Schematron 1.3.17 (updated 2026-10-09). Those numbers are in the page rather than in this answer on purpose — they move with releases, and every row in the published CSV and JSON carries the version it was counted under, so a figure can be pinned to a release.

Why are the rule messages in German?

Because that is what KoSIT's artefacts say, and the engine quotes the artefact's own message rather than paraphrasing it: the wording is what your buyer's validator will print, and a translation would be our opinion of the rule. A couple of assertions in the published artefacts happen to be English (BR-DE-22, BR-DEX-15), which tells you something about how rule sets are assembled. The common failures section is our plain-English summary of the same rules.

Does a warning fail the invoice?

In the norm's own terms, no: a warning is a should and a fatal finding is a must, and EN 16931 does not reject a document on a warning. In practice most buyers' gates do, so this page and the CLI report an invoice as not valid when any warning fires, and list warnings separately from violations so you can see what has to be fixed before you submit rather than what is merely untidy.

Does it check the XML schema as well as the business rules?

It checks structure first: an element the grammar does not allow, an element in the wrong order, or an attribute with the wrong shape comes back as a SCHEMA finding naming the position and what was expected there. Business rules run after that, because a rule about a misplaced element is not worth reporting — and the two kinds of finding are counted separately in every report, so a document that is structurally broken does not look like one that merely misses a field.

Can I validate a ZUGFeRD or Factur-X PDF against XRechnung?

Yes, on the Factur-X checker: it reads the PDF, checks the PDF/A-3 conformance and the attachment, then runs the invoice XML inside it through the same rule set, XRechnung included. The envelope and the invoice are judged separately, because they are fixed separately.

My invoice passes here and fails at the buyer's portal. Why?

Three usual reasons. The portal is running different artefact versions — compare the version this page names with the report you got. The buyer has rules of its own on top of the CIUS, which no published artefact contains and no validator can predict. Or the document failed on structure or on a warning the portal treats as fatal. If a rule id appears in their report and nowhere in ours, it is not a rule we can load, and we say so rather than guessing at it.

Is it really free?

Yes, in the browser, with no account and no email. The engine is open source under MIT with the European Commission's and KoSIT's artefacts embedded under their own licences; the CLI and the Go library are the same code. Paid work is the hosted API and batch pipelines, which is what the API & licences page is for. If anything here changes, the page will say so.