EU VAT Number Validator (VIES)
Pricing
from $2.00 / 1,000 vat number checks
EU VAT Number Validator (VIES)
Validate EU VAT numbers live against the European Commission's VIES service: valid or invalid, the registered company name and address where the member state shares them, and an official consultation number when you add your own VAT number. $2 per 1,000 checks; outages are free.
Pricing
from $2.00 / 1,000 vat number checks
Rating
0.0
(0)
Developer
SFOLN LLC
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
EU VAT Number Validator (VIES) checks EU VAT numbers live against the European Commission's VIES service and returns one record per number: valid or invalid, the registered company name and address where the member state shares them, and an official consultation number when you add your own VAT number. Every number is first checked against its country's format, so typos are caught without a request. Built for invoicing and checkout flows, supplier and customer onboarding, CRM clean-up and AI agents. $0.002 per checked number; member-state outages are reported as errors and never charged.
- What you get:
valid,name,address,requestDate,consultationNumber(withrequesterVatNumber), plus the normalisedvatNumber,countryCode,countryNameandformatValid. - All of VIES: the 27 EU member states and Northern Ireland (XI); Greece uses the prefix EL (GR is accepted and converted).
- Honest answers: a member state that is down or busy is retried, then returned as
status: "error"with the VIES code (for examplevies_ms_unavailable), never as invalid. - Price: $0.002 per definitive answer (
vat-check), valid or invalid; malformed numbers and outages are free. - Works everywhere: API, MCP for AI agents, Make, Zapier, n8n, schedules and webhooks.
Input
| Field | Type | Default | Description |
|---|---|---|---|
vatNumbers | string[] | – | EU VAT numbers with their country prefix, one per line (e.g. NL004495445B01, FR27552032534). Spaces, dots and dashes are ignored; a line may hold several numbers separated by commas or semicolons. The same number written twice, in any format, is checked once. |
requesterVatNumber | string | – | Your own EU VAT number. VIES then returns a consultation number for each check, a proof of when you verified the number. |
defaultCountry | string | – | Prefix (e.g. DE) for numbers given without one. Greece is EL, Northern Ireland XI. |
maxItems | integer | 10000 | Safety cap on VAT numbers per run (up to 100,000); further numbers are ignored and counted as inputItemsDropped in the OUTPUT record. |
concurrency | integer | 2 | Checks in parallel (1–4). VIES limits concurrent requests per member state; busy answers are retried. |
includeRaw | boolean | false | Attach the unmodified VIES answer under raw. |
{"vatNumbers": ["NL004495445B01", "FR27552032534", "DE123456789"],"requesterVatNumber": "NL004495445B01"}
Output
One dataset record per VAT number:
[{"input": "NL004495445B01","status": "ok","charged": true,"chargedEvent": "vat-check","source": "vies","fetchedAt": "2026-10-14T23:17:03.404Z","vatNumber": "NL004495445B01","countryCode": "NL","countryName": "Netherlands","number": "004495445B01","formatValid": true,"valid": true,"name": "OPENJONGERENVERENIGING DE KOORNBEURS","address": "VOLDERSGRACHT 00001, 2611ET DELFT","requestDate": "2026-10-14T23:17:03.575Z","consultationNumber": null,"requesterVatNumber": null},{"input": "DE123456789","status": "ok","charged": true,"chargedEvent": "vat-check","source": "vies","fetchedAt": "2026-10-14T23:17:03.249Z","vatNumber": "DE123456789","countryCode": "DE","countryName": "Germany","number": "123456789","formatValid": true,"valid": false,"name": null,"address": null,"requestDate": "2026-10-14T23:17:03.411Z","consultationNumber": null,"requesterVatNumber": null},{"input": "DE12345","status": "skipped_invalid","charged": false,"source": "vies","fetchedAt": "2026-10-14T23:17:03.406Z","vatNumber": "DE12345","countryCode": "DE","countryName": "Germany","number": "12345","formatValid": false,"valid": false,"error": { "code": "invalid_format", "message": "Germany VAT numbers look like DE123456789; \"DE12345\" does not." }}]
| Field | Description |
|---|---|
valid | true or false as answered by VIES; null when VIES gave no answer (status: "error"). |
name / address | The registered trader's name and address, when the member state shares them (Germany, for example, does not). |
consultationNumber | VIES request identifier, returned when requesterVatNumber is set; requesterVatNumber shows the requester used. |
formatValid | Whether the number matches its country's VAT format; malformed numbers are not sent to VIES. |
status is one of:
ok: VIES answered valid or invalid (charged);error: no definitive answer: the member state is unavailable or busy (vies_ms_unavailable,vies_ms_max_concurrent_req…), a timeout, or VIES rejected the request (not charged);skipped_invalid: the number does not match its country's format, or has no EU prefix (not charged);skipped_budget: your Maximum cost per run was reached (not charged);skipped_free_plan: beyond the free-plan limit below (not charged);skipped_unmetered: the run is not pay-per-event (not charged).
Pricing
Pay-per-event. You are charged only for definitive answers:
| Event | Price | When |
|---|---|---|
vat-check | $0.002 | once per VAT number VIES answered as valid or invalid (status: "ok") |
Checking 1,000 VAT numbers costs $2. Set Maximum cost per run on the run to cap spend; the Actor stops cleanly (records marked skipped_budget) when the cap is reached. Accounts on the Apify free plan can process up to 10 VAT numbers per run; further numbers are returned with status: "skipped_free_plan" and are not charged. Upgrade to any paid Apify plan for full batches.
Use with AI agents (MCP)
Use this Actor from Claude, ChatGPT, Cursor, VS Code or any other MCP client through the Apify MCP server. Add this server URL to your client and sign in with your Apify account when asked:
https://mcp.apify.com?tools=sfoln/vat-number-validator
To run the MCP server locally instead, start npx -y @apify/actors-mcp-server --tools sfoln/vat-number-validator with your APIFY_TOKEN in the environment.
Example prompt:
Check whether the EU VAT numbers NL004495445B01 and FR27552032534 are valid and return the registered company names.
Runs started by an agent are billed like any other run (see Pricing). Agents can cap what a run may spend with maxTotalChargeUsd.
API usage
Run the Actor and get its dataset items in one call (the call waits up to 5 minutes for the run to finish):
curl -X POST "https://api.apify.com/v2/acts/sfoln~vat-number-validator/run-sync-get-dataset-items" \-H "Authorization: Bearer <APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"vatNumbers": ["NL004495445B01"]}'
For large inputs, start the run asynchronously and download the dataset when it has finished:
# 1. Start a run: the response holds the run ID (data.id) and its dataset ID (data.defaultDatasetId)curl -X POST "https://api.apify.com/v2/acts/sfoln~vat-number-validator/runs" \-H "Authorization: Bearer <APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"vatNumbers": ["NL004495445B01"]}'# 2. Repeat until data.status is SUCCEEDED (each call waits up to 60 s)curl "https://api.apify.com/v2/actor-runs/<runId>?waitForFinish=60" -H "Authorization: Bearer <APIFY_TOKEN>"# 3. Download the results (format=json, csv or xlsx)curl "https://api.apify.com/v2/datasets/<defaultDatasetId>/items?format=json" -H "Authorization: Bearer <APIFY_TOKEN>"
Python (apify-client):
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("sfoln/vat-number-validator").call(run_input={"vatNumbers": ["NL004495445B01"]})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
Instead of polling, you can attach a webhook to the run (see Integrations). The API tab of this page shows the same calls for JavaScript and the Apify CLI.
Integrations
- Make, Zapier and n8n: run
sfoln/vat-number-validatorwith the Apify app (in n8n, the Apify node) and pass the dataset items to the next step of your workflow. - Google Sheets: add the items to a sheet with the Google Sheets step of Make, Zapier or n8n, or download them as CSV or Excel from the run's Storage tab or the API (
format=csvorformat=xlsx). - Webhooks: get a POST request when a run succeeds or fails: add a webhook in the Actor's Integrations tab, or pass
webhookswhen you start a run through the API. - Schedules: run it hourly, daily or weekly with the same input from Apify Schedules; every run keeps its results in its own dataset.
- More: Slack, Google Drive, GitHub, LangChain, LlamaIndex and other Apify integrations.
Related Actors
- KYB Company Check – Registry, LEI, VAT
- LEI Lookup – GLEIF Legal Entity Search
- Sanctions Screening – OFAC, EU, UK, UN Lists
- Website Contact Details Scraper
- Domain WHOIS & DNS Lookup
See all our Actors on Apify Store.
FAQ
How much does it cost, and am I charged for failed items?
You pay per event at the prices under Pricing above, plus a run start fee of $0.00005 per GB of memory, with no subscription; platform usage is included. Errors and skipped items (skipped_… statuses) are never charged; a lookup that finds nothing is charged only where Pricing says so, and every record's charged field shows whether it was billed. Set Maximum cost per run to cap what a single run can spend.
How fresh is the data?
Each run queries its source while it runs, so you get what the source returns at that moment. Source-specific details, such as how often a provider refreshes its own database, are under Limits & notes.
What are the limits?
Per-run caps (for example the maximum number of items) are listed under Input, source limits under Limits & notes, and the free-plan limit under Pricing. For big batches, start the run asynchronously (see API usage) and read the dataset when it has finished.
Can I schedule runs or get results by webhook?
Yes. Create a schedule in Apify Console to run it hourly, daily or weekly with the same input, and add a webhook to get a POST request when a run finishes (see Integrations).
What does this Actor record about my runs?
This Actor records operational metrics about each run (item counts, duration, charges, error codes and a pseudonymous hash of your Apify user ID) to monitor reliability and costs. It never stores your input or results.
What happens when a member state's VIES service is down?
VIES answers MS_UNAVAILABLE (often during night-time maintenance). The Actor retries, then returns the number with status error and code vies_ms_unavailable. It is never reported as invalid and never charged; run it again later.
Why are name and address empty for some valid numbers?
Some member states (Germany, for example) do not share trader details through VIES; the number is still confirmed valid.
What is a consultation number?
When you set your own VAT number as the requester, VIES issues a consultation number (requestIdentifier) per check that proves when you verified your customer's number.
How do I get help?
Open an issue in the Actor's Issues tab and include the link to the run, so we can reproduce the problem. Feature requests are welcome there too.
Limits & notes
- VIES relays each check to the member state's own VAT database. Some states are offline for maintenance at night or at weekends (VIES answers
MS_UNAVAILABLE); those numbers come back aserrorand can be checked again later at no extra cost. - VIES limits concurrent requests per member state, so busy states are retried with back-off and a batch for one country takes a few seconds per number at worst. Keep
concurrencyat 2 for large single-country batches. - If VIES rejects your
requesterVatNumber, the check is repeated without it and the record has a warning (no consultation number). - Non-EU VAT numbers (UK GB, Norway, Switzerland) are not in VIES and are returned as
skipped_invalid.