Back to blog

VAT Validation API: VIES, Tax Rates, and Checkout

VIES registration vs tax rates, a checkout state machine, and a production VAT validation API example for EU B2B.

VAT Validation API: VIES, Tax Rates, and Checkout

A VAT number can pass a regex and still be useless for an invoice: the trader is not in VIES, the ID belongs to another country, or the rate you applied has nothing to do with whether the number is valid. A VAT validation API has to answer two different questions — is this a registered VAT ID? and what tax applies to this transaction? — and keep them apart.

Try the checks in this guide

This is the canonical Cleariflow guide for EU VAT IDs and rates. The shorter posts linked at the end are implementation notes, not a second complete guide.

Two questions at checkout

Question What you need What a regex cannot do
Is this VAT ID registered? VIES (or a national register) Country prefix + checksum only prove shape
What rate applies? Place of supply, buyer type, goods/services category A valid ID does not imply 0% or reverse charge

Treat those as two fields in your domain model. Mixing them is how “valid VAT number” becomes a wrong tax total.

What format checks are actually for

Format checks belong on the first keystroke and as a guard before you spend a VIES call:

  • Country prefix (DE, FR, SE, …) matches the address country you already collected.
  • Length and checksum match that country’s VAT syntax.
  • Whitespace and punctuation are stripped once, then stored in a canonical form.

If the format fails, do not call VIES. If it passes, you still do not know whether the trader is registered today.

VIES: the registration check

VIES is the EU’s VAT Information Exchange System. A production validator should:

  1. Send the canonical VAT ID.
  2. Treat timeout / unavailable as a first-class state, not as invalid. Finance teams still need to complete onboarding when VIES is down.
  3. Persist the consultation evidence you are allowed to keep (request id, timestamp, valid flag, company name/address when returned) — not a screenshot of the public form.
  4. Never assume United Kingdom numbers behave like EU-27 VIES after Brexit. GB IDs need a separate policy.

Cleariflow’s VAT API validates through official VIES and returns company name/address when VIES provides them. It covers the 27 EU member states for that lookup. Do not advertise “worldwide VAT” from this endpoint.

Tax rates are a different API surface

Once you know who the buyer is, you still need how much tax to charge:

  • Standard vs reduced vs super-reduced vs zero — by country and often by product category.
  • Reverse charge for intra-EU B2B when the buyer’s VAT ID is valid and the place of supply rules say so.
  • Historical rates if you reprint an invoice from last year.

A lookup that only returns valid: true cannot price a cart. Pair VIES with a rate table (Cleariflow exposes tax-rate calculation on the same product) and keep the decision log: which rate, which category, which date.

Where validation belongs in the product

Put the VIES call at the moment you have country + VAT ID + intent (B2B checkout, seller onboarding, invoice draft) — not on every keypress.

Recommended state machine:

State User-facing System
format_invalid Fix the number No VIES
vies_unavailable Continue, flag for review Retry queue
not_registered Ask for another ID or fall back to consumer VAT Do not reverse-charge
registered Show trader name if you have it Safe to apply B2B rules if place-of-supply agrees

Do not block checkout solely because VIES timed out. Do block reverse charge until registered.

Production API example

curl -sG "https://vat.cleariflow.com/v1/validate/" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "vat_number=SE556656688001"

Typical payload includes valid, vat_number, company.name / company.address, and country.code. Use valid for registration; load rates in a separate step (or a dedicated rates call) before you freeze the invoice.

Product page: VAT Validation & Rates API. Docs: vat.

Evidence without over-collecting

Store what an auditor will ask for: canonical VAT ID, VIES result, time, and the rate snapshot you applied. Do not store full address dumps in application logs. Hash or truncate if you only need cache keys.

Conclusion

EU VAT in production is not “one checkbox.” Split registration (VIES) from rate (place of supply + category), degrade when VIES is down, and keep evidence.

Ship it:

Further reading

These are short notes on the same topic — not a second complete guide: