# EU VAT Number Validator: bulk VIES check (`bepolabs/vat-validation`) Actor

Upload a list; get valid or not, company name and address per entry, with automatic retries when a country's server is down.

- **URL**: https://apify.com/bepolabs/vat-validation.md
- **Developed by:** [BEPO Labs](https://apify.com/bepolabs) (community)
- **Categories:** Business, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 checked vat numbers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

### 🧾 What is EU VAT Number Validator?

Our VAT validator sends every row to VIES, the European Commission's official register, and gives back the verdict, the registered trader where the state discloses it, and the date of the lookup. Malformed input is caught locally before any call, and busy national endpoints are retried instead of dropped. Add your own VAT number and VIES issues a receipt you can file.

- **Invoicing and checkout**: confirm a B2B customer's VAT number before you apply the reverse charge
- **CRM and ERP clean-up**: check a whole customer or supplier export at once and find the numbers that are no longer valid
- **Audit trail**: with your own VAT id, keep the VIES consultation number of every check as proof
- **Onboarding and KYB**: match the company name and address VIES returns against what the customer entered
- **Automation and AI agents**: validate VAT numbers from Make, Zapier, n8n or an AI agent through MCP

![EU VAT Number Validator: Check thousands of EU VAT numbers against the official VIES service: valid or not, company name and address.](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/vat-validation-hero.png)

#### ✨ Why use this Actor?

- ✅ **Official source**: the European Commission's VIES service, the reference for intra-EU VAT checks
- ✅ **Format check first**: each number cleaned (spaces, dots, dashes) and matched to its country's pattern before any call
- ✅ **Survives VIES outages**: numbers hit by a busy or offline country are retried in later rounds with a wait
- ✅ **Proof of check**: with your own VAT id as requester, a VIES consultation number per number
- ✅ **All 27 countries plus XI**: Greece as EL (GR is accepted), Northern Ireland as XI
- ✅ **Gentle on VIES**: 2 checks at once by default, never more than 5, as VIES asks

### 📦 What data can you get with EU VAT Number Validator?

| | | |
|---|---|---|
| 🔢 Clean VAT number | 🌍 Country code | ✅ Valid or invalid |
| 🚦 Status (valid, invalid, format-error, unchecked) | 🏢 Registered company name | 📍 Registered address |
| 🧾 Consultation number (proof) | 📅 Date and time of the check | 🔁 Attempts needed |
| 📝 Note (why no name, format problem) | ⌨️ Your original input | 🧮 Number without prefix |

### 🚀 How to use EU VAT Number Validator

EU VAT Number Validator works in a few clicks, no coding needed:

1. [Create a free Apify account](https://console.apify.com/sign-up) (the free plan includes 5 USD of monthly credit).
2. Open [EU VAT Number Validator](https://apify.com/bepolabs/vat-validation) and click **Try for free**.
3. Paste your VAT numbers with their country prefix, one per line. Add your own VAT id if you want a consultation number per check.
4. Click **Start** and wait for the run to finish (most runs take seconds).
5. Download your data as JSON, CSV, Excel, XML or HTML, or send it straight to Google Sheets, Make, Zapier or your AI agent.

![How EU VAT Number Validator works](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/vat-validation-workflow.png)

### ⬇️ Input

Give VAT numbers with their two-letter country prefix, up to 10,000 per run. Spaces, dots and dashes are fine.

##### Which format?

Any EU VAT number with its country code: `IE6388047V`, `DE 811 569 869` or `be-0403.170.701`. Greece is `EL` (a `GR` prefix is read as EL); Northern Ireland is `XI`.

##### Proof of the check

Put your own valid EU VAT id in `requesterVatId` and VIES returns a consultation number for every check: the record VIES keeps that you checked on that day.

##### When countries are down

Member-state services go offline or get busy. `retryRounds` (3 if left empty) and `retryWaitSeconds` (default 20) set how often and after how long those numbers are tried again.

| Field | Type | What it does | Default |
|---|---|---|---|
| **VAT ids** (`vatIds`) | array | EU VAT ids with their country prefix, e.g. | `["IE6388047V","NL004495445B01"]` |
| **Your own VAT id (optional)** (`requesterVatId`) | string | With your own valid EU VAT id, VIES returns a consultation number per check, your proof that you checked. |  |
| **Leave out ids with a wrong format** (`skipFormatErrors`) | boolean | Off: each id that fails its country format gets a row with status format-error, without asking VIES. | `false` |
| **Checks at once** (`concurrency`) | integer | VIES is built for single checks and member states limit parallel requests; keep this low. | `2` |
| **Retry rounds** (`retryRounds`) | integer | How often ids are tried again when their country's service is down or busy. | `3` |
| **Wait before each retry round (seconds)** (`retryWaitSeconds`) | integer | Seconds to wait before each retry round, so a busy country can recover. | `20` |

![EU VAT Number Validator input form](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/vat-validation-input.png)

#### Input example

```json
{
    "vatIds": [
        "IE6388047V",
        "NL004495445B01",
        "ATU33864707"
    ]
}
```

### ⬆️ Output

Every VAT number becomes one row, in your input order. `status` tells you what happened: `valid`, `invalid`, `format-error` (caught before any call) or `unchecked` (the country stayed down through every retry). The run summary in the key-value store (`OUTPUT`) counts each status and lists every member state's availability.

![EU VAT Number Validator output table](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/vat-validation-output.png)

#### Output example

One row of the dataset (an Austrian VAT number):

```json
{
    "vatId": "ATU33864707",
    "countryCode": "AT",
    "status": "valid",
    "valid": true,
    "name": "Red Bull GmbH",
    "vatNumber": "U33864707",
    "attempts": 1,
    "address": "Am Brunnen 1, AT-5330 Fuschl/See",
    "input": "ATU33864707",
    "consultationNumber": null,
    "checkedAt": "2026-10-16T06:17:05.675Z",
    "note": null
}
```

#### Format errors, unchecked numbers and countries without names

A number that does not match its country's format stops before VIES; it gets `status: "format-error"` and a note. In a real run: `"FR123" does not match the FR VAT number format`. A number whose national service stayed down through every retry gets `status: "unchecked"` and `valid: null`, so you can run it again later. Germany and Spain withhold the trader's name or address, so their valid numbers come without them (`DE does not share name or address through VIES`). In the same test, the Belgian number needed 3 attempts before VIES answered.

```json
{
    "vatId": "FR123",
    "input": "FR123",
    "status": "format-error",
    "valid": false,
    "attempts": 0,
    "note": "\"FR123\" does not match the FR VAT number format"
}
```

View the results as a table or JSON in the Output tab and download them as JSON, CSV, Excel, XML, HTML or RSS, all fields or only those you pick.

### 💰 How much does EU VAT Number Validator cost?

EU VAT Number Validator is priced **per event**: **2 USD per 1,000 VAT numbers** (0.002 USD each), with no monthly rental. Every dataset row is billed, valid or not, including format errors and those left unchecked. Switch on `skipFormatErrors` to leave malformed entries out at no charge.

| You get | You pay |
|---|---|
| 100 VAT numbers | 0.2 USD |
| 1,000 VAT numbers | 2 USD |
| 10,000 VAT numbers | 20 USD |
| 100,000 VAT numbers | 200 USD |

💡 Apify's free plan gives you 5 USD of credit every month, enough for about **2,500 VAT numbers** at no cost. Set a spending limit per run and the Actor stops there.

### ⚖️ EU VAT Number Validator vs. the alternatives

| | EU VAT Number Validator | VIES website by hand | Typical VAT check tools |
|---|---|---|---|
| **Bulk lists, up to 10,000 per run** | ✅ | one at a time | often small batches |
| **Format check before the call** | ✅ | ❌ | varies |
| **Automatic retries when a country is down** | ✅ | ❌ | often fail at once |
| **Consultation number as proof** | ✅ with your VAT id | ✅ | varies |
| **Export, schedule, API and MCP** | ✅ | ❌ | varies |

### 🔌 Integrations, API and MCP

#### Connect EU VAT Number Validator to your AI agent (MCP)

Give Claude, ChatGPT, Cursor or any MCP client direct access to EU VAT Number Validator through the [Apify MCP server](https://mcp.apify.com). Add this URL to its settings:

```text
https://mcp.apify.com/?actors=bepolabs/vat-validation
```

For Claude Desktop, add it under `mcpServers` in `claude_desktop_config.json`:

```json
{
    "mcpServers": {
        "vat-validation": {
            "command": "npx",
            "args": [
                "-y",
                "@apify/actors-mcp-server",
                "--actors",
                "bepolabs/vat-validation"
            ],
            "env": {
                "APIFY_TOKEN": "<your Apify API token>"
            }
        }
    }
}
```

Then just ask: *"Check these EU VAT numbers and tell me which are valid and the company behind each: IE6388047V, ATU33864707, NL004495445B01."*

#### Run it from your code

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("bepolabs/vat-validation").call(run_input={"vatIds":["IE6388047V","NL004495445B01","ATU33864707"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

JavaScript (`npm install apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('bepolabs/vat-validation').call({"vatIds":["IE6388047V","NL004495445B01","ATU33864707"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### No-code integrations

Send results to **Google Sheets, Slack, Airtable, HubSpot, Make, Zapier, n8n** and more from the Integrations tab, start runs on a **schedule**, or trigger your own endpoint with a **webhook** when a run finishes. The [Apify API](https://docs.apify.com/api/v2) gives you full control over runs and datasets.

### ❓ FAQ

##### Why is a valid number shown without a name?

Some member states (Germany, Spain) never disclose trader details through VIES, and others share them only for some numbers. The row's `note` says so.

##### Why are some rows unchecked?

The country's VAT service was down or overloaded during every retry. `OUTPUT` lists each member state's status from VIES; run those numbers again later.

##### Does it check UK VAT numbers?

Only Northern Ireland (`XI`), which VIES still covers. Great Britain (`GB`) left VIES in 2021.

##### Is a VIES answer legal proof?

A VIES answer is information, not a certificate. With your own VAT id as requester, the consultation number is the record VIES keeps of your check, dated and kept on the VIES side.

##### How many numbers can I check per run?

Up to 10,000. Countries that are busy slow a run down, because their numbers wait for the next retry round.

##### Is it legal to use EU VAT Number Validator?

Yes. VIES is a free public service of the European Commission for checking VAT numbers, and the Actor uses its official REST interface without a key. As VIES asks, the Actor sends single checks, at most 5 at once (2 by default), and backs off when a country is busy. Company names and addresses are returned by the member states for VAT verification; use them for that purpose.

##### What if something is missing or does not work?

Open an issue on the **Issues** tab; we read each one and reply. Feature requests are welcome too.

### 💬 Your feedback

Tell us what EU VAT Number Validator should add on the **Issues** tab or leave a review; your notes decide what we work on next.

### 🔗 Related Actors

| Actor | What it does |
|---|---|
| 🏛️ [SEC EDGAR Filings](https://apify.com/bepolabs/sec-edgar) | Tickers or CIK numbers to SEC filings: 10-K, 10-Q, 8-K, Form 4 and any other form, with document links. |
| 🏛️ [SAM.gov Contract Opportunities](https://apify.com/bepolabs/sam-gov) | US federal contract opportunities by keyword, NAICS, set-aside or agency, with deadlines, contacts and attachments. |
| 🇬🇧 [UK Tenders](https://apify.com/bepolabs/uk-tenders) | UK public contracts from Contracts Finder and Find a Tender by keyword, CPV, value, region and deadline, with daily alerts. |
| 🏛️ [US Federal Grants Finder](https://apify.com/bepolabs/us-grants) | Grants.gov opportunities by keyword, agency or CFDA number, with award amounts, deadlines, eligibility and contacts. |
| 🛡️ [CVE Vulnerability Search](https://apify.com/bepolabs/cve-vulnerabilities) | Official NVD records by CVE id, keyword or product: CVSS, CWE, CISA known-exploited flag and fix links. |
| 📧 [Email Checker](https://apify.com/bepolabs/email-dns-check) | Bulk email validation over DNS: valid, risky or invalid per address, with the reason, MX host, throwaway and shared-inbox flags. |
| 💊 [openFDA Data](https://apify.com/bepolabs/openfda) | FDA adverse events, recalls, drug labels and 510(k) clearances for any drug or device, as clean rows. |
| 📞 [Phone Number Validator](https://apify.com/bepolabs/phone-validator) | Bulk phone number validation offline: valid or not, E.164 format, country and line type (mobile, fixed line, VoIP) for every number. |

# Changelog

This Actor's version history is a separate document: https://apify.com/bepolabs/vat-validation/changelog.md

# Actor input Schema

## `vatIds` (type: `array`):

EU VAT ids with their country prefix, e.g. IE6388047V or DE 811 569 869. Spaces, dots and dashes are removed; GR is read as EL (Greece).

## `requesterVatId` (type: `string`):

With your own valid EU VAT id, VIES returns a consultation number per check, your proof that you checked.

## `skipFormatErrors` (type: `boolean`):

Off: each id that fails its country format gets a row with status format-error, without asking VIES. On: those ids are left out and not charged.

## `concurrency` (type: `integer`):

VIES is built for single checks and member states limit parallel requests; keep this low.

## `retryRounds` (type: `integer`):

How often ids are tried again when their country's service is down or busy.

## `retryWaitSeconds` (type: `integer`):

Seconds to wait before each retry round, so a busy country can recover.

## Actor input object example

```json
{
  "vatIds": [
    "IE6388047V",
    "NL004495445B01"
  ],
  "skipFormatErrors": false,
  "concurrency": 2,
  "retryRounds": 3,
  "retryWaitSeconds": 20
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items, one row per result, in the overview table view.

# 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 = {
    "vatIds": [
        "IE6388047V",
        "NL004495445B01"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bepolabs/vat-validation").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 = { "vatIds": [
        "IE6388047V",
        "NL004495445B01",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("bepolabs/vat-validation").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 '{
  "vatIds": [
    "IE6388047V",
    "NL004495445B01"
  ]
}' |
apify call bepolabs/vat-validation --silent --output-dataset

```

## MCP server setup

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

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/d6sTXJLtHPaUoJJwL/builds/r7aafLt4gbx5vxVsV/openapi.json
