EU VAT number validation API (VIES): dated answers, 100 free calls

A VAT validation API checks that a VAT identification number is registered for intra-EU trade and gives you a record of the check. Veriport does it in one GET: the national structure and check digit first, then the European Commission’s VIES (REST, SOAP as fallback), the registered name and address where published, and, when a member state is down, a dated cached answer that says it is cached. Every answer states its provenance; on paid tiers the VIES consultation number is the audit evidence.

The answer, field by field

A German number validated live (Germany publishes no trader name through VIES, so name and address are null although the number is valid):

FieldWhat it says
validVIES’s verdict at requestDate: registered for intra-EU trade, or not. An invalid number is a 200, not an error.
countryCode, vatNumber, fullThe normalised number: upper case, prefix split off, spaces and dots removed; GR becomes EL.
structureThe pre-check: valid, checksum (passed, failed or not_checked where no public algorithm exists), expected (the national structure in words).
name, addressAs the member state publishes them; null where it publishes nothing (Germany, most Spanish companies) or when the answer is structure only.
consultationNumberThe VIES reference of this check when you sent requester; the proof an audit accepts. Null on the free tier.
sourcekind (live, cache, structure_only), checkedAt, cacheAgeSeconds, stale: where the answer came from and how old it is.
upstreamservice, transport (rest or soap), status (ok, member_state_unavailable, not_called…), memberStateAvailable.
200 OK · live answer
{
  "valid": true,
  "countryCode": "DE",
  "vatNumber": "136695976",
  "full": "DE136695976",
  "structure": {
    "valid": true,
    "checksum": "passed",
    "expected": "9 digits"
  },
  "name": null,
  "address": null,
  "requestDate": "2026-10-24",
  "consultationNumber": null,
  "source": {
    "kind": "live",
    "checkedAt": "2026-10-24T09:14:03Z",
    "cacheAgeSeconds": 0,
    "stale": false
  },
  "upstream": {
    "service": "vies",
    "transport": "rest",
    "status": "ok",
    "memberStateAvailable": true
  },
  "tableVersion": null
}

When VIES or a member state is down: the degraded path

VIES relays each query to a national register; registers go down for hours, sometimes days (Italy, Germany and Spain most often). Then the API serves the answer it obtained for the same number in the last 30 days, marked source.kind: "cache", stale: true, with the date it was obtained; without a cached answer it returns a 503 vies_unavailable with retryAfter, which is never counted. A cached answer looks like this:

200 OK · cached answer, member state unavailable
{
  "valid": true,
  "countryCode": "ES",
  "vatNumber": "B58378431",
  "full": "ESB58378431",
  "structure": {
    "valid": true,
    "checksum": "not_checked",
    "expected": "9 characters; the first, the last or both are letters"
  },
  "name": "EJEMPLO SL",
  "address": "CALLE EJEMPLO 1, 28001 MADRID",
  "requestDate": "2026-10-17",
  "consultationNumber": null,
  "source": {
    "kind": "cache",
    "checkedAt": "2026-10-17T16:40:11Z",
    "cacheAgeSeconds": 578632,
    "stale": true
  },
  "upstream": {
    "service": "vies",
    "transport": "rest",
    "status": "member_state_unavailable",
    "memberStateAvailable": false
  },
  "tableVersion": null
}

A cached answer is evidence that the number was valid on source.checkedAt, not today. For a one-off sale most sellers accept it; for onboarding a new customer, retry when the member state is back (the status page lists them).

The same call in six languages

One GET, the key optional for the first 20 calls a day. Errors are RFC 9457 problem documents with a stable code.

curl
curl "https://veriport.io/api/v1/vat/validate?country=DE&number=136695976"
# with a key, once you have one:
# curl -H "Authorization: Bearer vp_live_YOUR_KEY" "https://veriport.io/api/v1/vat/validate?country=DE&number=136695976"

Price per 1,000 calls, against the named alternatives

Competitors’ figures are read from their public pricing pages on 2026-10-28 at full use of the included volume; a range means several tiers. Ours include the tax of your country, charged by Stripe as merchant of record.

OfferPriceIncludedPer 1,000Billing
Vatstack Small Business → Enterprise$15 → $150 / month500 → 15,000 validations$30.00 → $10.00Subscription
vatcheckapi tiersmonthly tiersper tier$2.40 → $5.00Subscription
VATSense, vatlayer, Abstractmonthly tiersper tier$1.65 → $14.00Subscription
VIES itself (REST)freeno commitment$0No cache, no consultation number without SOAP, rate limits per IP
Veriport 2,000 pack$9 once2,000 calls, 12 months$4.50Prepaid, no renewal
Veriport 10,000 pack$29 once10,000 calls, 12 months$2.90Prepaid, no renewal
Veriport monthly plan$15 / month5,000 calls + bulk$3.00Subscription, cancel any time

Free before any of this: 100 calls a month with a key, 20 a day without one. A 4xx or 5xx is never counted.

What it is not

Not an official service and not affiliated with the Commission: the verdict is VIES’s, the provenance and the cache are ours. Not a KYB file: a valid number says the number is registered, not that your customer is that company. Not a UK, Swiss or Norwegian check: VIES covers the 27 member states and Northern Ireland; HMRC is on the roadmap.

Questions

Why not call VIES directly?
You can, and the quick start shows the Commission’s endpoint. What you do not get from VIES: a structural pre-check that saves the call, a cached answer when a member state is down, consultation numbers over REST, stable error codes, and a response that says where it came from. Those are the hours this API saves in an invoice run.
Does an invalid answer cost a call?
A 200 with valid: false from VIES costs one call. A structure-only refusal (upstream.status: "not_called") and any 4xx or 5xx cost nothing.
Is the consultation number enough for an audit?
It is the reference the Commission’s service issues to the requester for that check and the one tax administrations ask for; keep it with the date, the number checked and the answer. The API returns it on the paid tiers when you pass your own VAT number as requester.
Where is the data kept?
Functions and database in Paris, France (EU). Validated numbers and their answers are cached up to 30 days for the degraded path; keys are stored hashed; no analytics, no cookies.

100 validations a month, no card, key shown once.

Get a free key

Sources