# EU VAT Number Bulk Validator (from VIES data) (`br_data_hub/eu-vat-validator`) Actor

Bulk-check EU and Northern Ireland (XI) VAT numbers using the European Commission's public VIES service: valid or invalid, company name and address, consultation number. Offline check-digit validation and automatic retries.

- **URL**: https://apify.com/br_data_hub/eu-vat-validator.md
- **Developed by:** [br_data_hub](https://apify.com/br_data_hub) (community)
- **Categories:** Developer tools, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.75 / 1,000 vat checks

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## EU VAT Number Bulk Validator (from VIES data)

Check **EU VAT numbers in bulk** against **VIES**, the European Commission's official VAT Information Exchange System. Covers all 27 EU member states and **XI (Northern Ireland)**. For every number you get valid or invalid, the trader **name and address** when the member state shares them, the VIES request date and, if you give your own VAT number, the **consultation number** that proves the check to a tax auditor.

> Independent tool. Not affiliated with, endorsed by or operated by the European Commission or any national tax administration; it only calls the public VIES service on your behalf.

What it does that a plain VIES call doesn't:

- **Offline pre-check of format and check digit** for every country (via [python-stdnum](https://arthurdejong.org/python-stdnum/)). Typos such as a wrong last digit are flagged right away with a clear reason (`Invalid DE VAT number: check digit does not match`), without a VIES call and **free of charge**.
- **Automatic retries when a country's service is down.** National VIES back-ends often answer `MS_UNAVAILABLE` or `TIMEOUT`. Those numbers are retried after 15 s, 45 s and 120 s. If a country is still down at the end, the item says so (`status: "unavailable"`, `errorCode: "MS_UNAVAILABLE"`) and you are not charged.
- **Normalization and de-duplication.** `fr 40 303.265-045`, `FR40303265045` and `GR…`/`EL…` are understood; each distinct number is checked once and the other spellings are listed in `duplicateInputs`.

### Input

| Field | Description |
|---|---|
| `vatNumbers` | VAT numbers with country prefix, one per line (up to 10,000 per run). Spaces, dots, dashes and slashes are ignored. |
| `requesterVatNumber` | Optional. Your own EU VAT number. VIES then returns a `consultationNumber` for each check, to keep as proof of due diligence. |
| `defaultCountryCode` | Optional. Country used for numbers written without a prefix (e.g. `DE`). |
| `includeNameAndAddress` | Return the trader name and address (default `true`). |
| `strictChecksum` | Reject numbers with a wrong check digit offline (default `true`). Turn off to send them to VIES anyway. |
| `maxRetries` | Retry rounds for countries that did not answer (default 3, max 5). |
| `maxConcurrency` | Parallel VIES requests (default 3). VIES limits concurrent requests per country, so keep it low. |

The default input checks two well-known company numbers (Google Ireland and Amazon EU in Luxembourg), one duplicate spelling and one number with a wrong check digit, and finishes in seconds.

### Output

One item per distinct number:

```json
{
  "input": "IE6388047V",
  "vatNumber": "IE6388047V",
  "countryCode": "IE",
  "number": "6388047V",
  "duplicateInputs": ["ie 6388047v"],
  "status": "valid",
  "valid": true,
  "name": "GOOGLE IRELAND LIMITED",
  "address": "3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4",
  "requestDate": "2026-10-30T12:00:00.000Z",
  "consultationNumber": "WAPIAAAAZ1x2y3z4",
  "attempts": 1,
  "checkedAt": "2026-10-30T12:00:00+00:00"
}
```

| `status` | Meaning | Charged |
|---|---|---|
| `valid` | VIES confirmed the number is active for intra-EU transactions. | yes |
| `invalid` | VIES answered that the number is not valid (or not registered for intra-EU trade). | yes |
| `format_error` | Rejected offline: unknown country prefix, wrong length or format, or wrong check digit. `error` explains why. | no |
| `unavailable` | The national service or VIES did not answer after all retries. `errorCode` is `MS_UNAVAILABLE`, `TIMEOUT`, `SERVICE_UNAVAILABLE`, a concurrency limit or a network error. Run again later. | no |
| `error` | VIES refused the request (`INVALID_INPUT`, `INVALID_REQUESTER_INFO`, `VAT_BLOCKED`, `IP_BLOCKED`). | no |

`name` and `address` are `null` when the member state does not share them (Germany, for example, never does). The run's `OUTPUT` record in the key-value store has a count per status.

### How much does it cost?

Pay per event: **`vat-check`**, charged once for each number VIES actually answered (`valid` or `invalid`). Format errors, duplicates, unavailable countries and refused requests are free. Apify's standard **`apify-actor-start`** event (US$ 0.00005 per run) also applies. No platform usage is billed on top.

Suggested price: **US$ 0.002 per check (US$ 2 per 1,000)**. How it was set:

- Apify compute costs US$ 0.20 per compute unit (1 CU = 1 GB of memory for 1 hour). The Actor needs little memory (about 75 MB measured) and runs at 256 MB.
- A VIES answer takes roughly 0.3 to 1.5 s; with 3 parallel requests that is about 0.5 s per number, so 1,000 numbers take about 8 minutes: 0.25 GB × 0.14 h = 0.035 CU = **US$ 0.007 per 1,000 checks**. Start-up adds a few seconds per run, and a run that waits for an unavailable country can spend up to 3 minutes waiting (about US$ 0.0025).
- Profit per check is 0.8 × US$ 0.002 − compute ≈ US$ 0.0016, far above the compute cost, so even tiny runs and long retry waits are covered.

Similar Actors in the Store charge from about US$ 2.40 to US$ 5 per 1,000 checks, some with an extra fee per run; US$ 2 per 1,000 with free errors and free retries is at the low end.

**$0.0025 per vat check** (`vat-check` event, pay per event). Charged once per number VIES answered as valid or invalid. Format errors, unavailable services and duplicates are free.

- `apify-actor-start`: $0.00005 (Charged once when a run starts (Apify synthetic event).)

| You get | Free tier | Bronze tier (10% off) | Gold tier (30% off) |
|---|---|---|---|
| 100 vat checks | $0.25 | $0.23 | $0.17 |
| 1,000 vat checks | $2.50 | $2.25 | $1.75 |
| 10,000 vat checks | $25.00 | $22.50 | $17.50 |

Discounts follow your Apify subscription tier: Bronze 10%, Silver 20%, Gold and above 30%. No subscription to this Actor and no charge for platform usage: you pay only for results.
The Apify Free plan includes $5 of monthly credit, enough for about **2,000 vat checks** at the list price.
You can cap the cost of any run with **Maximum cost per run**; the Actor stops when it is reached.

### Data source

[VIES on the web](https://ec.europa.eu/taxation_customs/vies/) and its public REST API (`check-vat-number`), run by the European Commission (DG TAXUD). VIES is a search engine, not a database: each answer comes live from the tax administration of the member state, and the Commission states it cannot be held responsible for the accuracy of that data. The service is free and needs no key. This Actor sends one request per distinct number, with low concurrency and back-off when a country is busy, and does not keep any copy of the answers outside your run's dataset.

Names and addresses are shown as published by the member states for VAT purposes. Some VAT numbers belong to sole traders, whose name and address are personal data: use them only to verify business partners (as VIES intends), or set `includeNameAndAddress` to `false`. A valid answer does not replace your own legal or tax checks.

### More questions

#### Which countries does it cover? Can I check UK (GB) VAT numbers?

The 27 EU member states plus **XI** (Northern Ireland). VIES no longer covers Great Britain, so `GB…` numbers come back as `format_error` with "Unknown country prefix" and are not charged. Greek numbers can be written with `GR` or `EL`: both are sent to VIES as `EL`.

#### In what format can I paste the numbers?

Any common spelling works: `FR 40 303 265 045`, `fr40.303.265-045` and `FR40303265045` are the same number. Spaces, dots, dashes, slashes, commas and underscores are removed and letters are upper-cased. Numbers without a country prefix need `defaultCountryCode`; otherwise they get a free `format_error`. Each distinct number is checked once and the other spellings go to `duplicateInputs`.

#### Why are `name` and `address` empty for some numbers?

The member state decides what VIES shows. Some, such as Germany, never return the trader's name or address, and others answer `---`; in both cases the fields are `null`. The `valid` answer still comes from VIES. If you only need valid or invalid, turn off `includeNameAndAddress`.

#### How do I get a consultation number for my tax audit file?

Fill in `requesterVatNumber` with your own EU VAT number (with prefix). VIES then returns a `consultationNumber` for each check, which proves you verified that customer on that date (`requestDate`). The Actor checks your number's format before the run starts and stops with a clear message if it is wrong.

#### What happens when a country's VAT service is down?

National services often answer `MS_UNAVAILABLE` or `TIMEOUT`, and VIES may answer that too many requests are running at once. Those numbers are tried again after 15 s, 45 s and 120 s (`maxRetries`, default 3, up to 5). If there is still no answer, the item gets `status: "unavailable"` with the `errorCode` and the number of `attempts`, and you are not charged. Run those numbers again later.

#### Does `invalid` mean the company does not exist?

Not necessarily. VIES says whether the number is valid for **intra-EU** transactions. A business can have a domestic VAT number that is not registered for cross-border trade, and VIES then answers invalid. A check-digit error caught offline is a different case: it shows as `format_error`, without asking VIES. Set `strictChecksum` to `false` if you want those numbers sent to VIES anyway.

#### Is the answer live or cached?

Live. Every run asks VIES again, and `requestDate` is the date VIES gives in its answer. The Actor keeps no copy of the answers outside your run's dataset.

#### How many numbers can I check in one run?

Up to 10,000 per run; extra numbers are ignored with a warning in the log. With the default of 3 parallel requests, 1,000 numbers take a few minutes, plus the retry waits if a country is down. Raising `maxConcurrency` (up to 10) is faster but VIES limits concurrent requests per country, so busy answers become more likely.

### Use it via API

Run it from any language and get the results as JSON. Replace `<YOUR_API_TOKEN>` with your [Apify API token](https://console.apify.com/settings/integrations).

```bash
curl -X POST "https://api.apify.com/v2/acts/br_data_hub~eu-vat-validator/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"vatNumbers": ["IE6388047V", "LU 2637 5245", "ie 6388047v", "DE811569860"]}'
```

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("br_data_hub/eu-vat-validator").call(run_input={'vatNumbers': ['IE6388047V', 'LU 2637 5245', 'ie 6388047v', 'DE811569860']})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

You can also schedule runs, send results to webhooks, or connect the Actor to Make, Zapier, n8n, Google Sheets and other [integrations](https://docs.apify.com/platform/integrations).

### Use it with AI agents (MCP)

This Actor is ready for AI agents: typed input and output schemas, pay-per-event pricing, limited permissions and short runs.

- **Apify MCP server:** add `https://mcp.apify.com/?tools=br_data_hub/eu-vat-validator` to Claude, ChatGPT, Cursor, VS Code or any MCP client, and the agent can call this Actor as a tool.
- **Agent frameworks:** call it from LangChain, LlamaIndex, CrewAI or the OpenAI Agents SDK through the Apify integrations, or with the API call above.
- Results come as structured JSON with stable field names, documented in the **Output** tab.

### FAQ

#### Where does the data come from?

[VIES on the web](https://ec.europa.eu/taxation_customs/vies/) and its public REST API (`check-vat-number`), run by the European Commission (DG TAXUD). VIES is a search engine, not a database: each answer comes live from the tax administration of the member state, and the Commission states it cannot be held responsible for the accuracy of that data. The service is free and needs no key. This Actor sends one request per distinct number, with low concurrency and back-off when a country is busy, and does not keep any copy of the answers outside your run's dataset.

#### How much does it cost?

$0.0025 per vat check. Discounts follow your Apify subscription tier: Bronze 10%, Silver 20%, Gold and above 30%. See **How much does it cost?** above for examples.

#### Do I pay for errors or empty results?

No. Charged once per number VIES answered as valid or invalid. Format errors, unavailable services and duplicates are free.

#### Can I run it on a schedule or connect it to other tools?

Yes. Use Apify schedules to run it daily or weekly, webhooks to get notified, and integrations such as Make, Zapier, n8n and Google Sheets. Everything also works through the API.

#### Can AI agents use it?

Yes. It works as a tool in the Apify MCP server and in agent frameworks, and AI agents can pay per event. See **Use it with AI agents (MCP)**.

#### Is it legal to use this data?

The Actor reads only public sources. You are responsible for how you use the data and for complying with the source's terms and with privacy laws such as GDPR.

#### I found a bug or need a feature. What should I do?

Open an issue in the **Issues** tab. We answer within 14 days, usually much sooner.

### More Actors from BR Data Hub

| Actor | What it does |
|---|---|
| [LEI Lookup & Corporate Ownership Tree, from GLEIF data](https://apify.com/br_data_hub/lei-corporate-tree) | Look up companies by LEI or name in GLEIF's open Global LEI Index: legal data, direct and ultimate parent, sub |
| [Sanctions Screening: OFAC, UN, EU, UK](https://apify.com/br_data_hub/global-sanctions-screening) | Screen people and companies using data from the official OFAC SDN and Consolidated, UN Security Council, EU an |
| [US Company Financials from SEC XBRL Data (normalized)](https://apify.com/br_data_hub/sec-company-financials) | Standardized financial statements of US-listed companies, built from public SEC XBRL data: revenue, profits, E |
| [Entity Resolver & ID Crosswalk (from Wikidata data)](https://apify.com/br_data_hub/wikidata-entity-resolver) | Resolve company, brand, organization and place names to the right Wikidata entity with an explained confidence |
| [EU Public Tenders Search, from TED data](https://apify.com/br_data_hub/eu-ted-tenders) | Search European public tenders using open data from TED (Tenders Electronic Daily), the EU procurement journal |

See all our Actors at [apify.com/br_data_hub](https://apify.com/br_data_hub).

### Usar em português

Informe números de IVA (VAT) da União Europeia ou da Irlanda do Norte (XI), um por linha, com o prefixo do país, e receba para cada um se é válido no VIES, o sistema oficial da Comissão Europeia, com nome e endereço quando o país informa. Se informar o seu próprio número de IVA em `requesterVatNumber`, cada consulta traz o número de consulta (consultation number), que serve de prova perante o fisco. Números com dígito verificador errado são recusados sem consultar o VIES, países fora do ar são consultados de novo automaticamente e só as respostas do VIES (válido ou inválido) são cobradas.

**Quanto custa:** $0.0025 por resultado (`vat-check`); 1.000 resultados saem por $2.50. Desconto pelo nível da assinatura Apify: Bronze 10%, Silver 20%, Gold ou acima 30%. Erros e consultas sem resultado não são cobrados. Use também pela API ou por agentes de IA no servidor MCP da Apify (`https://mcp.apify.com/?tools=br_data_hub/eu-vat-validator`).

# Actor input Schema

## `vatNumbers` (type: `array`):

Enter VAT numbers with the country prefix, one per line, e.g. DE811569869 or FR 40 303 265 045, up to 10,000 per run. Spaces, dots and dashes are removed, GR is read as EL and duplicates are checked once.

## `requesterVatNumber` (type: `string`):

Type your company's EU VAT number with prefix to get a VIES consultation number for every check, which you can keep as audit proof that you verified the customer on that date. Optional.

## `defaultCountryCode` (type: `string`):

Type a two-letter VIES code, e.g. DE, FR, EL or XI, to use for numbers written without a country prefix.

## `includeNameAndAddress` (type: `boolean`):

Keep on to return the trader name and address when the member state shares them (some, such as Germany, never do). Turn off to keep no trader details, e.g. when sole traders may be personal data.

## `strictChecksum` (type: `boolean`):

Keep on to reject numbers whose check digit fails the national algorithm without calling VIES (free, status format_error). Turn off to send them to VIES anyway; length and format are still checked.

## `maxRetries` (type: `integer`):

Set how many times to retry numbers VIES could not answer (MS_UNAVAILABLE, TIMEOUT, busy), after 15 s, 45 s and then 120 s, e.g. 3. Numbers still unanswered get status unavailable and are not charged.

## `maxConcurrency` (type: `integer`):

Set how many checks go to VIES at the same time, e.g. 3. VIES limits concurrent requests per country, so keep it low.

## Actor input object example

```json
{
  "vatNumbers": [
    "IE6388047V",
    "LU 2637 5245",
    "ie 6388047v",
    "DE811569860"
  ],
  "includeNameAndAddress": true,
  "strictChecksum": true,
  "maxRetries": 3,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset with all results

## `files` (type: `string`):

Key-value store with the files and the OUTPUT summary of the run

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "vatNumbers": [
        "IE6388047V",
        "LU 2637 5245",
        "ie 6388047v",
        "DE811569860"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("br_data_hub/eu-vat-validator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "vatNumbers": [
        "IE6388047V",
        "LU 2637 5245",
        "ie 6388047v",
        "DE811569860",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("br_data_hub/eu-vat-validator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "vatNumbers": [
    "IE6388047V",
    "LU 2637 5245",
    "ie 6388047v",
    "DE811569860"
  ]
}' |
apify call br_data_hub/eu-vat-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,br_data_hub/eu-vat-validator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/89d72QDteKBHUJebm/builds/tgWOgtgCQvfD1zXZQ/openapi.json
