Validate VAT numbers, IBANs, EORI codes, and company data across 27 EU countries in a single API call. Under 100ms. Not 5 seconds. Not a SOAP timeout.
import eurovalidate
# One call. VAT + IBAN + EORI + company.
result = eurovalidate.validate({
"vat_number": "DE121132589",
"iban": "DE89370400440532013000",
"eori_number": "DE122240001"
})
# Response in ~47ms
{
"valid": true,
"vat": {
"valid": true,
"name": "Musterfirma GmbH",
"address": "Musterstr. 1, Berlin"
},
"iban": { "valid": true, "bic": "COBADEFFXXX" },
"eori": { "valid": true },
"latency_ms": 47
}
You shouldn't need a PhD in SOAP to validate a VAT number. But here we are.
2.45% request failure rate. Germany and Belgium endpoints average 32% monthly downtime. Your checkout flow depends on this.
VIES for VAT. National bank APIs for IBAN. EU Customs for EORI. Company registries for legal entities. Each one is different.
The EU Commission still speaks SOAP. You get to parse XML envelopes, handle namespace prefixes, and debug character encoding. Fun.
VIES routinely takes 3-8 seconds per request. Your users abandon checkout. Your background jobs time out. Your queue backs up.
When VIES goes down at 2 AM, you find out from angry support tickets. No webhooks. No status page. No retry logic.
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/
soap/envelope/"
xmlns:urn="urn:ec.europa.eu:taxud:
vies:services:checkVat:types">
<soapenv:Header/>
<soapenv:Body>
<urn:checkVat>
<urn:countryCode>DE</urn:countryCode>
<urn:vatNumber>123456789</urn:vatNumber>
</urn:checkVat>
</soapenv:Body>
</soapenv:Envelope>
<!-- ...and that's JUST for VAT.
Now add IBAN, EORI, company lookup.
Each with its own protocol.
Each with its own failure modes.
Each with its own XML schema.
Or... one JSON API call. -->
We handle the SOAP, the retries, the failovers, and the caching. You get clean JSON and sub-100ms responses.
VAT, IBAN, EORI, and company validation in a single POST /validate. Send what you have, get everything back.
Validate up to 1,000 VAT numbers per request. Async queue for large jobs with webhook on completion.
Webhooks for validity changes. Get notified when a customer's VAT status changes, not when your audit reveals it.
Official SDKs for Python, Node.js, PHP, Go, Ruby, Java, and .NET. Types included. No code generation needed.
Validation certificates with timestamps. Proof-of-validation for auditors. Exportable compliance reports.
All data processed and stored in the EU (Hetzner, Germany). GDPR compliant by architecture, not just policy.
Install an SDK, add your API key, and start validating. Here's how it looks in your language.
# pip install eurovalidate
from eurovalidate import Client
client = Client(api_key="ev_live_sk_...")
# Validate everything in one call
result = client.validate(
vat_number="DE121132589",
iban="DE89370400440532013000",
eori_number="DE122240001",
)
if result.valid:
print(f"Company: {result.vat.name}")
print(f"BIC: {result.iban.bic}")
print(f"Took: {result.latency_ms}ms")
else:
for err in result.errors:
print(f"Failed: {err.field} - {err.message}")
# Batch validation
batch = client.validate_batch([
{"vat_number": "FR40303265045"},
{"vat_number": "NL820646660B01"},
{"vat_number": "IT00159560366"},
])
valid = sum(1 for r in batch.results if r["status"] == "valid")
print(f"{valid}/{batch.total_items} valid")
// npm install @eurovalidate/sdk
import { EuroValidate } from '@eurovalidate/sdk';
const ev = new EuroValidate('ev_live_sk_...');
// Single validation
const result = await ev.validate({
vat_number: 'DE121132589',
iban: 'DE89370400440532013000',
eori_number: 'DE122240001',
});
if (result.valid) {
console.log(`Company: ${result.vat.name}`);
console.log(`BIC: ${result.iban.bic}`);
console.log(`Took: ${result.latencyMs}ms`);
}
// Batch validation
const batch = await ev.validateBatch([
{ vat_number: 'FR40303265045' },
{ vat_number: 'NL820646660B01' },
{ vat_number: 'IT00159560366' },
]);
const valid = batch.results.filter(r => r.status === 'valid').length;
console.log(`${valid}/${batch.total_items} valid`);
# Single validation
curl -X POST https://api.eurovalidate.com/v1/validate \
-H "X-API-Key: ev_live_sk_..." \
-H "Content-Type: application/json" \
-d '{
"vat_number": "DE121132589",
"iban": "DE89370400440532013000",
"eori_number": "DE122240001"
}'
# Response (47ms)
{
"valid": true,
"vat": {
"valid": true,
"name": "Musterfirma GmbH",
"address": "Musterstr. 1, 10115 Berlin",
"country": "DE"
},
"iban": {
"valid": true,
"bic": "COBADEFFXXX",
"bank_name": "Commerzbank"
},
"eori": { "valid": true },
"latency_ms": 47,
"cached": false
}
// composer require eurovalidate/sdk
use EuroValidate\Client;
$ev = new Client('ev_live_sk_...');
// Single validation
$result = $ev->validate([
'vat_number' => 'DE121132589',
'iban' => 'DE89370400440532013000',
'eori_number' => 'DE122240001',
]);
if ($result->valid) {
echo "Company: " . $result->vat->name;
echo "BIC: " . $result->iban->bic;
}
// Batch validation
$batch = $ev->validateBatch([
['vat_number' => 'FR40303265045'],
['vat_number' => 'NL820646660B01'],
['vat_number' => 'IT00159560366'],
]);
$valid = count(array_filter($batch->results, fn($r) => $r->status === 'valid'));
echo "{$valid}/{$batch->total_items} valid";
No signup needed. Enter a VAT number or IBAN and see the response live.
Enter a value below and hit Validate to see a real API response.
// Click "Validate" to see the response here
No credit card required. No surprise overages. Upgrade or downgrade anytime.
We obsess over uptime so you don't have to. Here's how we compare to going direct.
| Metric | VIES (Direct) | EuroValidate |
|---|---|---|
| Avg response time | 3,200ms | 47ms |
| p99 latency | 8,400ms | 98ms |
| Request failure rate | 2.45% | 0.003% |
| DE endpoint uptime | 68% (monthly avg) | 99.97% |
| BE endpoint uptime | 72% (monthly avg) | 99.95% |
| Protocol | SOAP/XML | REST/JSON |
| Rate limits | Undocumented | Transparent + headers |
VAT in the Digital Age requires real-time VAT validation for all intra-EU B2B transactions.
France, Germany, and Spain mandate B2B e-invoicing. Valid VAT numbers required on every invoice.
Real-time digital reporting to tax authorities. Automated validation becomes non-optional.
Cross-border VAT fraud prevention. Validation at point of transaction mandatory EU-wide.
Real code, real responses, real implementation patterns.
5 lines of code. Install the SDK, validate any EU VAT number, handle the response. Copy-paste ready.
Sync and async examples with the eurovalidate package. Timeout handling, caching tips, common pitfalls.
Validate before charge, apply reverse charge for EU B2B, store proof for tax audit. 10-minute setup.
Why developers switch from raw VIES: 70% uptime, SOAP/XML, no caching. Honest comparison of alternatives.
Germany generates 95% of errors. Circuit breakers, dual-layer cache, and confidence scoring explained.
Solo founder, 7/mo server, 2 weeks to production. The technical story of replacing 5 government APIs.
No fluff. Straight answers.
cached: true flag.cached flag and last_verified timestamp in the meta block.EU tax rules change fast. Get updates on VIES outages, ViDA deadlines, and new API features. No spam, unsubscribe anytime.
Free tier. No credit card. First API call in under 2 minutes.