Skip to main content

Command Palette

Search for a command to run...

VAT Validation REST API Example

Updated
4 min read

Validate EU VAT Numbers with a REST API

To validate an EU VAT number via REST API, send a GET request to https://api.eurovalidate.com/v1/vat/{vat_number} with your API key in the X-API-Key header. The response includes the validation status, company name, address, and a confidence score indicating data freshness. No SOAP, no XML parsing, no WSDL downloads. One HTTP call, JSON response, under 300ms.

curl Example

The fastest way to test. Replace YOUR_API_KEY with a free key from eurovalidate.com.

Valid VAT number

curl -H "X-API-Key: YOUR_API_KEY" \
  https://api.eurovalidate.com/v1/vat/NL820646660B01

Response:

{
  "vat_number": "NL820646660B01",
  "country_code": "NL",
  "status": "valid",
  "company_name": "ABN AMRO BANK N.V.",
  "company_address": "GUSTAV MAHLERLAAN 00010\n1082PP AMSTERDAM",
  "request_id": "req_abc123",
  "meta": {
    "confidence": "high",
    "source": "vies_live",
    "cached": false,
    "response_time_ms": 247,
    "last_verified": "2026-04-08T09:00:00Z",
    "upstream_status": "ok"
  }
}

Invalid VAT number

curl -H "X-API-Key: YOUR_API_KEY" \
  https://api.eurovalidate.com/v1/vat/DE000000000

Response:

{
  "vat_number": "DE000000000",
  "country_code": "DE",
  "status": "invalid",
  "company_name": null,
  "company_address": null,
  "request_id": "req_def456",
  "meta": {
    "confidence": "high",
    "source": "vies_live",
    "cached": false,
    "response_time_ms": 189,
    "upstream_status": "ok"
  }
}

Node.js Example

Install the SDK:

npm install @eurovalidate/sdk
import { EuroValidate } from '@eurovalidate/sdk';

const ev = new EuroValidate('YOUR_API_KEY');

const result = await ev.validateVat('FR40303265045');

if (result.status === 'valid') {
  console.log(`Company: ${result.company_name}`);
  console.log(`Cached: ${result.meta.cached}`);
  console.log(`Confidence: ${result.meta.confidence}`);
} else {
  console.log(`VAT ${result.vat_number} is ${result.status}`);
}

Python Example

Install the SDK:

pip install eurovalidate
from eurovalidate import Client

client = Client(api_key="YOUR_API_KEY")
result = client.validate_vat("IT00159560366")

if result.status == "valid":
    print(f"Company: {result.company_name}")  # FERRARI S.P.A.
    print(f"Response time: {result.meta.response_time_ms}ms")
else:
    print(f"VAT {result.vat_number} is {result.status}")

Unified Validation (VAT + IBAN + EORI in one call)

For checkout flows where you need multiple checks at once:

curl -X POST https://api.eurovalidate.com/v1/validate \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "vat_number": "NL820646660B01",
    "iban": "DE89370400440532013000",
    "eori_number": "NL810002383"
  }'

This returns all three results in a single response, saving you three round trips.

Response Fields Explained

FieldTypeDescription
vat_numberstringThe VAT number as submitted (normalized)
country_codestringISO 3166-1 alpha-2 (or EL for Greece)
statusstringvalid, invalid, error, or unavailable
company_namestring or nullRegistered company name from VIES
company_addressstring or nullRegistered address
meta.confidencestringhigh, medium, low, or unknown
meta.sourcestringvies_live or vies_cached
meta.cachedbooleanWhether the response came from cache
meta.response_time_msintegerTime to produce the response

Latency

ScenarioTypical Time
Cached response (Redis hit)1-5 ms
Live VIES call150-300 ms
VIES slow country (DE)500-1000 ms
IBAN (offline MOD-97)65 ms

Cached responses are served for 24 hours after the first live check. Second and subsequent requests for the same VAT number hit the cache.

Common Pitfalls

Germany and Spain never return company names. These countries redact trader data under national data protection law. Your code should handle company_name: null for DE and ES VAT numbers.

Greece uses EL, not GR. VIES uses EL as the country prefix for Greece, but ISO 3166 uses GR. The API accepts both: EL094019245 and GR094019245 resolve to the same company.

Format validation happens locally. If you send DE12345 (too short for Germany, which requires 9 digits), the API returns HTTP 400 immediately without calling VIES. This saves your quota.

Rate limits are per API key. Free tier: 100 requests/hour. Headers X-RateLimit-Remaining and X-RateLimit-Reset tell you where you stand.

Error Handling

The API uses RFC 7807 Problem Details for errors:

{
  "type": "https://eurovalidate.dev/errors/http",
  "title": "VAT number for DE must be 9 characters (got 5)",
  "status": 400,
  "detail": "VAT number for DE must be 9 characters (got 5)..."
}

Handle these status codes:

CodeMeaningAction
200Success (check status field)Process result
400Bad formatFix input
401Invalid API keyCheck key
429Rate limitWait, retry after Retry-After
502VIES upstream downUse cached result or retry

Authentication

Pass your API key in the X-API-Key header:

X-API-Key: ev_live_your_key_here

Get a free key (no credit card): eurovalidate.com

Pricing

TierPriceRequests
Free$0100/hour
Starter$19/mo5,000/hour
Growth$49/mo25,000/hour
Scale$149/mo100,000/hour

Next Steps