agenttoolworks

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.

RuleWhat it is aboutStatus
BR-01specification identifierby construction
BR-02invoice numberchecked
BR-03issue datechecked
BR-04invoice type codechecked
BR-05currency codechecked
BR-06seller namechecked
BR-07buyer namechecked
BR-08seller postal addresschecked
BR-09seller country codechecked
BR-10buyer postal addresschecked
BR-11buyer country codechecked
BR-12sum of line net amountsby construction
BR-13invoice total without VATby construction
BR-14invoice total with VATby construction
BR-15amount due for paymentby construction
BR-16at least one invoice linechecked
BR-21line identifierchecked
BR-22line quantitychecked
BR-23line unit of measurechecked
BR-24line net amountchecked
BR-25item namechecked
BR-26item net pricechecked
BR-27item net price is not negativechecked
BR-CO-10sum of line net amounts equals the linesby construction
BR-CO-13total without VAT is consistentby construction
BR-CO-15total with VAT equals total without VAT plus VATby construction
BR-CO-16amount due equals total with VAT minus prepaidby construction
BR-DEC-*amounts limited to two decimalschecked
BR-CL-*codelists: currency, country, VAT category, invoice typechecked
BR-S-*standard rate requires a positive VAT ratechecked
BR-Z-*zero rate requires a zero VAT ratechecked
BR-E-*exempt lines require a zero VAT ratechecked
BR-AE-*reverse charge requires a zero VAT ratechecked
BR-K-*intra-community supply requires a zero VAT ratechecked
BR-G-*free export requires a zero VAT ratechecked
BR-O-*outside the scope of VAT requires a zero VAT ratechecked
PEPPOL-EN16931-R120line net amount agrees with quantity times item net pricechecked
ATW-PREPAID-EXCEEDS-TOTALprepaid amount does not exceed the invoice totalchecked

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.