EU VAT number validation: the complete guide
A practical, source-linked guide to validating EU VAT numbers for invoicing, onboarding and checkout. Written by W System, maker of the api.wsystem.dev VAT validation API (disclosure: we sell the API described in section 7). Last checked 2026-10-17.
1. What an EU VAT number is
Every VAT-registered business in the EU has a VAT identification number: a two-letter country prefix followed by 2–13 characters. Greece uses EL (not GR). Northern Ireland traders use XI for goods since 2021. Great Britain (GB) numbers left the EU system on 1 January 2021 and are checked with HMRC.
| Country | Prefix | Format (after prefix) | Example |
|---|---|---|---|
| Austria | AT | U + 8 digits | ATU12345678 |
| Belgium | BE | 10 digits (0 or 1 first) | BE0123456789 |
| Bulgaria | BG | 9–10 digits | BG123456789 |
| Croatia | HR | 11 digits | HR12345678901 |
| Cyprus | CY | 8 digits + letter | CY12345678L |
| Czechia | CZ | 8–10 digits | CZ12345678 |
| Denmark | DK | 8 digits | DK12345678 |
| Estonia | EE | 9 digits | EE123456789 |
| Finland | FI | 8 digits | FI12345678 |
| France | FR | 2 check chars + 9-digit SIREN | FR40303265045 |
| Germany | DE | 9 digits | DE811193231 |
| Greece | EL | 9 digits | EL123456789 |
| Hungary | HU | 8 digits (first 8 of the adószám) | HU33119856 |
| Ireland | IE | 7 digits + 1–2 letters | IE6388047V |
| Italy | IT | 11 digits | IT12345678901 |
| Latvia | LV | 11 digits | LV12345678901 |
| Lithuania | LT | 9 or 12 digits | LT123456789 |
| Luxembourg | LU | 8 digits | LU12345678 |
| Malta | MT | 8 digits | MT12345678 |
| Netherlands | NL | 9 digits + B + 2 digits | NL123456789B01 |
| Poland | PL | 10 digits | PL1234567890 |
| Portugal | PT | 9 digits | PT123456789 |
| Romania | RO | 2–10 digits | RO1234567 |
| Slovakia | SK | 10 digits | SK1234567890 |
| Slovenia | SI | 8 digits | SI12345678 |
| Spain | ES | 9 characters (letter/digit first and last) | ESX1234567X |
| Sweden | SE | 12 digits (ends in 01) | SE123456789701 |
| Northern Ireland | XI | 9 or 12 digits, or GD/HA + 3 | XI123456789 |
A correct format does not mean the number is registered. Only VIES confirms that.
2. VIES: the official source
VIES (VAT Information Exchange System) is run by the European Commission. It does not hold its own database: each request is forwarded live to the national tax administration of the number's country, which answers valid/invalid and, depending on national rules, the registered name and address. Access options:
- Web form: ec.europa.eu/taxation_customs/vies
- SOAP service
checkVatServiceandcheckVatApproxService(the latter returns a consultation number) - REST endpoint
check-vat-numberused by the web form
All are free and need no key. Limitations: one number per call, national backends go offline (often evenings and weekends), concurrency limits (MS_MAX_CONCURRENT_REQ), and the EC states that VIES is for confirming validity, not for building databases.
3. When you must (or should) validate
- Intra-EU B2B supplies of goods: since the 2020 "quick fixes" (Directive 2018/1910), a valid VAT number of the customer, recorded in VIES, is a substantive condition for the 0% exemption.
- Reverse-charge B2B services: the customer's VAT number is how you show it is a taxable person; validate and keep evidence.
- Checkout VAT exemption in SaaS / e-commerce: validate before removing VAT, otherwise OSS rules for B2C apply.
- Supplier onboarding / KYB: invalid VAT IDs are a fraud signal (missing-trader fraud).
This is general information, not tax advice.
4. Keeping proof: the consultation number
If you include your own EU VAT number as the requester, VIES returns a consultation number (e.g. WAPIAAAAaFIeQCDg), a reference that the check happened on that date. Many tax authorities accept it as evidence of due diligence. Store it with the invoice. Germany's BZSt runs its own "qualifizierte Bestätigungsabfrage" for German businesses.
5. Results and error codes
| VIES answer | Meaning | What to do |
|---|---|---|
| valid = true | Registered for intra-EU transactions | Store date + consultation number |
| valid = false | Not registered (or not enabled for intra-EU trade) | Ask the customer; charge VAT |
| INVALID_INPUT | Malformed number | Fix prefix/format |
| MS_UNAVAILABLE / TIMEOUT / SERVICE_UNAVAILABLE | National backend or VIES down | Unknown, not invalid: retry later (guide) |
| MS_MAX_CONCURRENT_REQ / GLOBAL_MAX_CONCURRENT_REQ | Rate limited | Back off and retry |
6. Code: calling VIES directly
curl -s -X POST https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number \
-H 'Content-Type: application/json' -d '{"countryCode":"IE","vatNumber":"6388047V"}'
You then handle retries, caching, batch loops and the error codes above yourself.
7. Code: using a wrapper API (ours)
curl "https://api.wsystem.dev/verify?vat=IE6388047V"
curl -X POST https://api.wsystem.dev/verify/batch -H 'Content-Type: application/json' -d '{"vats":["IE6388047V","DE811193231"]}'
Free for 20 calls/day per IP without a key; $0.01 per call via x402 after that; also as an MCP tool for AI agents. Details: EU VAT validation API.
8. Checklist
- Normalise input (strip spaces/dots, uppercase, EL for Greece).
- Check the format locally.
- Validate in VIES with your requester VAT.
- Treat unavailable as unknown and retry.
- Store date, result and consultation number with the transaction.
- Re-validate recurring customers periodically (e.g. quarterly).
Facts and competitor details checked 2026-10-17. W System Hungary Kft. is the maker of this product. Not affiliated with the European Commission. Not legal or tax advice.