01Introduction
A VAT number is the identifier a tax authority assigns to a registered business, and in the EU it is the field that decides how an invoice is taxed. Get it wrong on a cross-border B2B invoice and you can end up owing the VAT you did not charge.
Most teams collect it as a free-text field at checkout or during onboarding, then find out it was wrong at quarter end. This post covers how EU VAT numbers are structured, why format validation and registry lookup are two different jobs, and how ApyHub's VAT Number Validation API handles the first one in a single call.
02What Is a VAT Number?
A VAT number, also called a VAT identification number or VAT ID, is issued by a national tax authority to a business registered for Value Added Tax. It appears on invoices, in tax filings, and in the customer records of anyone selling to businesses in the EU.
Every EU VAT number starts with a two-letter country code, which is the ISO 3166 code for the member state with one exception: Greece uses EL rather than GR. After the country code, each member state defines its own structure.
A few examples of how much the formats differ:
- Netherlands:
NLfollowed by nine digits, thenB, then two digits.NL123456789B01. - Germany:
DEfollowed by nine digits.DE123456789. - Italy:
ITfollowed by eleven digits. - France:
FRfollowed by a two-character key, then nine digits. - Spain:
ESfollowed by a mix of letters and digits depending on the entity type.
Several of these carry check digits, computed with a country-specific algorithm. A Dutch VAT number's digits have to satisfy a weighted checksum. An Italian one uses a Luhn-style scheme. This means a large share of mistyped VAT numbers are mathematically detectable without contacting any registry at all.
03Why Developers Need VAT Number Validation
VAT validation is one of the few data-quality checks with a direct tax consequence.
- Reverse charge on intra-EU B2B sales. When you sell to a VAT-registered business in another member state, the transaction is generally zero-rated and the buyer accounts for the VAT. That treatment depends on the buyer's VAT number being valid. If it is not, the liability can land back on you.
- Invoice generation. A VAT number is a mandatory field on a compliant EU invoice. An invoice with a malformed ID is a document your customer's finance team will send back.
- Checkout tax logic. Ecommerce and SaaS checkouts branch on whether a buyer is a business in the EU. That branch runs on the VAT field.
- Supplier and vendor onboarding. Procurement records collect a VAT number once and reuse it for the life of the relationship. Errors captured at onboarding propagate through every subsequent payment and filing.
- CRM hygiene. Sales teams type VAT numbers into forms. Formatting varies by country, spaces and dots get pasted in, and country prefixes get dropped. The data degrades continuously unless something checks it.
04Common Developer Approaches
1. A single regex for all EU countries
Some teams write one pattern for the whole EU.
- Pros: Fast to write, no dependency.
- Cons: There is no single EU format. A pattern loose enough to accept all 27 member states accepts almost anything, which means it stops being a validation.
2. Per-country regex plus checksum implementations
The thorough version: 27 patterns and the check-digit algorithms that go with them.
- Pros: Genuinely catches most typos, runs locally with no network call.
- Cons: You are now maintaining tax-format logic in your codebase. Formats change, member states adjust rules, and someone has to notice. This is a permanent maintenance cost for a check that is not your product.
3. Querying VIES directly
VIES is the European Commission's VAT Information Exchange System, which queries national registries to confirm whether a VAT number is currently registered.
- Pros: Authoritative. It is the source tax authorities point at, and it can return a consultation reference used as audit evidence.
- Cons: VIES is a proxy to 27 separate national systems, and availability varies by member state. Individual countries go offline. Some throttle heavily. You have to handle a third state beyond valid and invalid: "could not check right now." Building retry, per-country concurrency limits, and caching around it is real engineering work.
4. A format validation API
Send the number, get back whether it is structurally valid.
- Pros: No format logic to maintain, no per-country registry behavior to handle, one integration.
- Cons: Structural validation is not registration status. It tells you the number could exist, not that it does.
That last trade-off matters, so it is worth being precise about which job you are solving.
05Introducing ApyHub's VAT Number Validation API
ApyHub's VAT Number Validation API takes a VAT number in the request body and returns a boolean telling you whether it is structurally valid. It checks the format and the check digits. It does not perform a live registry lookup, and it does not return a company name or address.
That is deliberate, and it is the honest way to describe it. Format validation and registry lookup are two different checks with different costs and different failure modes. The structural check is instant, deterministic, has no external dependency, and catches the mistyped and malformed numbers that make up most bad VAT data. The registry lookup is authoritative but slower, subject to per-country downtime, and unnecessary for a number that cannot possibly be real.
The practical architecture is to run them in that order:
User input
│
├─▶ ApyHub VAT format check ──▶ invalid ──▶ reject at the form, instantly
│
└─▶ valid ──▶ VIES registry lookup ──▶ registered / not registered / unavailable
Most of what users type wrong dies at the first gate, which means fewer calls into a registry that throttles you and fewer users left waiting on a system that is down in one member state.
A request looks like this:
bash
curl --location --request POST 'https://api.apyhub.com/validate/vat' \
--header 'apy-token: APY_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
"vat": "NL123456789B01"
}'
The response is a boolean in data:
json
{
"data": true
}
And for a number that fails the structural check:
json
{
"data": false
}
If you are on Node.js, the same call through the official SDK:
javascript
import { initApyhub, validate } from "apyhub";
initApyhub("YOUR_APY_TOKEN");
const result = await validate.vat({ vat: "NL123456789B01" });
// { data: true }
[VERIFY: the catalog lists this as an EU VAT validator, but the official Node SDK documents the example input as GB123456789, which is a UK number and outside VIES post-Brexit. Worth confirming which non-EU formats are supported before publishing, since it changes how the post should be titled.]
06Benefits of Using ApyHub's VAT Number Validation API
- No per-country format logic in your codebase. The 27 member state patterns and their check-digit algorithms stay outside your repository.
- Deterministic and dependency-free at the point of use. A structural check does not depend on a national registry being reachable, so it does not inherit VIES availability as a failure mode.
- A cheap first gate. Filtering malformed input before a registry call cuts the volume you send into a throttled external system.
- One credential across the catalog. The same
apy-tokenand the same subscription cover IBAN validation, BIC validation, email validation, and everything else in an EU onboarding flow. - Machine-readable certification. Every endpoint publishes structured attributes for data residency, retention, sub-processors, and alignment with GDPR, SOC 2, and ISO 27001. This matters for a field that can be personal data when the registrant is a sole trader.
- MCP-ready by default. An agent handling invoice or onboarding workflows can call the endpoint directly without a hand-written tool definition.
07Use Cases
- SaaS and ecommerce checkout. Validate the VAT field before the buyer submits, so the reverse-charge branch never runs on a malformed ID and the customer gets a form error rather than a wrong invoice.
- Invoice generation. Gate invoice creation on a structurally valid VAT number, which stops non-compliant documents from reaching a customer's finance team.
- Supplier onboarding. Validate at the point of capture in a procurement flow, so the number stored against the vendor is at least well-formed from day one.
- CRM and billing data cleanup. Batch-validate an existing customer table and flag the malformed rows before running a VIES check on the rest, which keeps the registry call volume manageable.
- Agentic finance workflows. An agent processing supplier invoices can check the VAT field as part of its execution flow rather than passing an unverified value downstream.
08Getting Started
- Create a free ApyHub account at apyhub.com. No card required.
- Open workspace settings, go to API Keys, and generate a credential. Save the
apy-tokenvalue, since secrets are generated on the fly and are not stored in plain text. - Test the endpoint in the playground on the VAT Number Validation API page with a number from your own records.
- Call it on blur in your checkout or onboarding form, before submission.
- If you need registration status rather than format, layer a VIES lookup behind this check rather than in front of it.
09Conclusion
VAT validation splits into two questions that are easy to conflate. Is this number well-formed, and is it currently registered. They have different costs, different reliability profiles, and different right answers about where to put them in your stack.
The structural check belongs at the form, where it is instant and always available. Running it there removes most bad VAT data before it reaches an invoice, and it removes 27 countries' worth of format logic from code you have to maintain.
Try the VAT Number Validation API →
10FAQ
What is a VAT number? A VAT number is the identifier a national tax authority assigns to a VAT-registered business. In the EU it starts with a two-letter country code followed by a country-specific sequence of digits and letters.
Does this API check whether a VAT number is registered with VIES? No. It validates structure and check digits, and returns a boolean. For live registration status you need a VIES lookup, which is best run after this check rather than instead of it.
Why not just use a regular expression? Each of the 27 EU member states has its own format, and several carry country-specific check-digit algorithms. Maintaining all of that in your own codebase is ongoing work for a check that is not your product.
What does the API return? A JSON object with a single data field containing true or false.
Does Greece use GR as its VAT prefix? No. Greek VAT numbers use the prefix EL, which is the most common single mistake in hand-rolled EU VAT validation.
Does ApyHub store the VAT numbers I submit? Data handling, retention, and residency for this endpoint are published as machine-readable certification attributes on the service page, alongside GDPR, SOC 2, and ISO 27001 alignment.
11About ApyHub
ApyHub is a curated API catalog and the trusted operational layer for external APIs. The catalog covers 300+ services and 1,000+ endpoints across AI, data processing, documents, video and image editing, validation, and more, all available under a single subscription priced in atoms.
Every endpoint ships with machine-readable certification covering data residency, retention, sub-processors, and standards alignment across GDPR, SOC 2, and ISO 27001. Every endpoint is MCP-ready by default, so AI agents can discover and call it without a wrapper.
ApyHub is headquartered in Amsterdam, with offices in the Netherlands, Greece, and India, and serves 65,000+ developer workspaces every month. There is a free tier and no card is required to start.
Have an API of your own? Become a provider →
