Free & Open Source — No API Key Required

EU VAT Rates Data

Rates for 45 European countries — plus VAT number format descriptions and built-in format validation for every country. Checked daily against the European Commission TEDB and updated on any change. MIT licensed — here is how that pipeline works.

45 CountriesMIT LicenseChecked DailyEU-27 + CH · NO · GB · UA…TypeScript TypesVAT Format Validator Built-In

Quick Start

Pick your language and copy-paste to get started.

Install
npm install eu-vat-rates-data
import { getRate, getStandardRate, getAllRates, isEUMember, validateFormat, dataVersion } from 'eu-vat-rates-data'

// Get full record for a country
const fi = getRate('FI')
console.log(fi.standard)       // 25.5
console.log(fi.reduced)        // [10,13.5]
console.log(fi.eu_member)      // true
console.log(fi.vat_abbr)       // 'ALV'
console.log(fi.format)         // 'FI + 8 digits'
console.log(fi.pattern)        // '^FI\d{8}$'

// Shorthand for the standard rate
const de = getStandardRate('DE') // 19

// Iterate all 45 countries
const all = getAllRates()
for (const [code, rate] of Object.entries(all)) {
  console.log(`${code}: ${rate.standard}%`)
}

// VAT number format validation — free, no API key
validateFormat('FI12345678')  // true
validateFormat('INVALID')     // false

// Type guards
isEUMember('NO')        // false — Norway is in dataset but not EU
isEUMember('DE')        // true

// Dataset freshness
console.log(`Rates as of ${dataVersion}`) // 2026-08-13

What's in the Dataset

Each country record contains the following fields.

standardStandard VAT rate in percent (e.g. 25.5)
reducedReduced rates, sorted ascending. Empty array when none.
super_reducedSuper-reduced rate applied to a narrow set of essentials.
parkingTransitional parking rate. Null for most countries.
eu_memberWhether this is an EU-27 member state.
currencyISO 4217 currency code (EUR for eurozone).
vat_nameLocal name of the tax (e.g. 'Arvonlisävero').
vat_abbrShort abbreviation (e.g. 'ALV', 'MwSt', 'TVA').
formatHuman-readable VAT number format (e.g. 'ATU + 8 digits').built in
patternRegex string for VAT number format validation (e.g. '^ATU\\d{8}$').built in
Sample — Finland (FI)
{
  "country": "Finland",
  "currency": "EUR",
  "eu_member": true,
  "vat_name": "Arvonlisävero",
  "vat_abbr": "ALV",
  "standard": 25.5,
  "reduced": [
    10,
    13.5
  ],
  "super_reduced": null,
  "parking": null,
  "format": "FI + 8 digits",
  "pattern": "^FI\\d{8}$"
}

EU VAT Rates 2026

Standard, reduced, and super-reduced rates for all 27 EU member states. Checked daily against the European Commission TEDB and updated on any change. Last confirmed: 13.08.2026.

CountryStandardReducedSuper Reduced
🇦🇹ATAustria20%10%, 13%, 19%4.9%
🇧🇪BEBelgium21%6%, 12%
🇧🇬BGBulgaria20%9%
🇭🇷HRCroatia25%5%, 13%
🇨🇾CYCyprus19%5%, 9%3%
🇨🇿CZCzech Republic21%12%
🇩🇰DKDenmark25%
🇪🇪EEEstonia24%9%, 13%
🇫🇮FIFinland25.5%10%, 13.5%
🇫🇷FRFrance20%0.9%, 1.05%, 5.5%, 8.5%, 10%, 13%2.1%
🇩🇪DEGermany19%7%
🇬🇷GRGreece24%6%, 13%, 17%4%
🇭🇺HUHungary27%5%, 18%
🇮🇪IEIreland23%9%, 13.5%
🇮🇹ITItaly22%5%, 10%4%
🇱🇻LVLatvia21%5%, 12%
🇱🇹LTLithuania21%5%, 12%
🇱🇺LULuxembourg17%8%, 14%3%
🇲🇹MTMalta18%5%, 7%
🇳🇱NLNetherlands21%9%
🇵🇱PLPoland23%5%, 8%8%
🇵🇹PTPortugal23%6%, 13%, 16%, 22%6%
🇷🇴RORomania21%11%
🇸🇰SKSlovakia23%5%, 19%
🇸🇮SISlovenia22%5%, 9.5%
🇪🇸ESSpain21%10%4%
🇸🇪SESweden25%6%, 12%

Checked daily against EC TEDB — the official European Commission tax database — and updated on any change.
Reduced rates include all territorial variants (e.g. French overseas departments, Portuguese Azores).

European VAT Rates 2026 (Non-EU)

Standard and reduced VAT rates for European countries outside the EU — including Norway, Switzerland, United Kingdom, Ukraine, Turkey, and more. Last updated: 13.08.2026.

CountryStandardReducedSuper Reduced
🇦🇱ALAlbania20%6%, 10%
🇦🇩ADAndorra4.5%1%, 2.5%
🇧🇦BABosnia and Herzegovina17%
🇬🇪GEGeorgia18%
🇮🇸ISIceland24%11%
🇽🇰XKKosovo18%8%
🇱🇮LILiechtenstein8.1%2.6%, 3.8%
🇲🇩MDMoldova20%8%
🇲🇨MCMonaco20%5.5%, 10%2.1%
🇲🇪MEMontenegro21%7%, 15%
🇲🇰MKNorth Macedonia18%5%, 10%
🇬🇧XINorthern Ireland20%5%
🇳🇴NONorway25%12%, 15%
🇷🇸RSSerbia20%10%
🇨🇭CHSwitzerland8.1%2.6%, 3.8%
🇹🇷TRTurkey20%1%, 10%
🇺🇦UAUkraine20%7%, 14%
🇬🇧GBUnited Kingdom20%5%

Data sourced from the European Commission TEDB where available, supplemented by official national tax authority sources for non-EU countries.

Built-in validation — regex patterns ship with the rates

VAT Number Formats & Validation

Every country's VAT number follows a different format — FR for France, ATU for Austria, 45 different patterns in total. Keeping those patterns accurate as tax authorities update them is maintenance work that belongs in a package, not your codebase. Every entry in this dataset includes a human-readable format description and a tested regex pattern. The built-in validateFormat() function runs locally — no latency, no rate limits.

import { validateFormat } from 'eu-vat-rates-data'
validateFormat('ATU12345678') // true
validateFormat('DE123456789') // true
validateFormat('INVALID')     // false
CountryFormatPattern
🇦🇱ALAlbania1 letter + 8 digits + 1 letter^[A-Z]\d{8}[A-Z]$
🇦🇩ADAndorra1 letter + 6 digits + 1 letter^[A-Z]\d{6}[A-Z]$
🇦🇹ATAustriaATU + 8 digits^ATU\d{8}$
🇧🇪BEBelgiumBE + 0/1 + 9 digits^BE[01]\d{9}$
🇧🇦BABosnia and Herzegovina12 digits^\d{12}$
🇧🇬BGBulgariaBG + 9–10 digits^BG\d{9,10}$
🇭🇷HRCroatiaHR + 11 digits^HR\d{11}$
🇨🇾CYCyprusCY + 8 digits + 1 letter^CY\d{8}[A-Z]$
🇨🇿CZCzech RepublicCZ + 8–10 digits^CZ\d{8,10}$
🇩🇰DKDenmarkDK + 8 digits^DK\d{8}$
🇪🇪EEEstoniaEE + 9 digits^EE\d{9}$
🇫🇮FIFinlandFI + 8 digits^FI\d{8}$
🇫🇷FRFranceFR + 2 alphanumeric + 9 digits^FR[A-HJ-NP-Z0-9]{2}\d{9}$
🇬🇪GEGeorgia9 digits^\d{9}$
🇩🇪DEGermanyDE + 9 digits^DE\d{9}$
🇬🇷GRGreeceEL + 9 digits^EL\d{9}$
🇭🇺HUHungaryHU + 8 digits^HU\d{8}$
🇮🇸ISIceland5–6 digits^\d{5,6}$
🇮🇪IEIrelandIE + 7 digits + 1–2 letters^IE\d{7}[A-W][A-IW]?$|^IE\d[A-Z+*]\d{5}[A-W]$
🇮🇹ITItalyIT + 11 digits^IT\d{11}$
🇽🇰XKKosovo9 digits^\d{9}$
🇱🇻LVLatviaLV + 11 digits^LV\d{11}$
🇱🇮LILiechtenstein5 digits^\d{5}$
🇱🇹LTLithuaniaLT + 9 or 12 digits^LT(\d{9}|\d{12})$
🇱🇺LULuxembourgLU + 8 digits^LU\d{8}$
🇲🇹MTMaltaMT + 8 digits^MT\d{8}$
🇲🇩MDMoldova7 digits^\d{7}$
🇲🇨MCMonacoFR + 2 alphanumeric + 9 digits^FR[A-HJ-NP-Z0-9]{2}\d{9}$
🇲🇪MEMontenegro8 digits^\d{8}$
🇳🇱NLNetherlandsNL + 9 digits + B + 2 digits^NL\d{9}B\d{2}$
🇲🇰MKNorth MacedoniaMK + 13 digits^MK\d{13}$
🇬🇧XINorthern IrelandXI + 9 digits, 12 digits, or GD/HA + 3 digits^XI(\d{9}|\d{12}|(GD|HA)\d{3})$
🇳🇴NONorway9 digits + MVA^\d{9}MVA$
🇵🇱PLPolandPL + 10 digits^PL\d{10}$
🇵🇹PTPortugalPT + 9 digits^PT\d{9}$
🇷🇴RORomaniaRO + 2–10 digits^RO\d{2,10}$
🇷🇸RSSerbia9 digits^\d{9}$
🇸🇰SKSlovakiaSK + 10 digits^SK\d{10}$
🇸🇮SISloveniaSI + 8 digits^SI\d{8}$
🇪🇸ESSpainES + letter/digit + 7 digits + letter/digit^ES[A-Z0-9]\d{7}[A-Z0-9]$
🇸🇪SESwedenSE + 10 digits + 01^SE\d{10}01$
🇨🇭CHSwitzerlandCHE-NNN.NNN.NNN (+ MWST/TVA/IVA)^CHE-?\d{3}\.?\d{3}\.?\d{3}[ ]?(MWST|TVA|IVA)?$
🇹🇷TRTurkey10 digits^\d{10}$
🇺🇦UAUkraine9 digits^\d{9}$
🇬🇧GBUnited KingdomGB + 9 digits, 12 digits, or GD/HA + 3 digits^GB(\d{9}|\d{12}|GD\d{3}|HA\d{3})$

Note: the "GR" code shown here is the ISO rates code. Greek VAT numbers themselves use the "EL" prefix, not "GR".

Format validation is step 1 of 2

It confirms the number is structured correctly. For production B2B workflows — invoicing, supplier onboarding, checkout tax exemption — you also need to verify the business is currently VAT-registered. The vatnode API checks against the official EU VIES database in real time.

See VIES Validation API

Everything You Need, Nothing You Don't

A self-contained dataset — no network calls, no rate limits, no account.

45 Countries

EU-27 plus Norway, Switzerland, UK, Turkey, Ukraine and 13 more non-EU European countries.

6 Languages

Native packages for JavaScript/TypeScript, Python, PHP, Go, Ruby, and a WordPress plugin.

Checked Daily

A scheduled job compares the data against the EC TEDB every morning. A new package version goes out when a rate actually moves, not on a timer.

TypeScript Types

Full type safety with CountryCode, VatRate, and helper type guards included.

VAT Format Validation

Every country includes a format description and regex pattern. Built-in validateFormat() — free, no API key.

Available Packages

All packages ship the same dataset — pick the one for your stack.

TypeScript

JavaScript / TypeScript

npm install eu-vat-rates-data
Python

Python

pip install eu-vat-rates-data
PHP

PHP

composer require vatnode/eu-vat-rates-data
Go

Go

go get github.com/vatnode/eu-vat-rates-data-go
Ruby

Ruby

gem install eu_vat_rates_data
WordPress / WooCommerce

WordPress / WooCommerce

Canonical dataset repo

Raw JSON data, update scripts, and GitHub Actions workflow for all packages.

vatnode/eu-vat-rates-data

Where the Package Stops

The dataset answers what a rate is. It cannot answer whether a VAT number in front of you belongs to a real, registered business — that check has to reach VIES.

The package, free and offline

  • Standard, reduced, super-reduced and parking rates for 45 countries
  • validateFormat() — does this string look like a VAT number
  • EU membership flag, local VAT name and abbreviation
  • No account, no key, no network call, MIT licensed

What the API adds

  • Live VIES lookup — is this number registered right now
  • Registered company name, address and registration date
  • The VIES consultation number, your reference if the check is ever questioned
  • National registry fallback when VIES is down, plus webhooks on status change

A format check catches typos. It does not catch a number that was valid last quarter and has since been deregistered — which is the case that costs money on a reverse-charge invoice.

Need VAT Number Validation Too?

The vatnode API validates EU VAT numbers against the official VIES database — real-time, with caching and webhook support.