Menu

VAT Number Formats: What Changes Across Countries

A VAT number is a tax registration identifier, and its format is set by each country's tax authority. Here is what varies, and why a format check never proves registration.

Published

  • VAT number
  • tax data
  • test data

A VAT number is the identifier a business uses for value added tax, and it is one of the few fields that appears on almost every cross-border business document. It is also the field where teams most often confuse two entirely different questions: does this look like a valid number, and is this business actually registered for VAT. Getting those two mixed up produces forms that reject real customers and systems that accept invented ones.

This article covers what the number is, why its structure changes at every border, how the public lookup services fit in, and how to design the field so that format checking and registration checking stay in their own lanes.

What is a VAT number?

It is a tax registration identifier. A business that is liable for value added tax registers with the tax authority of the country concerned and is given a number; that number is then quoted on invoices, in returns, and in the cross-border reporting that EU-style systems require.

Two properties follow from that definition. First, the number belongs to a tax administration, not to a companies register, so it is issued under tax law and can exist for an entity registered somewhere else entirely. Second, the number is country-specific by construction: it is issued by one authority under one jurisdiction’s rules, and it means nothing outside that jurisdiction on its own.

It is also not a company registration number, not a tax identification number in the broad sense, and not a licence. A business can hold several of these identifiers at once, and a business that trades purely domestically may never need a VAT number at all.

When does a business actually need one?

More often than you would guess from the field’s reputation, and in a handful of recurring situations.

  • Selling goods or services across a border where the buyer is a business and the tax treatment depends on the buyer’s status.
  • Invoicing a business customer who needs the number on the document to reclaim or account for the tax.
  • Reporting intra-community supplies, where the counterparty’s number is part of the return.
  • Registering in a country where the business has crossed the local threshold for tax registration.
  • Importing and exporting, where the tax authority needs to tie the shipment to a registered trader.

The pattern is that the number matters most precisely when two tax systems meet. That is also why the field is so error-prone: it is filled in by a human reading a document produced under unfamiliar rules, and it is checked by software written under one familiar set of rules.

What varies from country to country?

Almost everything a parser would want to rely on. The structure is set by the issuing tax authority, so the only safe generalisation is a weak one: many formats begin with a two-letter country code and then continue with digits, letters or a mixture.

Beyond that starting observation, the differences are exactly the ones that break strict rules.

Property Why a fixed rule fails
Whether a country prefix is present The same authority may print it in one context and omit it in another
Total length Formats range from short to noticeably long, and no single limit covers all
Letters versus digits Some formats are numeric, others alphanumeric, others contain both blocks
Internal separators Spacing and punctuation are presentation, not part of the identifier
Check digits Some formats embed one, others are plain allocations with no arithmetic

Notice that the prefix is a convenience, not a guarantee. When it is present it tells you which authority issued the number — which is genuinely useful for routing a lookup — but treating it as mandatory will reject perfectly good inputs typed from a document that left it off.

Is a valid format the same as a registered business?

No, and the gap between them is the single most useful thing to understand about this field.

A number can be syntactically perfect and belong to nobody. Someone who understands the pattern can write one that no authority ever issued, and a system that only checks the pattern will accept it. Conversely, a number can be registered and still fail a home-made rule, because the rule was written against a different country or an older printed layout.

This is why the European Commission’s public VAT number checking service matters so much as an example: it exists so that a business can confirm whether a number is actually registered for VAT in a member state, which is a question no pattern can answer. The distinction generalises well beyond that service — wherever a tax authority publishes an official enquiry facility, that facility is the authority, and a regular expression is not.

There is a useful consequence for interface design. When a check fails, the message should say which check failed. “This does not look like a VAT number” and “we could not confirm this number with the tax authority” lead the user to different actions, and conflating them wastes everybody’s time.

Why should teams avoid writing their own rules?

Because the rules are national, revised occasionally, and numerous, and because a home-made validator is a maintenance liability that fails in the least visible direction.

Consider what a self-written rule actually does. It encodes one country’s layout. It is tested against a handful of examples from one or two countries. It reports a single generic error. And when a tax authority changes a layout, nothing announces it — the rule simply starts rejecting real customers, gradually, in the countries nobody on the team trades with. The failure is silent and its cost is borne by the sales team.

The alternative is not “no validation”. It is layered validation, where each layer answers a question it can actually answer, and the authoritative layer is a call to the official service rather than a guess. That architecture also degrades gracefully: if the official service is slow, unreachable, or returns an ambiguous result, the form can still accept the input and mark the confirmation as pending instead of blocking a legitimate customer.

For developers: format checks and register checks are different functions

Split the responsibility into two functions with two different return types, and do not let them share an error message.

The first is a local shape check. It should be deliberately permissive: strip separators, normalise case, reject empty values and characters that cannot appear in any format, and apply a maximum length that is comfortably above the longest real format. If you hold a country-specific pattern and you are confident in its provenance, apply it as a hint that can downgrade a warning, never as a hard rejection of a value you cannot verify. Where a format genuinely carries a check digit, implement it only for the countries where you have verified the algorithm, and treat a failure as “possible typo” rather than “not registered”.

The second is a registration lookup against the official facility. Give it its own timeout, its own retry policy, and its own vocabulary of outcomes: confirmed, not found, unavailable, and not applicable for this country. Cache a positive result for a sensible period and cache a negative one for much less, because a business that registers today should not be rejected for a week by a stale answer. Log which numbers were checked and when, but treat the log as containing business data and protect it accordingly.

Two more habits are worth adopting. Keep the raw value the user typed alongside the normalised one, so that a display or a document can reproduce exactly what the source showed. And keep generated values unmistakably synthetic: the generator on this site fills the VAT number field with formatted values that belong to no tax authority, and every export from it carries a note saying so. The related tax identifier article walks through the same layering for the broader family of tax numbers. Testing all of this against a real product’s form is covered in the billing form test cases article.

Next steps

List every place in your product where a VAT number is validated today and label each check as either shape or registration. Any check that claims to be about existence but is implemented as a pattern is a bug waiting for an international customer. Then run your billing form through the four branches — number present, number absent, cross-border, and individual — using generated data from the company data generator so that nothing you test with can be mistaken for a real business.

Keep reading

Test Company Data Generator guides