Lints invoice payloads and field mappings against EN 16931 and national CIUS rules (XRechnung, Factur-X, FatturaPA, Peppol BIS, KSeF): missing business terms, stale spec IDs, wrong mandate dates. Runs entirely in your browser — nothing is uploaded.
Same engine as the VS Code extension, byte for byte.
Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.
npmMCP server (npx)Docker Hubnpx @readystack/en16931-einvoice-lint <file> npx @readystack/en16931-einvoice-lint --mcp docker run --rm -v "$PWD:/w" getreadystack/en16931-einvoice-lint /w
Team? One key for every ReadyStack linter, 5 seats, $149 once
This page is the working piece. The full pack has everything below.
Checks an invoice payload or field mapping against EN 16931 and the national CIUS of the country it detects — 29 rules, in your editor.
A German tax adviser's time fee is fixed by StBVV § 13 at EUR 30-70 per half hour (EUR 60-140 an hour); one review of one invoice mapping costs more than this licence.
Buy the full version — $29· ReadyStack
Real numbers from this tool, line by line.

line 1 error EN 16931 is bound to UBL 2.1. UBL 2.0 is not supported.
line 2 error BT-24 Specification identifier must begin 'urn:cen.eu:en16931:2017#'.
line 3 error Dates are ISO 8601 YYYY-MM-DD. '01/09/2026' is ambiguous.
line 4 error BT-3 must be a 3-digit UNCL1001 code, not a word: 380, 381, 384.
line 5 error @unitCode must come from UN/ECE Recommendation 20: C62, H87, HUR.
line 6 error UBL requires @currencyID on every amount element.
line 6 error The decimal separator in XML is '.', never ','.
Six lines, seven findings. Real output. Here is the file that produced it — an invoice an assistant wrote when asked for "a Peppol BIS 3.0 invoice":
<cbc:UBLVersionID>2.0</cbc:UBLVersionID>
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
<cbc:IssueDate>01/09/2026</cbc:IssueDate>
<cbc:InvoiceTypeCode>INVOICE</cbc:InvoiceTypeCode>
<cbc:InvoicedQuantity unitCode="pcs">10</cbc:InvoicedQuantity>
<cbc:PayableAmount>1200,00</cbc:PayableAmount>
It looks perfect. In order:
...#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0, for XRechnung one ending xrechnung_3.0. A model trained on BIS 2.0 gives you a cenbii.eu URN.
01/09/2026. 1 September or 9 January? EN 16931 does not guess: ISO 8601, 2026-09-01.INVOICE. BT-3 is a UNCL1001 code, not a word: 380 invoice, 381 credit note.unitCode="pcs". Unit codes come from UN/ECE Rec 20 — C62 a piece, HUR an hour.1200,00 with no @currencyID. The separator is a point, and every amount needs itscurrency attribute — one line, two rejections.
This matters now. France crossed its line on 1 September 2026: every business established there must be able to receive a structured e-invoice. Belgium went first on 1 January, Poland's KSeF in February and April.
Not a knock on the models; it is structural. E-invoicing identifiers are versioned strings that change by revision and by country, on political timetables. Spain is the cleanest example: Verifactu was documented as starting January 2026 until Royal Decree-Law 15/2025 pushed it to
A date, a form number, a jurisdiction, a revision: the shape of question a model cannot reason its way to, and the answer that costs money when wrong. A rejected invoice is not a bug report, it is an unpaid one.
E-Invoicing Lint is a VS Code extension with 37 of these encoded as line rules, plus 26 snippets that are correct when you insert them. Every finding carries its BT- or BR- reference.
It runs offline; nothing you open leaves your machine. It also reads the country off the document: FR raises the September 2026 note, DE the Leitweg-ID in BT-10, and a Polish KSeF file is named as such rather than checked against rules that do not fit it.
These are line-level rules: wrong values, wrong codes, wrong formats. They do no cross-field arithmetic and cannot see a missing mandatory block. Use this while you write, and a full Schematron validator before you go live. A free web version runs the same 37 rules in one page, with a broken invoice already loaded.
Checking the file you have open: all 37 rules, all 26 snippets, no key, no counter, no watermark, nothing held back. That is the whole job of validating the invoice you are writing.
The licence is a different job, not a bigger one: every XML fixture in a repository at once, JSON output so a CI build fails when one stops being valid, and an exportable report. $49 once. Validating a single invoice, you will never need it.
It reads the invoice payload or field mapping open in your editor — JSON, YAML or XML — and applies 29 rules: the mandatory EN 16931 business terms, the national CIUS fields for the country it detects, and date rules that compare the file against the real mandate dates. Findings appear inline with the line that breaks and the change that fixes it.
Developers and integration consultants who ship invoicing code for customers in Germany, France, Italy, Belgium, Poland or Spain. If you are the person who maps your billing model onto XRechnung, Factur-X, FatturaPA, Peppol BIS or KSeF, this is the check that runs before the access point sees the document.
Free validators such as the Peppol test tool or the KoSIT schematron take a finished UBL or CII document and tell you it is malformed. They never see the JSON mapping in your repository, where the mistake was actually made, and they have no opinion about dates: they cannot tell you that the French deadline in your config is eight months wrong.
Checking the file in front of you is free and complete. All 29 rules run, every finding is shown with its fix, there is no watermark, no counter and no trial. The licence covers a different job: sweeping every invoice mapping in the workspace in one pass and writing a dated report file you keep, commit and hand to an auditor.
A German tax adviser's time fee is fixed by StBVV § 13 at EUR 30 to 70 per half hour, so EUR 60 to 140 an hour. Having one invoice mapping reviewed once costs more than the licence, and it tells you nothing about the mapping you change next week. The check runs again for free every time you save.
One question, answered by the person who built it. Your email only if you want the answer sent.