SFOLN

Catalogue / Compliance & public records

EU VAT Number Validator (VIES)

sfoln/vat-number-validator · Automation, Developer tools, AI

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.

About

What it does

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.

Price

Price per delivered record

EventPricePer 1,000Charged for
VAT number check
vat-check
$0.002$2 / 1,000One VAT number checked against VIES with a definitive answer (valid or invalid).

Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.

Run

Call it from code, an agent or the Console

curl · synchronous run, rows in the response
curl -X POST "https://api.apify.com/v2/actors/sfoln~vat-number-validator/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"vatNumbers":["NL004495445B01"]}'
mcp.json · hosted Apify MCP server
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/vat-number-validator"
    }
  }
}
asynchronous run · for large batches
POST https://api.apify.com/v2/actors/sfoln~vat-number-validator/runs?maxTotalChargeUsd=1
GET  https://api.apify.com/v2/actor-runs/{runId}            # until status is SUCCEEDED
GET  https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json

Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: Check whether the EU VAT numbers NL004495445B01 and FR27552032534 are valid and return the registered company names.

Input

Input fields

EU VAT numbers to validate against VIES. Each number produces one dataset record.

FieldTypeDefaultMeaning
vatNumbersarray—VAT numbers
EU VAT numbers with their country prefix, one per line (e.g. NL004495445B01, FR27552032534, DE123456789); spaces, dots and dashes are ignored. Accounts on the Apify free plan can process up to 10 VAT numbers per run.
requesterVatNumberstring—Your VAT number (for consultation numbers)
Optional: your own EU VAT number. VIES then returns a consultation number for each check, which tax authorities accept as proof that you verified the number.
defaultCountrystring—Default country prefix
Optional: the prefix (e.g. DE) for numbers given without one. Greece is EL, Northern Ireland XI.
maxItemsinteger10000Max VAT numbers
Safety cap on VAT numbers per run; further numbers are ignored and counted in the OUTPUT record. Range 1–100000.
concurrencyinteger2Concurrency
Checks in parallel. VIES limits concurrent requests per member state; busy answers are retried. Range 1–4.
includeRawbooleanfalseInclude raw VIES response
Attach the unmodified VIES answer under raw.
Example input
{
  "vatNumbers": [
    "NL004495445B01"
  ]
}

Output

One record per input item

Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.

FieldTypeMeaning
inputstring | objectInput
The VAT number as given.
statusstringStatus
ok | error | skipped_invalid | skipped_budget | skipped_free_plan | skipped_unmetered e.g. "ok"
chargedbooleanCharged
Whether this record incurred a pay-per-event charge.
chargedEventstringCharged event
Pay-per-event event charged for this record (present only when charged).
chargedCountintegerEvents charged
Events actually charged when the charge came back short of the requested count (present only then; a warning explains it).
sourcestringSource
Upstream data source.
fetchedAtstringFetched at
ISO timestamp.
errorobjectError
{ code, message, provider?, status? } when status is not ok. Codes set by the runtime: budget_exhausted, free_plan_limit, unmetered, aborted, charge_failed, record_too_large, invalid_record, dataset_push_failed; this Actor: invalid_format, vies_ms_unavailable, vies_timeout, vies_service_unavailable, vies_ms_max_concurrent_req, vies_global_max_concurrent_req, vies_invalid_input, vies_vat_blocked, vies_ip_blocked; upstream: rate_limit, timeout, network, server, client, invalid_response.
warningsarrayWarnings
Notes about this record, e.g. a requester VAT number VIES rejected.
vatNumberstringVAT number
Normalised VAT number: prefix + number, no separators (Greece EL).
countryCodestring | nullCountry prefix
VIES member-state prefix.
countryNamestring | nullCountry
Member state name.
numberstringNational number
The number without its prefix.
formatValidbooleanFormat valid
The number has the member state's VAT format.
validboolean | nullValid
VIES answer: true (registered for intra-EU trade), false (not valid), null (no answer: see error).
namestring | nullRegistered name
Trader name from VIES (null when the member state does not share it).
addressstring | nullRegistered address
Trader address from VIES, lines joined with commas (null when not shared).
requestDatestring | nullRequest date
When VIES answered (ISO).
consultationNumberstring | nullConsultation number
VIES consultation number (requestIdentifier), issued when requesterVatNumber is set.
requesterVatNumberstring | nullRequester VAT number
Your VAT number as sent to VIES.
rawobjectRaw VIES answer
Unmodified VIES response (only with includeRaw).
Example record
[
  {
    "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."
    }
  }
]

FAQ

Questions

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.

Machine-readable

This page for agents