# EU VAT Number Validator: VIES Check with Company Name (`f0rty7even/vat-validator`) Actor

Validate EU VAT numbers in bulk against VIES, the European Commission's official service. Returns whether each number is registered and active, the trader name and address where the country publishes them, and a consultation number you can keep as proof of the check.

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

## Pricing

from $3.50 / 1,000 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## EU VAT Number Validator: VIES Check with Company Name

Paste a list of EU VAT numbers. Get back, for each one, whether it is registered and active, the trader's name and address where the issuing country publishes them, and a consultation number you can keep as evidence that you checked.

This queries **VIES**, the European Commission's official VAT Information Exchange System, which forwards each request to the member state that issued the number. A `valid` result here is the same answer the tax authority would give.

**$5 per 1,000 numbers.** Numbers that could not be checked because a country's service was down are never charged.

***

### What you get for every number

| Field | Example | Notes |
|---|---|---|
| `status` | `valid` | `valid`, `invalid`, `unchecked` or `unparseable` |
| `isValid` | `true` | Registered and active right now |
| `reason` | `VIES confirmed this VAT number is registered and active` | Plain English, safe to show a user |
| `companyName` | `GOOGLE IRELAND LIMITED` | Where the country publishes it |
| `companyAddress` | `3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4` | Where the country publishes it |
| `detailsWithheldByCountry` | `true` | Valid number, but that country never publishes trader details |
| `consultationNumber` | `WAPIAAAAV1234` | VIES reference, your proof of the check |
| `countryCode`, `vatNumber`, `fullVatNumber` | `DE`, `812871812`, `DE812871812` | Normalised |
| `requestDate` | `2026-08-09T20:00:00.000Z` | When VIES answered |
| `input` | `DE 812 871 812` | Exactly what you supplied, for joining back |

***

### Four statuses, and why that matters

Most VAT tools return a boolean. A boolean cannot tell you the difference between "this number is not registered" and "Germany's tax service was offline when we asked", and treating the second as the first is how a supplier gets wrongly flagged in a compliance workflow.

| Status | Meaning | Charged |
|---|---|---|
| `valid` | VIES confirms an active registration | Yes |
| `invalid` | VIES has no active registration for that number, or the format is not a valid EU VAT identifier | Yes |
| `unchecked` | The issuing country's service was unavailable, timed out, or VIES rate limited the request | **No** |
| `unparseable` | No EU VAT number could be read from that input at all | **No** |

VIES answers `HTTP 200` with `isValid: false` for national outages just as it does for genuinely invalid numbers, distinguishing them only by an error code buried in the response. This reads that code, retries the transient ones, and keeps the two apart.

A run also checks which member states VIES currently reports as down and says so in the log up front, so a batch of `unchecked` rows has a visible explanation.

***

### Germany and Spain confirm the number but withhold the name

Several member states validate a VAT number without publishing the trader's details. Germany and Spain are the common ones. VIES returns `---` in those fields.

Rather than pass that through as a literal string or silently return an empty name, this sets `companyName` and `companyAddress` to `null` and raises `detailsWithheldByCountry: true`. So an empty name means one of two clearly distinguished things, and you can tell which.

***

### Input formatting is handled for you

Real VAT numbers arrive from invoices and spreadsheets, formatted for humans.

- `DE812871812`, `DE 812 871 812` and `de-812.871.812` are all the same number.
- Spaces are **not** treated as separators, because a spaced number is one number, not three. Line breaks, commas and semicolons split entries.
- Greece files VAT under `EL`, not its ISO code `GR`, and `GR` is translated automatically.
- Northern Ireland kept an EU VAT prefix after Brexit; `GB` and `UK` map to `XI`.
- Duplicates are removed after normalising, so the same number written two ways is checked and charged once.
- Numbers with no prefix work if you set a default country.

***

### Common uses

**Onboarding a new supplier or customer.** Confirm the VAT number is real and, where published, that the registered name matches the one on the contract. `consultationNumber` is the record that you performed the check.

**Zero-rating cross-border invoices.** Charging 0% VAT on an intra-EU B2B sale depends on the customer's VAT number being valid at the time of supply. This is the check that entitlement rests on, and the consultation number is the evidence.

**Cleaning a customer database.** Registrations get cancelled. Re-running your existing VAT numbers finds the ones that have lapsed since you collected them.

**Validating at signup.** Check the number before the account is created and reject or flag it there, rather than at invoicing time.

**KYB and due diligence.** A valid VAT number with a matching published trader name is a cheap, official corroboration of a company's existence.

***

### Pricing

**$0.005 per number, so $5 per 1,000.** One charge per number that got a real answer from VIES, valid or invalid.

Never charged for `unchecked` or `unparseable` rows, and duplicates are removed before anything runs.

Tier discounts apply automatically on paid Apify plans, down to $3.50 per 1,000.

***

### Speed and rate limits

VIES is a free public service shared by all of Europe and it rate limits accordingly. The default of four checks at a time is deliberately conservative: it is what allows a batch of thousands to finish rather than collapse into rate-limit errors. Transient failures are retried once automatically.

Expect roughly one to two seconds per number. A list of 1,000 takes a few minutes.

***

### Honest limits

**Only EU VAT numbers, plus Northern Ireland.** VIES covers the 27 member states and `XI`. It cannot validate UK (`GB`) VAT numbers post-Brexit, or Swiss, Norwegian or any other non-EU registration.

**Validity is a point in time.** A number valid today can be cancelled tomorrow. Keep the `consultationNumber` and `requestDate`; together they are what evidences the check for the date it was made.

**Name matching is left to you.** Where a country publishes the trader name, this returns it verbatim. It does not fuzzy-match it against a name you supply, because whether "Northwind Ltd" and "NORTHWIND LIMITED" are the same company is a judgment your process should make.

***

### Frequently asked questions

**How do I check if an EU VAT number is valid?**
Paste it in. The answer comes from VIES, the European Commission's official service, so it is the same result you would get from the VIES website, just for a whole list at once and as structured data.

**Can I get the company name from a VAT number?**
Yes, where the issuing member state publishes it. Most do. Germany and Spain do not, and those rows are flagged with `detailsWithheldByCountry`.

**Does this work for UK VAT numbers?**
No. Since Brexit, `GB` numbers are outside VIES. Northern Ireland numbers with the `XI` prefix are covered, and `GB` input is mapped to `XI` on the assumption that is what was meant.

**What is a consultation number?**
A reference VIES issues for a validation request. It is the standard evidence that you verified a customer's VAT number on a given date, which matters if an intra-EU zero-rated sale is ever questioned.

**Why did I get `unchecked` instead of a result?**
A member state's own VAT service was unavailable or rate limited the request. It is not a statement about the number. Re-run those rows later, at no charge for the failed attempt.

**Is there a limit on how many I can check?**
No hard limit here, but VIES is a shared service, so large batches run at a deliberate pace.

**Do you store the VAT numbers I check?**
No. Results go to your dataset in your account.

***

### Works well with

- [Website Lead Extractor](https://apify.com/f0rty7even/website-lead-extractor): pulls VAT and company registration numbers straight off company websites, which this then validates
- [Domain Intelligence](https://apify.com/f0rty7even/domain-intelligence): registrar, DNS and email authentication for the same companies
- [Bulk Email Verifier](https://apify.com/f0rty7even/email-verifier): check their email addresses against DNS

***

### Notes

Queries the official VIES service only. Nothing is sent to the companies themselves.

# Actor input Schema

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

One per line, or comma separated. Any spacing and punctuation is fine, so DE812871812 and DE 812 871 812 are the same number. Include the two-letter country prefix, or set a default country below.

## `defaultCountry` (type: `string`):

Two-letter EU VAT country code, used only for numbers that do not carry their own prefix. Greece is EL, and Northern Ireland is XI.

## `maxNumbers` (type: `integer`):

Hard stop after this many numbers, as a safety net on large inputs. Leave empty to check everything you supplied.

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

VIES is a shared public service that rate limits aggressively. The low default is deliberate and is what lets a large batch finish. Raise it only if you are checking a handful of numbers.

## `proxyConfiguration` (type: `object`):

Proxy used to reach VIES. The default is usually fine; a different IP can help if VIES is rate limiting.

## Actor input object example

```json
{
  "vatNumbers": [
    "DE 812 871 812",
    "FR40303265045"
  ],
  "defaultCountry": "DE",
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `vatChecks` (type: `string`):

One row per VAT number. Export as JSON, JSONL, CSV or Excel.

# 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": [
        "DE812871812",
        "IE6388047V",
        "NL822010929B01"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("f0rty7even/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": [
        "DE812871812",
        "IE6388047V",
        "NL822010929B01",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("f0rty7even/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": [
    "DE812871812",
    "IE6388047V",
    "NL822010929B01"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call f0rty7even/vat-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,f0rty7even/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/TvC8hzegfx2smryqt/builds/BVTCHjfWQZyilTtRY/openapi.json
