EU national VAT databases explained: fallback paths when VIES is down
How the 27 member-state VAT registries sit behind VIES, which national databases expose direct public endpoints, and where the tradeoffs around using them directly actually land.
Key facts
- VIES is an aggregator in front of 27 national VAT registries plus Northern Ireland. When the gateway is down or a specific country returns
MS_UNAVAILABLE, the only way to hit fresh data is the national registry itself. - Only a handful of member states publish direct public APIs (notably Italy's Agenzia delle Entrate, Germany's BZSt confirmation endpoint, and the Czech ARES register). Most states expose only a web form and treat VIES as the sole programmatic surface.
- National registries frequently carry richer metadata than VIES returns (structured addresses, legal form, registration date, status transitions). Querying a national endpoint sometimes means upgrading the response, not downgrading it.
- The Monday-morning maintenance window (roughly 03:00 to 05:00 UTC) trips all VIES traffic at once; a warm cache plus a sensible degraded-mode posture is what smooths that hour for callers that cannot wait.
- vatverify's current approach leans on the 30-day VIES cache and a seven-day fallback window for degraded responses. We do not run parallel national-registry integrations for the EU-27 today.
What the registry is
"EU national VAT databases" is a loose category because the 27 member states do not share a single architecture. Each country's tax authority runs its own register: Agenzia delle Entrate (Italy), Agencia Tributaria (Spain), Direction Générale des Finances Publiques (France), the Bundeszentralamt für Steuern or BZSt (Germany), ARES (Czech Republic, a cross-register index run by the Ministry of Finance), and so on. VIES exists precisely because this heterogeneity would otherwise force every cross-border invoicer to integrate twenty-seven separate APIs.
The legal framing: Council Regulation (EU) No 904/2010 on administrative cooperation for VAT obliges member states to expose their registration data through VIES. It does not oblige them to expose a public national API, which is why direct fallbacks only exist for countries that chose to publish one.
A short tour of what is actually available:
- Italy (Agenzia delle Entrate). A public web service for partita IVA validation, older but functional, returns the business name and registration status.
- Germany (BZSt confirmation endpoint).
Bestätigungsverfahrenfor German businesses confirming EU counterparties; effectively a VIES proxy, so not a true independent fallback, but useful for therequestIdentifieraudit record. - Czech Republic (ARES). A rich cross-register index covering company, VAT, trades, and insolvency status. Not strictly a VAT registry but the VAT flag is present and the public JSON endpoint is generous.
- Netherlands (KVK, Kamer van Koophandel). Company register with the VAT flag, behind a paid API key with tiered access. Not a pure fallback, but useful for enriched company data.
- Poland (Biała Lista, the White List). Maintained by the Ministry of Finance, publicly accessible, returns VAT status plus sanctioned bank accounts. Required for Polish-domestic split-payment scenarios.
- France, Spain, Belgium, and most others: VIES is the only public API. The national register has a web form for humans, no programmatic access.
Northern Ireland sits inside VIES (prefix XI) under the Windsor Framework; it has no independent EU-level fallback because HMRC owns the underlying data and exposes it through its own UK-only API.
What the API returns
Because each national endpoint is different, the returned shape is endpoint-specific. A sketch of three common ones gives the flavour:
Italy (Agenzia delle Entrate, SOAP):
<checkVatNumber>
<partitaIva>12345678901</partitaIva>
<statoUtente>P</statoUtente>
<denominazione>Esempio S.R.L.</denominazione>
<dataInizioAttivita>2017-03-01</dataInizioAttivita>
</checkVatNumber>Czech ARES (REST JSON):
{
"ico": "12345678",
"dic": "CZ12345678",
"obchodniJmeno": "Priklad s.r.o.",
"sidlo": {
"ulice": "Vaclavske namesti",
"cisloDomovni": "1",
"obec": "Praha",
"psc": "11000"
},
"pravniForma": "112",
"datumVzniku": "2015-01-15",
"seznamRegistraci": { "stavZdrojeVr": "AKTIVNI" }
}Poland Biała Lista (REST JSON):
{
"result": {
"subject": {
"name": "Przyklad sp. z o.o.",
"nip": "1234567890",
"statusVat": "Czynny",
"registrationLegalDate": "2014-05-12",
"workingAddress": "ul. Przykladowa 1, 00-001 Warszawa"
},
"requestId": "aa-bbbbbb-cccccc"
}
}The common thread is that national responses tend to include more than VIES does: the registration date, the legal form, structured address components, sometimes a status code that distinguishes active from suspended from deregistered.
The tradeoffs: national endpoints are less uniform, less predictable, and in some cases require credentials or paid access. Building a fallback strategy means picking which countries justify the integration work, and which are fine to leave on VIES-only with a graceful-degradation posture.
Rate limits and quirks
There is no single answer because every national registry sets its own limits.
- Italy's Agenzia delle Entrate is loosely rate-limited and can return intermittent 500s under load. Back off aggressively.
- Czech ARES publishes a fair-use limit (historically around one request per second per IP for the free tier) and is strict about it.
- Polish Biała Lista allows a published burst but blacklists IPs that scrape in tight loops.
- German BZSt Bestätigungsverfahren acts as a VIES passthrough; it shares all of VIES's rate-limit characteristics and adds a requirement that the caller is itself a German VAT-registered entity.
- Dutch KVK is credential-gated and metered by subscription tier.
Common failure modes across the board: cold-cache latencies of 1 to 3 seconds, HTML error pages returned inside a 200 response when the upstream application tier is confused, and character-encoding drift (Latin-1 leaking into what should be UTF-8 responses).
How vatverify handles it
For the 27 EU member states plus XI, vatverify treats VIES as the single source of truth and leans on its cache to absorb VIES's bad hours. The order, in plain terms:
- Normalise and format-check. Uppercase the prefix, strip spaces and punctuation. Reject obviously malformed input as
invalid_formatbefore any network call. Greek numbers are expected to arrive with the VIES-nativeELprefix. - Cache lookup. Upstash Redis, keyed per registry and number. Freshness is 30 days on valid results and 24 hours on invalids, with a seven-day fallback window past freshness used to serve degraded responses when VIES is unreachable. Fresh cache hits return in under 20 ms.
- Primary upstream: VIES. 10-second timeout. On a clean response, cache and return.
- Soft-fail path. If VIES returns
MS_UNAVAILABLE,SERVICE_UNAVAILABLE, or times out, check whether any cached value exists for this number (including entries past the freshness window but still inside the fallback window). If one does, serve it withmeta.source_status: "degraded". If nothing is cached, returnregistry_unavailablewith a 502 status.
Country-specific checksum helpers ship separately in @vatverify/vat-rates for clients that want to reject typos offline before calling the API.
We deliberately do not maintain parallel integrations into 27 national registries. Most of them sit behind credentials, paid tiers, or fragile SOAP endpoints, and running two codepaths per country would add more downtime surface than it removes. The VIES cache plus the fallback window does the heavy lifting; genuinely-cold numbers during a VIES outage surface a structured registry_unavailable and a retry hint rather than a second-best data source.
The caching posture is deliberately generous: a VAT registration does not flip day to day, 30 days of validity is well within the tolerance band for almost every commercial use case, and the cache is the single biggest lever against every form of upstream instability, whether that is a VIES outage or a national backend crashing during tax season.
For audit-grade verification, pass requester_vat_number on the /v1/validate request. The call routes through VIES's authenticated consultation path and stores the returned requestIdentifier as verify_id in the response. That is the consultation number to keep on file.
Gotchas worth knowing
- VIES and national registries disagree more often than you would expect. A number can show
valid: trueon VIES andvalid: falseon the national endpoint (or vice versa) during the 24-hour propagation window after a status change. Treat VIES as source of truth for EU cross-border invoicing (that is what Council Regulation 904/2010 says); use national data for enrichment. - Fallback is not a free performance upgrade. Direct national APIs are usually slower and less reliable than VIES on a good day. The fallback exists for VIES's bad days, not its baseline.
- Do not double-bill yourself. If you run VIES and a national registry in parallel for redundancy, both count against your infrastructure budget even when the second call is discarded. Sequential fallback keeps costs sane.
- The
requestIdentifieronly comes from VIES. A national-database fallback cannot produce a VIES consultation number. For audit-critical flows, wait for VIES to come back rather than accept a fallback result that is not audit-grade.
See the API reference
- API reference:
GET /v1/validate - Glossary: VIES, consultation number, checksum, VAT number
- Error surface:
registry_unavailable,country_unsupported,invalid_format - Related guides: Handle VIES downtime, VIES explained, HMRC VAT API, Swiss BFS explained, Norwegian brreg explained