VIES VAT Checker icon

Developer tools

VIES VAT Checker — Bulk VAT Number Validation

Bulk VAT number validation against the official, keyless VIES REST API — one row back per number, with a clear skip reason for anything that doesn't check out, so a finance or compliance team can run a VAT number validation API job against a whole customer list in one go.

Free Apify credit covers a first run. No credit card to try.

What this Actor scrapes

A customer hands us a list of VAT numbers — glued, spaced, or structured pairs, mixed together — and we return one row per number: validity, the registered company name and address where the member state discloses it, and a clear skip reason for anything we can't parse or that VIES can't complete. Think of it as a VIES VAT checker and EU VAT validator in one: built for a recurring compliance/onboarding batch job running VAT number validation against a customer list, not a one-off lookup — the product optimizes for cheap, high-volume, fault-isolated throughput. One bad entry in a 5,000-row batch never fails the run — it lands as its own explained row and everything else still ships.

What we handle for you

  • 🧾 Any input shape, one clean pair — glued (DE811907980), spaced (DE 811907980), or structured ({"country":"DE","number":"811907980"}) all normalize to the same (country, number) before we ever call VIES.
  • 🧱 Bounded, polite concurrency — VIES is a shared EC service that throttles hard under load, so we cap in-flight requests and back off automatically on 429/5xx instead of hammering it.
  • Clean negatives are not errors — an invalid VAT number is a normal, useful answer. Every entry — valid, cleanly invalid, or unparseable — lands as its own row with a clear status, so one bad number never fails your whole batch.
  • 🕵️ Optional service-status pre-flight — turn on checkServiceStatus to see which member states are down before you burn a run against unavailable infrastructure.
  • 🧊 Typed, validated dataset rows — Pydantic-checked, one row per requested number, every time — the row count you get back always matches the row count you sent in.
  • 💰 Pay-Per-Event pricing — priced for volume, not per-lookup margin. You always know what a batch costs before you run it.

Use cases

  • Customer onboarding — validate a new B2B customer's VAT number before invoicing them without VAT.
  • Recurring compliance sweeps — re-validate an entire customer list on a schedule to catch deregistered numbers.
  • Invoice/AR cleanup — batch-check VAT numbers on file before a VAT audit.
  • CRM/ERP enrichment — attach the registered company name and address VIES discloses to existing records.

Input

Paste this into the Apify Console, or send it as the run input over the API. Proxy settings are on by default; you rarely need to touch them.

FieldTypeRequiredWhat it does
vatNumbers array yes VAT numbers to validate, one per list item. Each item is either a glued string ("DE811907980"), a spaced string ("DE 811907980"), or a structured object ({"country": "DE", "number": "811907980"}).
checkServiceStatus boolean no If enabled, calls the VIES check-status endpoint once at the start of the run and surfaces any member-state outage before processing entries.
maxConcurrency integer no Cap on concurrent requests to VIES. Kept low by design — VIES is a shared public EC service that rejects excessive parallel load.
{
  "vatNumbers": [
    "DE811907980",
    "IE 6388047V",
    {
      "country": "NL",
      "number": "810462215B01"
    }
  ],
  "checkServiceStatus": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}

Output

One row per result, schema-validated before it is written. Export JSON, CSV, Excel or XML from the run, or read it over the API.

countryCodevatNumberisValidnameaddressrequestDateskippedskipReason

{
  "countryCode": "IE",
  "vatNumber": "6388047V",
  "isValid": true,
  "name": "GOOGLE IRELAND LIMITED",
  "address": null,
  "requestDate": "2026-09-06+02:00",
  "skipped": false,
  "skipReason": null
}

Pricing

EventPriceWhen
Actor start$0.20Once per run, covers warm-up and proxy session setup.
VAT number checked$0.0010Per result written to the dataset.

You pay only for results that land. Cap any run with maxTotalChargeUsd. See pricing & billing for worked examples.

Limitations

  • VIES covers EU member states only — no UK post-Brexit, Norwegian, or Swiss tax-ID formats.
  • Some member states (confirmed: DE, ES) never return a registered company name or address by policy — those fields come back null for those countries even on a valid VAT number, not a scraping gap.
  • Concurrency is capped at 5 requests in flight by design — VIES is a shared public EC service and rejects excessive parallel load.
  • No caching or dedup of previously-seen VAT numbers across runs — every run re-checks every number you send.

FAQ

Why do some rows have a null name and address even though the VAT number is valid?
A handful of EU member states (Germany and Spain, confirmed) never disclose the registered company name or address through VIES, by that country's own policy — we normalize their internal '---' placeholder to null so it's clear this is a policy limit, not missing data.
Is an invalid VAT number a failed run?
No. A VAT number VIES reports as invalid is a normal, useful answer — the run still succeeds, and that row simply says isValid: false.
What happens if one VAT number in my batch is malformed?
It lands as its own row with skipped: true and a human-readable skipReason explaining why — the rest of your batch is processed normally.
Can I check if VIES itself is having an outage before I run a large batch?
Yes — enable checkServiceStatus and we call VIES's own status endpoint once at the start of the run and surface any member-state outage.

Ready to run it?

Open the listing on Apify, paste the input above, and watch rows land. If it ever breaks, it is our problem before it is yours.

Related Actors

Teams that run this also run