Validate EU VAT in Node.js (5 Lines of Code)
Validate EU VAT in Node.js (5 Lines of Code)
You can validate any EU VAT number in Node.js by calling the EuroValidate REST API. Install the SDK, pass a VAT number, and get back a typed result with the company name, address, and a confidence score -- all in under 5 milliseconds for cached lookups. No SOAP parsing, no XML, no VIES downtime headaches. Here is the minimal working example.
Quick start
Install the SDK:
npm install @eurovalidate/sdk
Validate a VAT number in 5 lines:
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."
That is it. The SDK handles retries on rate limits (429 with Retry-After), timeouts, and error mapping automatically.
Using curl instead
If you prefer to test from the terminal before writing any code:
curl -H "X-API-Key: ev_live_your_key_here" \
https://api.eurovalidate.com/v1/vat/NL820646660B01
What the API returns
Valid VAT number
Request: GET /v1/vat/NL820646660B01
{
"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"
}
}
Invalid VAT number
Request: GET /v1/vat/NL000000000B00
{
"vat_number": "NL000000000B00",
"country_code": "NL",
"status": "invalid",
"company_name": null,
"company_address": null,
"request_id": "req_def456",
"meta": {
"confidence": "high",
"source": "vies_live",
"cached": false,
"response_time_ms": 189,
"last_verified": "2026-04-05T10:15:35Z",
"upstream_status": "ok"
}
}
The status field is one of: valid, invalid, error, or unavailable. The confidence field tells you how fresh the data is: high means a live upstream check, medium means served from cache, low means the upstream was down and you are getting stale data.
TypeScript support
The SDK ships with full type definitions. Every response is a typed interface:
import { EuroValidate, VatResult } from "@eurovalidate/sdk";
const client = new EuroValidate("ev_live_your_key_here");
const result: VatResult = await client.validateVat("FR40303265045");
if (result.valid) {
console.log(`Company: ${result.companyName}`);
console.log(`Address: ${result.companyAddress}`);
console.log(`Confidence: ${result.meta?.confidence}`);
} else {
console.log(`VAT number ${result.vatNumber} is not valid`);
}
The VatResult interface gives you autocomplete for valid, vatNumber, countryCode, companyName, companyAddress, status, meta, and requestId.
Error handling
The SDK throws typed errors you can catch:
import { EuroValidate, RateLimitError, AuthError } from "@eurovalidate/sdk";
const client = new EuroValidate("ev_live_your_key_here");
try {
const result = await client.validateVat("NL820646660B01");
console.log(result.valid);
} catch (err) {
if (err instanceof RateLimitError) {
// Automatic retry handles most 429s, but if retries are exhausted:
console.log("Rate limited. Try again later.");
} else if (err instanceof AuthError) {
console.log("Invalid API key.");
} else {
throw err;
}
}
Latency
Typical response times you can expect:
| Scenario | Latency |
| Cached result (Redis hit) | 1--5 ms |
| Live VIES lookup | 150--300 ms |
| VIES unavailable, stale cache returned | 2--8 ms |
Once a VAT number is validated, the result is cached for 24 hours. Subsequent lookups for the same number hit the Redis cache and return in single-digit milliseconds. For high-traffic applications, this means the majority of your requests resolve almost instantly.
Common pitfalls
Germany and Spain never return company names
The German (DE) and Spanish (ES) tax authorities do not return trader name or address through VIES. This is a data protection policy at the country level, not a bug. When you validate a German VAT number, company_name and company_address will be null even if the number is valid.
EuroValidate works around this by cross-referencing GLEIF data (the Global LEI system) when available, but coverage depends on whether the company holds an LEI.
Greece uses EL, not GR
VIES uses the prefix EL for Greece, but ISO 3166 uses GR. The API accepts both -- you can pass EL820646660 or GR820646660 and the mapping is handled automatically. The country_code field in the response always returns the ISO code (GR).
Northern Ireland dual status
Northern Ireland businesses may have both a UK VAT number (GB prefix) and an EU EORI number (XI prefix) for customs. If you are handling cross-border e-commerce involving Northern Ireland, validate both the VAT and EORI separately.
VIES downtime
The VIES service operated by the European Commission has a historical uptime around 70%. Individual country backends go down independently -- Germany alone accounts for the majority of VIES errors. EuroValidate uses per-country circuit breakers so that one country going offline does not affect lookups for other countries. When a country backend is unavailable, the API returns the last cached result with confidence: "low" and upstream_status indicating the issue.
Unified validation
If you need to validate a VAT number and an IBAN in a single request, use the unified endpoint:
const client = new EuroValidate("ev_live_your_key_here");
const response = await fetch("https://api.eurovalidate.com/v1/validate", {
method: "POST",
headers: {
"X-API-Key": "ev_live_your_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
vat_number: "NL820646660B01",
iban: "DE89370400440532013000"
})
});
const data = await response.json();
console.log(data.vat.status); // "valid"
console.log(data.iban.valid); // true
This counts as one API call against your quota.
Pricing
The free tier includes 100 requests per hour -- enough to build and test your integration. Paid plans start at EUR 19/month for 5,000 requests.
| Plan | Price | Requests/month |
| Free | EUR 0 | 100/hr |
| Starter | EUR 19/mo | 5,000 |
| Growth | EUR 49/mo | 25,000 |
| Scale | EUR 149/mo | 100,000 |
Next steps
- Get your free API key -- takes 30 seconds, no credit card required.
- Read the full API docs -- interactive Swagger UI where you can test every endpoint.
- Explore the IBAN endpoint -- validate IBANs and get bank name + BIC in the same call.
- Batch validation -- validate up to 1,000 VAT numbers in a single async request.
EuroValidate is a unified REST API that replaces 5 fragmented EU government services (VIES, EORI, IBAN, GLEIF, national registries) with a single JSON endpoint. Built for developers who need reliable EU business data validation without dealing with SOAP/XML, per-country downtime, or inconsistent response formats.
