Check VAT number format by EU country
Check that a VAT number has the right shape for its EU country: «DE 136-695-976» is read as DE136695976 and passes the German pattern. Spaces, dots and hyphens copied from invoices are ignored. It checks the format, not the registration. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- DE 136-695-976
- Normalized
- DE136695976
- Country code
- DE
- Country name
- Germany
- Expected format
- DE123456789
A VAT number can look plausible and still use the wrong structure for its country. This checker reads the two-letter prefix, selects the corresponding EU format, and tests the remaining characters against that country's published pattern. It handles the different lengths and required letters used across the EU, while ignoring ordinary spaces, dots, and hyphens. The result is a fast syntax check, not a confirmation that a business exists or that its VAT registration is currently active.
What a VAT format check can tell you
A format check answers a narrow but useful question: could this string be a VAT number issued under the syntax used by the stated EU country? The country prefix controls the test. German numbers, for example, have a different length from Belgian numbers, while Austrian, Dutch, Irish, Spanish, Cypriot, and French formats may require letters in particular positions.
The checker converts letters to uppercase, removes ordinary spaces, periods, and hyphens, and then applies the matching country rule. A string can therefore pass the structural test and still be mistyped, unassigned, expired, or associated with a different organization. Treat a positive result as permission to continue validation, not as proof of registration or identity.
How to enter country prefixes and separators
Enter the complete VAT number, beginning with its two-letter VAT prefix. Most prefixes match the familiar country code, but Greece uses EL for EU VAT purposes, so a Greek entry must begin with EL rather than GR. The checker recognizes the current 27 EU member-state VAT prefixes and returns an input error when the prefix is unknown.
That distinction matters: a recognized country with a badly shaped number produces a normal result with valid set to false, whereas an unknown prefix means there is no country rule to apply. Spaces, full stops, and hyphens are accepted as visual separators and removed before matching, which makes values copied from invoices easier to use. Other punctuation is retained and will normally make the format invalid.
Do not add labels such as VAT, TVA, or MwSt around the number. Although many formats contain only digits after the prefix, several countries require one or more letters. Preserve those letters; replacing them with digits changes the format and should correctly fail the check.
The normalized value in the response shows exactly which compact string was evaluated.
Format validation versus registration verification
Syntax validation belongs near the start of an intake workflow. It is deterministic, immediate, and does not send the supplied identifier to an external registry. Use it while a person is filling in a billing form, when importing supplier records, or before placing VAT numbers into a queue for a slower authoritative check.
A false result gives you a clear reason to ask for a corrected value before making any network request. A true result only says that the characters occupy allowed positions for that prefix. It does not query VIES, a national tax authority, or a company register, and it cannot establish whether the number was issued, is active for cross-border transactions, or belongs to the named customer.
For tax decisions, invoice zero-rating, or compliance evidence, follow a successful format check with the appropriate official registration verification and retain whatever evidence your process requires. This separation also makes failures easier to understand: local syntax errors can be corrected instantly, while registry outages, unavailable member-state services, and genuine inactive registrations remain part of the later verification stage rather than being confused with formatting mistakes.
What you can do with it
Validate a billing form
Catch an unsupported prefix or a country-specific length error before the customer submits an invoice profile.
Clean supplier data
Normalize separators and identify structurally invalid VAT numbers during a supplier or customer import.
Preflight registry checks
Filter obvious syntax errors locally before sending plausible numbers to an authoritative registration service.
FAQ
Does a valid result prove that the VAT number is registered?
No. It proves only that the number matches the recognized country's character pattern. Use an official registry check to confirm registration status.
Which countries are recognized?
The checker recognizes VAT prefixes for all 27 current EU member states. Greece must use the EU VAT prefix EL.
Can the part after the country prefix contain letters?
Yes. Several official VAT formats require letters in specific positions, and the checker preserves and validates them.
Are spaces and hyphens allowed?
Yes. Spaces, periods, and hyphens are removed before the country pattern is tested, and the compact value is returned as normalized.
Why does a Greek VAT number have to start with EL?
Because Greece uses EL instead of GR for EU VAT purposes. A Greek number entered with GR is treated as an unknown prefix and returns an error, since there is no country rule to apply to it.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/data/vat-number-format-check \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"DE 136 695 976"}'const res = await fetch("https://api.kit.forhosting.com/data/vat-number-format-check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "DE 136 695 976"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/data/vat-number-format-check",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "DE 136 695 976"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/data/vat-number-format-check", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"DE 136 695 976"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"DE 136 695 976"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/data/vat-number-format-check", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "DE 136 695 976"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "data.vat_number_format_check",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
What a VAT format check can tell you
It reports the normalized value, recognized country, expected example format, and a Boolean result. This is ideal for catching missing digits, misplaced letters, an accidental domestic tax number without its international prefix, or a number copied with an incomplete suffix. It deliberately does not calculate or validate country-specific check digits.
Technical questions
What happens with an unknown country prefix?
The request returns an invalid_input error because no country-specific VAT pattern is available for that prefix.
What does the API request cost?
Each API request costs $0.002. The browser version runs locally without a network lookup.