Explainer · VIES

VIES VAT validation: how it works and how to automate it

VIES tells you whether an EU VAT number is registered for cross-border trade. What it returns, why checks fail, and how to call it from code without rejecting good customers when a national register is down.

Updated October 29, 2026 · 8 min read

VIES VAT validation is the European Commission’s free check of whether an EU VAT number is valid for cross-border trade. You send a country code and a number, VIES forwards the question to the tax administration that issued the number, and you get its answer back: valid or invalid, plus the registered name and address where that country shares them. This guide explains what that answer means, why checks fail, how UK numbers fit in since Brexit, and how to call VIES from code. The behaviour and error codes below were checked against the live VIES service on 29 October 2026.

General information, not tax advice.

1. What VIES is

VIES (VAT Information Exchange System) connects the VAT registers of the 27 EU member states and Northern Ireland. There is no central EU database behind it. In the words of the VIES FAQ: “Each time you make a request, a message is sent to the Member State which issued the VAT identification number asking if the number quoted is valid.”

That has two consequences:

VIES exists so that businesses can confirm their trading partners’ VAT numbers (Article 31 of Regulation (EU) No 904/2010). Its disclaimer forbids other uses, such as extracting or republishing the data.

2. What a VIES check returns

The REST API’s check-vat-number answer has these fields:

FieldWhat it means
validtrue if the number is in the issuing country’s VIES register right now
name, addressThe registered name and address, only where the member state shares them. Germany and Spain return ---
requestDateWhen VIES answered
requestIdentifierThe consultation number, if you sent your own VAT number as the requester; otherwise empty
traderNameMatch and the other …Match fieldsVALID, INVALID or NOT_PROCESSED, if you sent the name and address you expect (approximate matching). Most member states answer NOT_PROCESSED

When VIES says “invalid”

valid: false does not always mean a typo. According to the VIES FAQ, the number may not exist, may not be activated for intra-EU transactions (some member states keep a separate register for that), or the registration may not be complete yet. Registrations also end.

A correct check digit is no proof either. In our test, DE136695976, a number with a valid German check digit that appears in many code examples, came back as invalid: the checksum shows the number is well formed, not that it is registered.

If a customer’s number comes back invalid, ask them to check it. If it is correct, they have to contact their own tax administration, because only national administrations can update VIES. Until the number is confirmed, don’t invoice without VAT. The reverse charge guide explains why.

3. The consultation number

Enter your own EU VAT number as the requester and the answer contains a unique consultation number (requestIdentifier in the REST API). The VIES help page recommends keeping it “if you want to be able to prove to a tax administration of a Member State that you have checked a given VAT number at a given time”.

4. Why VIES checks fail

VIES reports problems in an errorWrappers list. The REST API sends most of them with HTTP status 200, so code that only looks at the status code treats a failed check as an answer. A missing field is the exception: HTTP 400 with VOW-ERR-11.

ErrorMeaningWhat to do
INVALID_INPUTUnknown country code (GB, for example) or an empty numberFix the input; a retry gives the same answer
INVALID_REQUESTER_INFOYour requester VAT number is not validFix your own number
MS_UNAVAILABLEThe member state’s system is not answering, often during maintenanceRetry later
TIMEOUTNo answer in timeRetry later
SERVICE_UNAVAILABLEVIES itself or the network failedRetry later
MS_MAX_CONCURRENT_REQ, GLOBAL_MAX_CONCURRENT_REQ (and …_TIME variants)Too many requests at once, for one member state or overallSlow down, then retry
VAT_BLOCKED, IP_BLOCKEDThe number or your IP address is blockedContact the VIES help desk

Maintenance windows

National systems have regular downtimes. A few from the VIES help page (times as VIES lists them; it gives no time zone):

CountryAvailability
GermanyAvailable from 05:00 to 23:00
NetherlandsUnavailable every weekend from Saturday 21:50 to Sunday 21:40
ItalyUnavailable Monday to Saturday from 20:00 for 30 to 60 minutes
RomaniaUnavailable almost every weekend from Saturday 21:50 to Sunday 21:50
Northern Ireland (XI)Unavailable Saturdays from 07:30 to 10:30 and almost daily from about 04:30 to 04:40

The check-status endpoint shows which countries VIES can reach right now.

When a check fails: don’t reject the customer. Take the order, mark the number as unchecked, retry later and keep the error with its time as a record that you tried. A format and check-digit test still catches typos in the meantime (see VAT number formats).

5. UK VAT numbers since Brexit

GB numbers left VIES on 1 January 2021; VIES now answers INVALID_INPUT for them. Northern Ireland businesses that trade goods with the EU use their VAT number with the XI prefix, and those numbers are checked in VIES like any EU number.

GB numbers are checked with HMRC: in the Check a UK VAT number service on GOV.UK, or through HMRC’s API. Version 2 of that API needs an application registered with HMRC’s Developer Hub; version 1, which worked without one, was removed on 17 February 2025. The free UK VAT checker checks GB and XI numbers without code.

6. Call VIES from code

InterfaceAddress
REST: check a numberPOST https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number
REST: status of each member stateGET https://ec.europa.eu/taxation_customs/vies/rest-api/check-status
REST: test servicePOST https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-test-service
SOAPhttps://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl (operations checkVat and checkVatApprox)

None of them needs a key. The REST request body takes countryCode and vatNumber (without the prefix), and optionally requesterMemberStateCode and requesterNumber for a consultation number.

This Python function (Python 3.11, requests 2.34) normalises the input, sends the check and retries only the errors that can go away:

import os
import time

import requests

VIES_URL = "https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number"

# VIES reports these in an errorWrappers list, with HTTP status 200. Retry them later.
RETRYABLE = {
    "SERVICE_UNAVAILABLE", "MS_UNAVAILABLE", "TIMEOUT", "SERVER_BUSY",
    "GLOBAL_MAX_CONCURRENT_REQ", "GLOBAL_MAX_CONCURRENT_REQ_TIME",
    "MS_MAX_CONCURRENT_REQ", "MS_MAX_CONCURRENT_REQ_TIME",
}


class ViesError(Exception):
    def __init__(self, code):
        super().__init__(code)
        self.code = code
        self.retryable = code in RETRYABLE


def check_vies(vat_number, requester=None, attempts=3, url=VIES_URL):
    """Check an EU VAT number such as 'LU26375245' in VIES.

    requester: your own EU VAT number. VIES then returns a consultation
    number in requestIdentifier.
    """
    vat = vat_number.upper().replace(" ", "").replace(".", "").replace("-", "")
    body = {"countryCode": vat[:2], "vatNumber": vat[2:]}
    if requester:
        body["requesterMemberStateCode"] = requester[:2].upper()
        body["requesterNumber"] = requester[2:]

    for attempt in range(1, attempts + 1):
        try:
            response = requests.post(url, json=body, timeout=30)
            data = response.json()
        except (requests.RequestException, ValueError):
            data = {"errorWrappers": [{"error": "SERVICE_UNAVAILABLE"}]}

        errors = data.get("errorWrappers") or []
        if not errors and "valid" in data:
            return data
        error = ViesError(errors[0].get("error", "UNKNOWN") if errors else "UNKNOWN")
        if not error.retryable or attempt == attempts:
            raise error
        time.sleep(5 * attempt)  # wait 5 s, then 10 s


if __name__ == "__main__":
    result = check_vies("LU26375245", requester=os.environ.get("MY_VAT_NUMBER"))
    print(result["valid"], result["name"], result["requestIdentifier"] or "-")

What it did in our test run against the live service:

Test your error handling

The test service answers by the number you send: 100 is valid and 200 invalid, and 201, 202, 300, 301, 302, 400, 401, 500, 501, 600 and 601 return INVALID_INPUT, INVALID_REQUESTER_INFO, SERVICE_UNAVAILABLE, MS_UNAVAILABLE, TIMEOUT, VAT_BLOCKED, IP_BLOCKED, GLOBAL_MAX_CONCURRENT_REQ, GLOBAL_MAX_CONCURRENT_REQ_TIME, MS_MAX_CONCURRENT_REQ and MS_MAX_CONCURRENT_REQ_TIME. Point the function at it with check_vies("DE301", url="https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-test-service").

7. VIES directly or through an API

Calling VIES yourself is free. What it leaves to you is GB numbers, a format check before the call, retries and a record of each check. A VAT validation API such as vatcheckapi wraps those into one request:

VIES directlyvatcheckapi
PriceFree150 free checks a month, then paid plans
Countries27 EU member states and XIThe same plus GB, 29 country codes in one call
Format and check digitNot checked firstChecked before the register is asked
Name and addressWhere the member state shares themThe same; also for GB numbers
Register downAn error code in a 200 responseUp to 5 attempts within about 55 seconds, then a 503, which is not billed (at once when VIES reports the country as down)
Consultation numberWith your requester numberWith requester_vat_number (EU and XI numbers)
curl -G https://api.vatcheckapi.com/v2/check \
    -d vat_number=LU26375245 \
    -d requester_vat_number=ATU78304602 \
    -H "apikey: $VATCHECKAPI_KEY"

The answer has format_valid, checksum_valid and registration_info with is_registered, name, address, consultation_number and checked_at. The Validate VAT Number documentation lists every field; validate VAT numbers in code has examples in JavaScript, Python and PHP. To try a number without code, use the VAT number validator.

Frequently asked questions

Is VIES free?

Yes. The VIES web form, its SOAP service and its REST API are free and need no account or key. There is no service level, VIES is designed for single requests, and it refuses requests when too many run at once (MS_MAX_CONCURRENT_REQ, GLOBAL_MAX_CONCURRENT_REQ).

Can I check UK VAT numbers in VIES?

No, not since 1 January 2021: VIES answers INVALID_INPUT for the GB prefix. GB numbers are checked with HMRC, whose Check a UK VAT number API needs a registered application since version 1 was removed on 17 February 2025. Northern Ireland businesses that trade goods with the EU have XI numbers, which VIES checks.

What is a VIES consultation number?

A unique reference VIES returns when you enter your own EU VAT number as the requester. It proves that you checked a given number at a given time and what VIES answered, so keep it with the invoice. VIES points out that it is only one element of evidence for a VAT-free intra-EU supply.

Why does VIES say a VAT number is invalid when the customer says it is correct?

VIES only knows numbers that the issuing country has activated for intra-EU transactions. Some member states need a separate registration for that, and registrations end. Ask the customer to check the number and, if it is right, to contact their tax administration: only national administrations can correct VIES data.

Why does VIES not show the company name?

The name and address come from the member state, and some do not share them. Germany and Spain, for example, return only the valid or invalid answer.

Does VIES have an API?

Yes. The REST API at https://ec.europa.eu/taxation_customs/vies/rest-api/ has check-vat-number, check-status and a test service; the SOAP service is described in checkVatService.wsdl. Both are free and need no key.

Can I check many VAT numbers at once in VIES?

Not in one request. VIES says it is designed for single requests, so send them one after another and slow down when it reports too many concurrent requests. For lists, the bulk VAT validator checks up to 50 numbers per run.

VAT validation API

Validate VAT numbers in your app

vatcheckapi checks the format and checksum of EU and UK VAT numbers and confirms the registration live (VIES for EU numbers), with company name and address where the country provides them.

/v2/check documentation VAT number API All documentation

150 free validations every month. No credit card required.

GET https://api.vatcheckapi.com/v2/check?vat_number=LU26375245

{
  "country_code": "LU",
  "vat_number": "26375245",
  "format_valid": true,
  "checksum_valid": true,
  "registration_info": {
    "is_registered": true,
    "name": "AMAZON EUROPE CORE S.A R.L.",
    "address": "38, AVENUE JOHN F. KENNEDY\nL-1855  LUXEMBOURG",
    "address_parts": null,
    "checked_at": "2026-10-16T09:12:44.000000Z"
  },
  "registration_info_history": []
}

Keep reading

Start using our VAT validation API for free today

Get 150 validations / month for free