Free tool no signup
EN 16931 invoice validator.
Paste invoice data and see exactly which business rules it breaks, each with its rule identifier and the business term it applies to. It runs on your machine: the invoice is never uploaded, to us or to anyone.
Why the invoice does not leave your browser
An invoice carries a customer name, an address, amounts and often a bank account. Uploading that to a stranger's server to answer a question about a country code is a bad trade, and it is the reason a lot of people paste their data into nothing at all and guess instead.
The rule engine is pure computation: it reads a document and applies arithmetic and code lists, with no lookup and no external service. So it compiles to JavaScript and runs where you are. This page makes no network request when you press the button, which you can verify in your browser's network tab rather than taking our word for it.
It is also the identical module our paid server runs, imported rather than copied. There is one implementation of every rule, so the free answer and the billed answer cannot drift apart.
What it checks, and what it does not
29 rule groups are actively checked. 9 more appear below marked as satisfied by construction: they constrain totals that this engine recomputes from the lines rather than accepting from you, so they cannot be violated here at all. We list them separately instead of inflating the first number.
Got an identifier back and want to know what it means? The rule index explains each one, why it fires on invoices that look correct, and what to change.
| Rule | What it is about | Status |
|---|---|---|
| BR-01 | specification identifier | by construction |
| BR-02 | invoice number | checked |
| BR-03 | issue date | checked |
| BR-04 | invoice type code | checked |
| BR-05 | currency code | checked |
| BR-06 | seller name | checked |
| BR-07 | buyer name | checked |
| BR-08 | seller postal address | checked |
| BR-09 | seller country code | checked |
| BR-10 | buyer postal address | checked |
| BR-11 | buyer country code | checked |
| BR-12 | sum of line net amounts | by construction |
| BR-13 | invoice total without VAT | by construction |
| BR-14 | invoice total with VAT | by construction |
| BR-15 | amount due for payment | by construction |
| BR-16 | at least one invoice line | checked |
| BR-21 | line identifier | checked |
| BR-22 | line quantity | checked |
| BR-23 | line unit of measure | checked |
| BR-24 | line net amount | checked |
| BR-25 | item name | checked |
| BR-26 | item net price | checked |
| BR-27 | item net price is not negative | checked |
| BR-CO-10 | sum of line net amounts equals the lines | by construction |
| BR-CO-13 | total without VAT is consistent | by construction |
| BR-CO-15 | total with VAT equals total without VAT plus VAT | by construction |
| BR-CO-16 | amount due equals total with VAT minus prepaid | by construction |
| BR-DEC-* | amounts limited to two decimals | checked |
| BR-CL-* | codelists: currency, country, VAT category, invoice type | checked |
| BR-S-* | standard rate requires a positive VAT rate | checked |
| BR-Z-* | zero rate requires a zero VAT rate | checked |
| BR-E-* | exempt lines require a zero VAT rate | checked |
| BR-AE-* | reverse charge requires a zero VAT rate | checked |
| BR-K-* | intra-community supply requires a zero VAT rate | checked |
| BR-G-* | free export requires a zero VAT rate | checked |
| BR-O-* | outside the scope of VAT requires a zero VAT rate | checked |
| PEPPOL-EN16931-R120 | line net amount agrees with quantity times item net price | checked |
| ATW-PREPAID-EXCEEDS-TOTAL | prepaid amount does not exceed the invoice total | checked |
The full norm has roughly 150 rules, plus the national extensions a country adds on top. Passing here means no rule we check was broken. It does not mean a tax authority will accept the document, and anyone telling you otherwise is selling you certainty they do not have.
Reading a violation
Each row carries three things. The rule, such as BR-09, is the identifier used by the norm and by every other validator, so it is what to search when a partner rejects your document. The term, such as BT-40, names the field the rule constrains, so you know what to change. The message says what was actually wrong, including the value we saw, because a country code error is much easier to fix when you can see that the document said FRA rather than FR.
Severity matters too. An error is a rule the norm states as mandatory. A warning is an inconsistency we can detect but that the norm treats more loosely, such as a line total that disagrees with quantity times unit price. Warnings are usually a symptom of a bug upstream in whatever produced the file.
Questions people actually ask
- Does my invoice data leave my browser?
- No. The rule engine is JavaScript that runs on your machine, and this page makes no network request when you press Check it. You can confirm that in your browser's network tab, which is a better guarantee than our word.
- Is this the same engine as the paid API?
- Yes, literally the same module. The rule code is pure computation with no network calls, so the site imports it directly rather than reimplementing it. The free tool and the paid tool cannot disagree about what a rule means.
- Does passing this mean my invoice is compliant?
- No, and we will not say otherwise. It means none of the rules this engine checks was broken. The full norm has roughly 150 rules plus national extensions, and a tax authority applies its own. Treat a pass as one obstacle removed, not as clearance.
- Why does it accept incomplete data instead of rejecting it?
- Because refusing to read a malformed invoice would mean refusing to diagnose exactly the document you came here to diagnose. Missing and wrong fields are reported as rule violations, which is what you wanted to know.
- What is a business term, the BT number?
- EN 16931 gives every field in the semantic model an identifier, such as BT-40 for the seller country code. Rules are written against those identifiers, so quoting both tells you which rule fired and which field to change.
- Can I use this from an agent or a script?
- That is what InvoiceForge is for. The same validation is available as an MCP tool and over HTTP, alongside generating UBL documents and reading incoming ones, priced per call.
When you need this in a pipeline
This page is for the invoice in front of you. When it is a thousand of them, or when an agent needs to check a document mid-task, InvoiceForge exposes the same validation over MCP and plain HTTP, along with generating UBL documents and reading incoming ones back into structured data.