DEV Community

Alexander Nitrovich
Alexander Nitrovich

Posted on • Originally published at blog.eurovalidate.com

VIES API Alternative — Why Developers Are Switching

VIES API Alternative

If you are looking for a VIES API alternative, the short answer is: you need a reliability layer on top of VIES, not a replacement for it. VIES is the only authoritative source for EU VAT validation -- every alternative still queries VIES under the hood. The difference is how they handle VIES failures, caching, response format, and the data gaps that VIES does not fill. This article breaks down when VIES alone is not enough, compares the main alternatives, and shows you working code.

Why VIES alone is not enough

The VIES service (VAT Information Exchange System) is operated by the European Commission and connects to 27 national tax authority databases. It is free and authoritative. It is also unreliable.

Uptime problems

VIES does not publish an official SLA. In practice, developers report roughly 70% effective availability when you account for individual country backends going down independently. Germany alone generates the majority of VIES errors. The service uses a GLOBAL rate limit (MS_MAX_CONCURRENT_REQ) that is shared across all callers -- when the limit is hit, the entire country backend rejects requests regardless of who sent them.

SOAP/XML in 2026

VIES exposes a SOAP/WSDL interface. To validate a single VAT number, you need to construct an XML envelope, parse an XML response, and handle SOAP faults. Most modern applications use REST/JSON. Wrapping VIES in your own REST proxy is straightforward but means you own the retry logic, caching, error handling, and monitoring.

Missing data for Germany and Spain

German (DE) and Spanish (ES) tax authorities do not return trader name or address through VIES. This is a permanent data protection policy, not a temporary bug. If your checkout or KYB flow requires the company name, VIES will give you null for every German and Spanish business.

Greece country code mismatch

VIES uses EL for Greece, while ISO 3166 uses GR. If you do not handle the bidirectional mapping, your integration will fail silently for Greek VAT numbers.

No caching, no degradation

VIES has no built-in caching. Every request hits the live backend. If the backend is down, you get a SOAP fault. There is no fallback, no stale-data option, no confidence indicator. Your application either gets an answer or it fails.

Alternatives compared

Here is an honest comparison of the main options available.

EuroValidate

What it is: A unified REST API that wraps VIES, EORI, IBAN, GLEIF, and HMRC behind a single JSON endpoint with caching and circuit breakers.

How it addresses VIES limitations:

  • Per-country circuit breakers: 27 independent breakers. Germany going down does not affect France. When a country backend is unavailable, the API returns the last cached result with confidence: "low" and upstream_status indicating the issue.
  • Dual-layer cache: Redis (hot, 1--5 ms reads) and PostgreSQL (persistent, survives restarts). VAT results cached 24 hours. Cached responses include meta.cached: true and meta.confidence: "medium".
  • REST/JSON: No SOAP, no XML parsing. Standard HTTP with X-API-Key authentication.
  • Germany/Spain workaround: Cross-references GLEIF data to fill in company names when VIES returns null. Coverage depends on LEI registration.
  • Greece handling: Accepts both GR and EL prefixes, maps automatically.
  • Confidence scoring: Every response includes confidence: "high" | "medium" | "low" | "unknown" so your application can decide how to treat stale data.
  • Beyond VAT: Also validates IBANs (offline, 65 ms), EORI numbers, and does company lookups via GLEIF -- all through the same API.

Pricing: Free tier (100 req/hr), paid plans from EUR 19/mo (5,000 requests) to EUR 149/mo (100,000 requests).

Quick example:

curl -H "X-API-Key: ev_live_your_key_here" \
  https://api.eurovalidate.com/v1/vat/NL820646660B01
Enter fullscreen mode Exit fullscreen mode
{
  "vat_number": "NL820646660B01",
  "country_code": "NL",
  "status": "valid",
  "company_name": "COOLBLUE B.V.",
  "company_address": "Weena 664 3012CN ROTTERDAM",
  "request_id": "req_abc123",
  "meta": {
    "confidence": "high",
    "source": "vies_live",
    "cached": false,
    "response_time_ms": 247,
    "last_verified": "2026-04-05T10:15:30Z",
    "upstream_status": "ok"
  }
}
Enter fullscreen mode Exit fullscreen mode

With the Python SDK:

from eurovalidate import EuroValidate

client = EuroValidate("ev_live_your_key_here")
result = client.validate_vat("NL820646660B01")
print(result.valid, result.company_name)
# True "COOLBLUE B.V."
Enter fullscreen mode Exit fullscreen mode

With the Node.js SDK:

import { EuroValidate } from "@eurovalidate/sdk";

const client = new EuroValidate("ev_live_your_key_here");
const result = await client.validateVat("NL820646660B01");
console.log(result.valid, result.companyName);
// true "COOLBLUE B.V."
Enter fullscreen mode Exit fullscreen mode

What it returns when VIES is down:

{
  "vat_number": "NL820646660B01",
  "country_code": "NL",
  "status": "valid",
  "company_name": "COOLBLUE B.V.",
  "company_address": "Weena 664 3012CN ROTTERDAM",
  "request_id": "req_ghi789",
  "meta": {
    "confidence": "low",
    "source": "vies_cached",
    "cached": true,
    "response_time_ms": 3,
    "last_verified": "2026-04-04T22:00:00Z",
    "upstream_status": "unavailable"
  }
}
Enter fullscreen mode Exit fullscreen mode

Notice confidence: "low" and source: "vies_cached". Your application can decide: is stale-but-previously-valid data good enough for this transaction, or should you retry later?

Vatly

What it is: A VAT-only validation API covering 32 countries (EU + some non-EU).

Strengths: Broader country coverage beyond the EU. Simple REST API.

Limitations: VAT only -- no IBAN, no EORI, no company enrichment. If you need more than VAT validation, you will need additional services. Pricing starts at EUR 29/mo, which is higher than alternatives for the same feature scope.

Best for: Applications that only need VAT validation and require non-EU countries.

VatDB

What it is: A basic VAT validation API for the 27 EU member states.

Strengths: Low price point (EUR 19.99/mo). Straightforward REST API.

Limitations: EU-only, no UK. No IBAN or EORI validation. Limited documentation on caching and failover behavior.

Best for: Simple EU-only VAT checks on a tight budget where uptime guarantees are not critical.

Build your own VIES wrapper

What it is: Call VIES directly using a SOAP library (zeep in Python, soap in Node.js) and build your own caching and error handling.

Strengths: No third-party dependency. No per-request costs. Full control.

Limitations: You own the maintenance. That means: implementing per-country circuit breakers, managing a caching layer, handling the Greece EL/GR mapping, building retry logic for the global rate limit, monitoring 27 independent country backends, and dealing with SOAP/XML parsing. This is a meaningful engineering investment -- likely 2--4 weeks for a production-grade implementation.

Best for: Teams with the engineering bandwidth who want full control and have very high volume (500K+ validations/month) where per-request pricing becomes significant.

Decision criteria

Criteria VIES direct EuroValidate Vatly VatDB DIY wrapper
VAT validation Yes Yes Yes Yes Yes
IBAN validation No Yes No No Separate
EORI validation No Yes No No Separate
Company enrichment Partial Yes (GLEIF) No No Separate
REST/JSON No (SOAP) Yes Yes Yes Your choice
Caching No Dual-layer Unknown Unknown Your build
Circuit breakers No Per-country Unknown Unknown Your build
Confidence scoring No Yes No No Your build
DE/ES company names No Via GLEIF No No Via GLEIF
UK support No Yes (HMRC) Yes No Separate
Free tier Unlimited 100 req/hr No No Unlimited
Paid pricing Free From EUR 19/mo From EUR 29/mo EUR 19.99/mo Infra costs

When to use each option

Use VIES directly if you have low volume, can tolerate downtime, and only need basic VAT valid/invalid checks. Be prepared for 30% of your requests to fail during peak hours.

Use EuroValidate if you need a production-grade integration that handles VIES failures gracefully, you want VAT + IBAN + EORI in one API, and you do not want to build caching infrastructure. The free tier is enough to build and test. Get a free API key.

Use Vatly if you specifically need non-EU country coverage (e.g., Norway, Switzerland) and only need VAT validation.

Use VatDB if you only need EU VAT validation and want the lowest possible price.

Build your own if you have engineering capacity, need full control over the stack, and validate at volumes where per-request pricing is a concern.

Common pitfalls when switching from VIES

Do not cache indefinitely

VAT registrations change. Companies deregister, merge, or update their details. A 24-hour cache TTL balances freshness against upstream load. If you cached a VIES result 6 months ago, it may no longer reflect reality.

Handle the confidence field

If you switch to an API that provides confidence scoring, use it. A confidence: "low" response means the data is stale -- the upstream was unavailable at request time. For low-risk operations (pre-filling a form), stale data is fine. For high-risk operations (reverse charge invoicing), you may want to require confidence: "high" and retry later if the upstream is down.

Test with real country edge cases

Use NL820646660B01 (Netherlands, returns full data), FR40303265045 (France, returns full data), and a German VAT number (returns null for company name). Do not test with made-up numbers -- VIES validates against real tax databases, and invalid formats produce different error codes than non-existent registrations.

Next steps

  1. Get a free EuroValidate API key -- 100 requests per hour, no credit card.
  2. Interactive API docs -- test every endpoint from your browser.
  3. Node.js integration guide -- 5 lines of code to validate VAT in Node.js.
  4. Python integration guide -- sync and async examples for Python.

EuroValidate is a unified REST API for EU business data validation. It wraps VIES, EORI, IBAN, GLEIF, and HMRC behind a single JSON endpoint with per-country circuit breakers, dual-layer caching, and confidence scoring on every response.

Top comments (0)