RXed AI News

AI to the bone.
An afternoon ↓ architecture v1.0 · 2026-09-19

The zero-rate check: the VAT number you validated once, two years ago

Your customer's VAT number is checked before every zero-rated invoice, and again each quarter. The proof is filed with the sale, not remembered.

Every EU business customer's VAT number checked before the invoice leaves and again each quarter, with the EU's own proof code filed next to the sale

Setup: An afternoon (~3-6 h) Running cost: $0-12/mo (software included) Time saved: none directly — the exposure per missed check is the VAT on that invoice plus interest - 21% standard rate in Belgium, 19% in Germany, 20% in France - against EUR 0 of software and a VPS you may already run; paid VAT-validation APIs wrapping the same free endpoint publish plans from EUR 5.99/month for 500 lookups (VAT Sense, checked 19/09/2026) After setup: — the checks and the quarterly sweep run themselves; deciding what to do with an invalid number stays with you, and nothing is ever sent to the customer by machine Data lives: Your server — The ledger holds your customer list and your own tax position on each sale. It calls one public EU endpoint and stores the answer locally; no customer data is handed to a third-party validation service that then knows exactly who you sell to.
VIESn8nGristNocoDBDockerInvoicingBookkeepingDocuments & archive
Built for small businesses in general — not a sector list.
Before you start
  • Your own VAT number - without it in the request the EU returns no consultation number, and you have a check you cannot prove you made
  • A list of which customers you actually invoice without VAT as a business in another EU member state - usually 5 to 50 rows, not thousands
  • An always-on machine or a mini-VPS at EUR 5-12/month running Docker
  • Your accountant told, once, that this ledger exists - they own the rest of the exemption file
What breaks first FAILS SILENTLY
the day VIES answers MS_UNAVAILABLE and the workflow records it as invalid. Half your customers get flagged dead on a Tuesday because a member state's system was down, and after two of those mornings you stop trusting the flags. Branch on three outcomes - valid, invalid, unreachable - from the first version, and count inconclusive checks per month.
Version history
v1.0 · 2026-09-19 — First release. Built on the European Commission's free VIES REST API (verified live 19/09/2026, including the consultation number that only appears when you pass your own VAT number), an append-only check ledger in Grist and three triggers in n8n. Written because a valid VAT identification number has been a substantive condition for zero-rating an intra-Community supply since 01/01/2020, Directive (EU) 2018/1910.

Every EU business customer's VAT number checked before the invoice leaves, and again every quarter, with the EU's own reference code filed next to the sale.

The architecture

A new EU businesscustomerAn invoice about to gooutThe quarterly sweepone call to the EU's own free serviceThe check ledger - one row per check,never overwrittendate, valid or not, the name it came back with, and the EU'sreference coderead before the invoice, and before the quarterlyreturnStop, before a zero-rated invoicegoes out on a dead numberA quarterly sweep of every activecustomerOne page your accountant can attachto the fileNothing is sent to the customer by a machine. The ledger checks andrecords; you decide what to do about it.
the same flow as text
[ New customer ]  or  [ Invoice about to go out ]  or  [ Quarterly sweep ]
        ▼
[ n8n (self-hosted) — one HTTP call ]
        │  GET ec.europa.eu/taxation_customs/vies/rest-api/ms/<MS>/vat/<number>
        │  ?requesterMemberStateCode=<yours>&requesterNumber=<yours>
        ▼
[ The check ledger (Grist) — one row per check, never overwritten ]
        ├─ valid / invalid, date, name and address as returned
        ├─ requestIdentifier — the EU's own consultation number
        └─ the raw JSON, stored as-is

valid → the customer stays zero-rateable
invalid → flag on the customer, mail to you, nothing sent to the customer by machine
service down → retry, never recorded as "invalid"

Three triggers, one call, one append-only ledger. The design decision is the ledger: you are not storing "this customer is valid", you are storing "on this date the EU answered this". A status field can be overwritten. A dated row with a consultation number is evidence.

The problem

You sell to a company in another EU country. They give you their VAT number, you leave the VAT off the invoice, everyone is happy. Three years later an inspector opens that file and asks one question: was that number valid on the day you invoiced, and can you show it. Since 1 January 2020 this stopped being paperwork. Directive (EU) 2018/1910 — the third of the "quick fixes" — made a valid VAT identification number, communicated by the customer, a substantive condition for zero-rating an intra-Community supply, not a formality you can repair afterwards. If the number was cancelled, or was never valid, the exemption is exposed and the VAT is yours to pay, on a sale whose margin is long gone. Most small businesses check the number once, at onboarding, on the EU website, and never again. Companies deregister, go bankrupt, restructure, change legal form. The number rots quietly and nothing tells you.

Tool choices — and why

VIES, direct
The European Commission runs the VAT Information Exchange System and now exposes it as plain REST: GET /taxation_customs/vies/rest-api/ms/BE/vat/0417497106 returns JSON, no API key, no registration, no cost. Checked live on 19/09/2026: it answers isValid, requestDate, name, address. Add requesterMemberStateCode and requesterNumber — your own VAT number — and the response fills requestIdentifier with a consultation number (format WAPIAAAA…). Without those two parameters that field comes back empty. That string is the point of the whole exercise: it is the Commission's own proof that you asked, on that date. Every paid VAT-validation API in this space is a wrapper around the same free endpoint.
n8n
(Sustainable Use License, free for internal business use, 204k stars, v2.39.5 released 14/09/2026) makes the call, on a webhook from your invoicing tool and on a cron for the quarterly sweep. An HTTP node, an IF node, an append node. If you already run n8n for another blueprint in this library, this is one more workflow on the same box, not another box. AI audit →
Alternative: a cron job and 30 lines of script — if you are comfortable in a terminal the whole thing is a scheduled script; n8n earns its place only if you already run it, or want the retries and the error mail without writing them
Grist
(Apache-2.0, grist-core, active — v1.7.19) is the ledger. A spreadsheet your accountant can read and filter, with a real API underneath and Python formulas for the "last checked more than 90 days ago" column. NocoDB (2026.09.0) does the same job if you prefer its interface; move the date logic into n8n in that case. Either runs in Docker next to n8n.
Alternative: NocoDB — same job, easier first install, no Python formulas - move the 'checked more than 90 days ago' logic into n8n if you pick it
Monthly cost
Software EUR 0. VIES EUR 0. A small VPS at roughly EUR 5–12/month if you don't already have one, and EUR 0 if you do. Compare with the outcome you are insuring against: one disallowed zero-rating is the VAT on that invoice plus interest, at 21% in Belgium, 19% in Germany, 20% in France.

Setup outline

  1. Pull your customer list. Keep only the ones you invoice without VAT because they are a business in another EU member state. For most small businesses that is 5 to 50 rows, not thousands.
  2. Build the ledger table: customer, country code, VAT number, checked_at, is_valid, returned_name, returned_address, consultation_number, raw_response, trigger (onboarding / pre-invoice / quarterly). Append-only — no row is ever updated.
  3. In n8n, one HTTP Request node to the REST endpoint, with your own VAT number in the two requester parameters. Test it against a number you know is good and one you know is bad before anything else is wired.
  4. Branch on three outcomes, not two: valid, invalid, and unreachable. Unreachable retries after an hour and alerts you if it is still unreachable after three tries.
  5. Trigger 1 — onboarding: a form or a webhook when you add an EU business customer. No valid check, no zero-rated invoice.
  6. Trigger 2 — pre-invoice: if your invoicing tool has a webhook, check the number when the invoice is created. Cheap, and it catches the deregistration that happened last month.
  7. Trigger 3 — quarterly sweep, spread over the night: re-check every active EU business customer before you file the EC Sales List for that quarter.
  8. One page for your accountant: customer, last check date, result, consultation number. That page is what gets attached to the file when someone asks.

Pitfalls — what goes wrong when you build this

"Service unavailable" is not "invalid"
VIES is not one database, it is a router to 27 national systems, each with its own maintenance windows and outages, and it returns MS_UNAVAILABLE when a member state does not answer. Code that treats a timeout as a failed check will, on a bad Tuesday, flag half your customers as dead. Retry with a delay and record the attempt as inconclusive.
Some countries return no name
Several member states answer valid/invalid only, with --- where the name and address should be. Never build a rule that requires the returned name to match your customer record — you will block real customers in those countries. Use the name when it comes, log it when it doesn't.
The consultation number only appears if you ask for it
Without requesterMemberStateCode and requesterNumber, requestIdentifier is an empty string and you have a check you cannot prove you made. This is the single most common way this gets built wrong.
A valid number is not the whole exemption
The quick fixes also require the supply to be correctly reported in your EC Sales List, and transport of the goods to be evidenced. This blueprint closes one condition, the one nobody automates. Your accountant owns the rest — show them the ledger and ask what else their file needs.
Don't hammer it
A nightly sweep of 40 customers is nothing. A loop that re-checks your whole list on every page load is abuse of a free public service, and it will be throttled.
Screenshots rot
A folder of PNGs from the VIES website is what most businesses have, and it survives exactly as long as the person who named the files. Store the JSON response and the consultation number as text, in a table, with the date.
If you are in the US:
the mechanism is different but the failure is the same shape — a resale or exemption certificate on file that has expired or was never valid, discovered years later in an audit. Same ledger, same re-check rhythm, different source of truth. Check with your accountant which states require re-validation and on what cycle.

Verified repos

n8n — Sustainable Use License (free self-hosted internal use), 204k stars, v2.39.5 released 14/09/2026
Grist — Apache-2.0, active, v1.7.19
NocoDB — Sustainable Use License, release 2026.09.0 (alternative to Grist)
VIES — European Commission, free REST API, no key, verified live 19/09/2026

Get the next blueprint as it publishes — free, practical, verified tooling only.

Subscribe · Want it audited or extended? DM @RXed_EU