Vatnode is a single-endpoint REST API that validates EU VAT numbers and returns the official VIES consultation number — the timestamped proof EU tax authorities accept at audit.
Base URL: https://vatnode.com
All requests and responses use JSON. All endpoints require HTTPS.
✅ The API is live. Grab a free key and make your first call in under a minute.
Vatnode uses an API key passed in the x-api-key header. Include your key in every request:
Get your API key by joining the waitlist. Keys are issued per account and tied to your plan quota. Keep your key secret — never expose it in client-side code or public repos.
Validate a VAT number in one call. Most integrations are live in under an hour.
Validates an EU VAT number and returns the official VIES consultation number — the timestamped proof that you checked a customer's VAT ID against the EU's system.
Coverage: the EU-27 via VIES, plus non-VIES countries via their national registries — Norway (Brønnøysund) and Switzerland (the federal UID/MWST register) are both live. National-registry results return company name and address; consultationNumber is VIES-only.
YOUR_OWN_VAT_NUMBER with your company's real VAT number. VIES only issues a consultation number to a requester it can identify — a placeholder or another company's number gets the request rejected, which is the single most common reason a first integration returns no consultation number.| Parameter | Type | Required | Description |
|---|---|---|---|
| vat_number | string | required | The VAT number to validate. Include the 2-letter country prefix (e.g. IE6388047V, DE811907980). Spaces, dots and hyphens are stripped and the prefix is upper-cased automatically. Greece must be sent as EL, not GR. |
| requester_vat | string | optional | Your own VAT number — it must be a real, currently valid EU VAT number that belongs to you. Required by VIES to issue a consultation number. Send a made-up or expired number and VIES rejects the request (invalid_requester): you get no consultation number, and no company data. Omit it entirely and you still get a valid/invalid answer — just no audit evidence. |
name and address are returned as published by each member state, and are null when a state doesn't publish them. Germany and Spain release validity only — that is VIES policy for those states, not a gap in the API. Full breakdown in Country coverage.
VIES has frequent per-country outages. When the relevant member-state database is down, the API returns {"error":"vies_unavailable","retryable":true} rather than a misleading valid:false — so you can implement a short retry with exponential backoff instead of wrongly rejecting a real customer. Live per-country status is on the VIES status page.
Is there a fallback when a country's VIES is down? Yes — two layers, both clearly labelled, neither of them ever disguised as a fresh VIES check.
source: "national_vat_register_pl" and similar. It carries consultationNumber: null, because a national register doesn't issue one.source: "cache", cached: true, with the original cachedAt timestamp. Your checkout keeps working; you retry for a fresh consultation number once VIES recovers.If neither applies, you get vies_unavailable with retryable: true — never a guessed valid: false. We never serve cached or third-party data as a fresh check, and we never enrich from a data broker and call it VIES. For countries VIES doesn't cover at all, the national register is the primary source — Norway is live today. Which countries are up right now: live status page. Full per-country detail: country coverage.
Every validation for the 27 EU member states + Northern Ireland (XI) confirms validity and, when you pass requester_vat, returns the official consultation number — always. Two things vary by country: whether the company name & address is released, and what happens if that country's VIES node goes down. The national-register fallback (green) is live where a country publishes a free official register.
| Code | Country | Name & address | If VIES is down |
|---|---|---|---|
| AT | Austria | ✓ | 24h cache1 |
| BE | Belgium | ✓ | 24h cache1 |
| BG | Bulgaria | ✓ | 24h cache1 |
| HR | Croatia | ✓ | 24h cache1 |
| CY | Cyprus | ✓ | 24h cache1 |
| CZ | Czechia | ✓ | Live register · ARES2 |
| DK | Denmark | ✓ | Live register · CVR2 |
| EE | Estonia | ✓ | 24h cache1 |
| FI | Finland | ✓ | Live register · PRH2 |
| FR | France | ✓ | Live register · SIRENE2 |
| DE | Germany | — validity only3 | 24h cache1 |
| EL | Greece (EL5) | ✓ | 24h cache1 |
| HU | Hungary | ✓ | 24h cache1 |
| IE | Ireland | ✓ | 24h cache1 |
| IT | Italy | ✓ | 24h cache1 |
| LV | Latvia | ✓ | 24h cache1 |
| LT | Lithuania | ✓ | 24h cache1 |
| LU | Luxembourg | ✓ | 24h cache1 |
| MT | Malta | ✓ | 24h cache1 |
| NL | Netherlands | ✓ | 24h cache1 |
| PL | Poland | ✓ | Live register · White List2 |
| PT | Portugal | ✓ | 24h cache1 |
| RO | Romania | ✓ | 24h cache1 |
| SK | Slovakia | ✓ | 24h cache1 |
| SI | Slovenia | ✓ | 24h cache1 |
| ES | Spain | — validity only3 | 24h cache1 |
| SE | Sweden | ✓ | 24h cache1 |
| XI | Northern Ireland | ✓ | 24h cache1 |
| NO | Norway · non-VIES | ✓ | National register is the source4 |
| CH | Switzerland · non-VIES | — validity only6 | National register is the source6 |
Notes — how to read this table
Every EU-27 + XI row returns validity + the official VIES consultation number whenever you pass your own requester_vat — that's the audit evidence auditors ask for, and it's constant across every country here. Only the two columns above differ.
1 Standard fallback (24h cache). If a country's VIES node is down, we return your key's own last confirmed check from the past 24 hours, flagged source: "cache" — so your checkout keeps working and you keep the real consultation number. Retry for a fresh one when VIES recovers.
2 Live national-register fallback (FR, PL, FI, CZ, DK). These states publish a free official register, so during a VIES outage we confirm the number against it live. Two of them expose actual VAT status — Poland (VAT White List) and Czechia (ARES, stavZdrojeDph) — and are flagged source: "national_vat_register_pl" / _cz. The other three (France SIRENE, Finland PRH, Denmark CVR) confirm that the company is registered and active, which is strong evidence but not a VAT-status check; those are flagged source: "national_company_register_fr" and similar so you can tell the difference in your own logs. All five carry consultationNumber: null, because a national register doesn't issue one. Romania (ANAF) is the next one we want to add.
3 Germany (DE) & Spain (ES) release validity only. name and address come back empty for these two — it's their national policy, not a gap in the API. Every other state returns the registered company name and address.
4 Norway (NO) is not part of VIES. We validate it directly against the Brønnøysund national register (name + address; no consultation number, as that's a VIES-only concept).
5 Greece uses the EL prefix in VIES, even though its ISO country code is GR. 6 Switzerland (CH) is not in VIES either. We validate CHE… numbers against the Swiss federal UID/MWST register, which publishes VAT status only — no company name or address, and no consultation number. Send the number in any common form (CHE-116.281.710 MWST or CHE116281710); results carry source: "national_vat_register_ch". Send EL123456789 — that is the form VIES recognises. Casing and spaces don't matter (el 094 014 249 works); the prefix does.
Disclosure policy can change; we verify continuously and this table reflects live behaviour. Try any country yourself with the free checker.
Same endpoint, same fields — only what each source releases differs. Check for error first, then read valid.
1. Most EU-27 — validity + consultation number + name + address:
2. Germany & Spain — validity + consultation number; name/address empty (state releases validity only):
3. Non-VIES country (Norway) — validity + name + address from the national register; no consultation number (VIES-only concept), but the check is recorded in your audit log:
4. During a VIES outage (cache fallback) — if your key checked this exact VAT in the last 24h, we serve that last confirmed result flagged as cached, so your flow doesn't break. Retry for a fresh consultation number when VIES recovers:
Cache only ever serves your own key's prior confirmed check for the same VAT, within 24h — never third-party data, and always flagged. If there's no recent cached check, you get vies_unavailable to retry.
Returns the validation history for your API key — every check is logged server-side, so this is your audit trail. Pass your key in the x-api-key header, same as /v1/validate.
| Parameter | Type | Description |
|---|---|---|
| limit | integer | Number of records to return, newest first. Default: 100. Max: 1000. |
CSV export and date-range filtering are on the roadmap — email us if you need them now.
All responses return HTTP 200 with a JSON body. Check the valid field and the presence of error to determine success or failure.
| Field | Type | Description |
|---|---|---|
| valid | boolean | Whether the VAT number is active and registered. |
| vatNumber | string | The VAT number that was validated. |
| countryCode | string | ISO 3166-1 alpha-2 country code derived from the VAT number prefix. |
| consultationNumber | string | null | The official VIES consultation number (e.g. WAPIAAAAW1234567). null when the VAT is invalid, when you didn't pass a valid requester_vat, or when the answer came from a national register rather than VIES. |
| name | string | null | Registered company name as published by the member state. null when the state doesn't release it (DE, ES) or the number is invalid. |
| address | string | null | Registered company address as published by the member state. null when unavailable. May contain newlines. |
| source | string | Only present when the answer did not come from a live VIES call: cache, national_vat_register_pl, national_company_register_fr, national_registry_no, etc. Absent means a fresh VIES result. |
| cached | boolean | Present and true only when serving your key's own prior confirmed check during a VIES outage. |
| cachedAt | string | ISO 8601 timestamp of when the cached check actually ran against VIES. |
| requestDate | string | Date of the VIES query (YYYY-MM-DD+offset). |
| timestamp | string | ISO 8601 timestamp of when the validation was performed. |
| error | string | Present only on failure — see error codes. When present, ignore valid. |
All responses return HTTP 200. When an error occurs, the response body contains an error field. Check for this before reading validation results.
| Error code | Description |
|---|---|
invalid_api_key | Missing or invalid API key. Pass your key in the x-api-key header. |
vies_unavailable | The member state's VIES node is temporarily down and no fallback applied. See VIES error codes explained for the full mapping. retryable: true is included — implement exponential backoff. Check the status page for which countries are affected. |
rate_limit_exceeded | Your key's monthly quota is used up. The body includes limit, used and your plan. Quotas reset on the 1st. |
invalid_requester | VIES rejected the requester_vat you sent — it must be a real, currently valid EU VAT number belonging to you. No consultation number is issued for a rejected requester, so we surface this instead of silently returning a weaker result. retryable: false. |
Each API key has a monthly validation quota, enforced per key: Free 100 · Starter 2,000 · Growth 10,000 · Scale 50,000 (see the pricing page).
When a key exceeds its monthly quota, the API returns an error body instead of a validation result:
Check for the error field before reading validation results. Need a higher quota for evaluation? Email us and we'll raise your key's limit.
Lightweight, dependency-free clients for Node.js, Python, and PHP are available now. Each wraps /v1/validate and /v1/log so you don't hand-roll HTTP.
Dependency-free clients for Node.js, Python and PHP are on GitHub: github.com/acirema792/vatnode-sdks. Need Ruby, Go, or a WooCommerce / Shopify plugin? Tell us →
Validate VAT numbers — with consultation numbers — directly inside Claude Desktop, Cursor, or any MCP-compatible AI client. Published on npm as vies-mcp.
Tools: validate_vat (validity + company data + consultation number) and vies_status (live per-country VIES availability). Source: github.com/acirema792/vies-mcp.
CHE… VAT numbers are now validated against the Swiss federal UID/MWST register (source: "national_vat_register_ch"). Switzerland is outside VIES, so the register publishes VAT status only — no name, address or consultation number — and both CHE-116.281.710 MWST and CHE116281710 are accepted. Non-VIES coverage is now Norway and Switzerland. The free status page also gained an inline checker.
When a member state's VIES node was offline, the API could return valid: false instead of flagging the outage — VIES reports every failure mode, including downtime, as "not valid". The API now reads the underlying VIES status code: downtime, timeouts and rate-blocks route into the documented fallback chain (live national register where one exists, then your key's own 24-hour cache, then a retryable vies_unavailable), and only a genuine "not registered" answer returns valid: false. A rejected requester_vat now returns the new invalid_requester error rather than degrading quietly. Greek numbers are accepted with either the GR or EL prefix and normalised to EL, the form VIES recognises. The same corrections apply to the free VAT checker, which additionally now supports Norwegian organisation numbers.
Every code sample now uses a YOUR_OWN_VAT_NUMBER placeholder instead of a made-up requester VAT — sending an invalid requester is the most common reason a first integration gets no consultation number, and the old examples walked people straight into it. Response schema corrected: name, address and consultationNumber are null (not empty strings) when unavailable, and the source, cached, cachedAt and error fields are now documented. Added rate_limit_exceeded to the error table, documented the EL/GR prefix rule for Greece, and rewrote the outage section so it matches the two-layer fallback shown in country coverage — live national register for FR/PL/FI/CZ/DK, 24-hour cache elsewhere, with the VAT-status registers (PL, CZ) distinguished from the company registers (FR, FI, DK).
vies-mcp published on npm — VAT validation inside any MCP-compatible AI client. New country coverage reference documenting exactly what each member state returns. Docs examples switched to an Irish VAT number so the sample response matches real VIES behavior (DE/ES release validity only).
Initial API release for design partners. Endpoint: POST /v1/validate. VIES consultation number capture + company enrichment for all 27 EU member states. API key auth via x-api-key header.