EU & UK VAT number validator
Paste a list of VAT numbers, or a whole page, and check each one's country prefix, format and checksum. Covers all 27 EU member states plus GB and XI (Northern Ireland).
Nothing yet. Paste numbers or a page on the left, or load the sample.
Runs entirely in your browser. A passing check means the number is well-formed, not that it is registered or active. Categories are inferred from the number format.
What gets checked
- The two-letter prefix selects the country rules (Greece uses EL, not GR; Northern Ireland uses XI).
- Format is checked for every country. Checksums are verified for DE, ES, FR, IT, BE, PL, PT and GB/XI; other countries get a format-only result, labelled as such.
- Spanish VAT numbers also show the legal form encoded in the CIF letter.
- Extraction mode looks for numbers next to labels such as VAT, TVA, IVA, USt-IdNr., BTW or NIP.
To confirm a number is registered and active, use EU VIES. The European Commission's VIES service confirms whether an EU VAT number is active. UK numbers are checked with HMRC.
What the prefix tells you
| DE, FR, IT, ES, BE, PL, PT, GB | Format plus checksum |
| Other EU prefixes | Format only |
| XI | Northern Ireland trader (post-Brexit) |
| GBGD / GBHA | UK government department / health authority |
Run the same checks in your own code
import re
def de_ok(n: str) -> bool: # ISO 7064 MOD 11,10
product = 10
for d in n[:8]:
s = (int(d) + product) % 10 or 10
product = (2 * s) % 11
return (11 - product) % 10 == int(n[8])
def gb_ok(n: str) -> bool: # mod 97 with the 9755 variant
total = sum(int(d) * w for d, w in zip(n[:7], range(8, 1, -1))) + int(n[7:9])
return total % 97 == 0 or (total + 55) % 97 == 0
def validate_vat(raw: str) -> bool:
v = re.sub(r"[\s.-]", "", raw.upper())
cc, rest = v[:2], v[2:]
if cc == "DE": return bool(re.fullmatch(r"[1-9]\d{8}", rest)) and de_ok(rest)
if cc in ("GB", "XI"): return bool(re.fullmatch(r"\d{9}(\d{3})?", rest)) and gb_ok(rest)
raise ValueError("add the rule for " + cc)
print(validate_vat("DE 136 695 976"), validate_vat("GB980780684")) # True TrueCollect the numbers from company websites
A browser can't fetch other sites for you. Irmu fetches the page, handles rendering and blocking, and ai_query (+5 credits) returns the fields you ask for.
# Fetch a company's legal page with Irmu and let ai_query pull the IDs out,
# then validate them locally with the functions above.
import os, requests
resp = requests.get(
"https://app.irmu.com/api/crawl",
headers={"Authorization": f"Bearer {os.environ['IRMU_API_KEY']}"},
params={
"url": "https://example.com/legal",
"js": "true",
"ai_query": "List every VAT number on this page with the company name next to it. Return JSON: [{company, vat}].",
},
timeout=120,
)
resp.raise_for_status()
print(resp.json()["data"])Build a verified company database
Fetch legal pages at scale with one API. 200 free credits every month, no card required.