Accurate European VAT rates, automatically updated from official sources. JSON + packages for JavaScript, Python, PHP, Go and Ruby. Covers 45 European jurisdictions: every EU member state plus 18 non-EU jurisdictions.
EU rates come from the European Commission Taxes in Europe Database (TEDB). The source is checked daily; normalized, validated data is published automatically. See the methodology, rate history, and VAT Rates website.
https://cdn.jsdelivr.net/gh/vatnode/eu-vat-rates-data@main/data/eu-vat-rates-data.json
const response = await fetch(
'https://cdn.jsdelivr.net/gh/vatnode/eu-vat-rates-data@main/data/eu-vat-rates-data.json'
)
const { rates } = await response.json()
console.log(rates.DE.standard) // 19
console.log(rates.FI.reduced) // [10, 13.5]jsDelivr is the recommended cached CDN endpoint. Raw GitHub serves the file directly from the latest commit and is useful when GitHub origin semantics are preferred over CDN caching.
For reproducible builds, replace @main with a commit SHA. Package users should pin a package version or lockfile.
npm install eu-vat-rates-dataimport { getRate, getStandardRate, validateFormat } from 'eu-vat-rates-data'
getStandardRate('DE') // 19
getRate('FI')?.reduced // [10, 13.5]
validateFormat('DE123456789') // true: format only, not VIES statuspip install eu-vat-rates-datafrom eu_vat_rates_data import get_rate, get_standard_rate, validate_format
get_standard_rate("DE") # 19.0
get_rate("FI")["reduced"] # [10.0, 13.5]
validate_format("DE123456789") # True: format only, not VIES statuscomposer require vatnode/eu-vat-rates-datause vatnode\EuVatRates\EuVatRates;
EuVatRates::getStandardRate('DE'); // 19.0
EuVatRates::getRate('FI')['reduced']; // [10.0, 13.5]
EuVatRates::validateFormat('DE123456789'); // true: format onlygo get github.com/vatnode/eu-vat-rates-data-gopackage main
import (
"fmt"
euvatrates "github.com/vatnode/eu-vat-rates-data-go"
)
func main() {
standard, _ := euvatrates.GetStandardRate("DE")
fi, _ := euvatrates.GetRate("FI")
fmt.Println(standard, fi.Reduced)
fmt.Println(euvatrates.ValidateFormat("DE123456789")) // format only
}gem install eu_vat_rates_datarequire "eu_vat_rates_data"
EuVatRatesData.get_standard_rate("DE") # 19.0
EuVatRatesData.get_rate("FI")["reduced"] # [10.0, 13.5]
EuVatRatesData.valid_format?("DE123456789") # true: format onlyUsing this dataset in production or an open-source project? A GitHub star helps other developers discover it.
| Ecosystem | Package | Install | Repository / registry |
|---|---|---|---|
| Direct JSON | eu-vat-rates-data.json |
No install | CDN · repository |
| JavaScript / TypeScript | eu-vat-rates-data |
npm install eu-vat-rates-data |
repository · npm |
| Python | eu-vat-rates-data |
pip install eu-vat-rates-data |
repository · PyPI |
| PHP | vatnode/eu-vat-rates-data |
composer require vatnode/eu-vat-rates-data |
repository · Packagist |
| Go | github.com/vatnode/eu-vat-rates-data-go |
go get github.com/vatnode/eu-vat-rates-data-go |
repository · pkg.go.dev |
| Ruby | eu_vat_rates_data |
gem install eu_vat_rates_data |
repository · RubyGems |
All packages bundle a snapshot for offline use. The canonical repository for source data, schema, provenance, and history is this repository.
The dataset is available in six distribution formats: direct JSON plus five language ecosystems. Public package and CDN request statistics are recorded weekly in stats/downloads.csv. CDN requests are HTTP requests, not unique users.
jsDelivr publishes usage statistics for the GitHub CDN endpoint. This repository records weekly and monthly request totals automatically so developers do not need to use the stats API directly. Use @main for automatically refreshed data or a commit SHA for reproducible builds.
The machine-readable contract is schema/eu-vat-rates-data.schema.json.
interface VatRate {
country: string
currency: string // ISO 4217
eu_member: boolean
vat_name: string
vat_abbr: string
standard: number // percentage points, e.g. 25.5
reduced: number[] // sorted ascending; [] when none
super_reduced: number | null
parking: number | null
format: string // human-readable VAT ID format
pattern: string // regex format check
identifiers: {
registry_authority_name: LocalizedName | null // who keeps the company register
registry_name: LocalizedName | null // the register itself
registry_code_name: LocalizedName | null // the number an entity gets in that register
tax_id_name: LocalizedName | null // the business tax identification number
vat_id_name: LocalizedName | null // the VAT identification number
}
}
// keyed by ISO 639-1 language: every official language, plus "en"
type LocalizedName = Record<string, string>identifiers holds names, never numbers, in every official language plus English. For Switzerland registry_code_name reads Unternehmens-Identifikationsnummer, numéro d'identification des entreprises, numero d'identificazione delle imprese and Unique Enterprise Identification Number. Where two concepts share one number (Danish CVR, Finnish Y-tunnus) the name repeats. Each name was checked against the registrar's or tax authority's own pages or legal text; null means no official name could be confirmed. The names are hand-curated in scripts/identifiers.json, not taken from TEDB.
Top-level version is an ISO date, source names the primary source, and rates is keyed by country code. Codes use ISO 3166-1 alpha-2 where available; Greece is stored as GR although VAT IDs use the EU prefix EL. XI identifies Northern Ireland for VAT purposes and XK is the user-assigned code used for Kosovo.
Fields documented by the current schema are stable. The registry packages currently use date-based versions for data releases; an ordinary rate update does not change the schema. Removing a field or changing its meaning is breaking and must not ship as an ordinary date release: it requires a documented migration and a coordinated opt-in compatibility boundary across packages. Adding an optional field is non-breaking; package types are updated with the data release.
- Current-data commit history shows every published snapshot.
data/eu-vat-rates-history.jsoncontains EU-27 standard-rate periods back to 1967, including effective dates and source identifiers.- GitHub Releases summarize meaningful rate changes. Daily checks with no rate change do not create releases.
CHANGELOG.mdrecords schema, pipeline, and correction changes rather than duplicating generated rate history.
The history dataset covers standard rates only. Reduced, super-reduced, and parking rate history is not currently published.
- EU-27: European Commission TEDB is the primary current-data source and is checked daily at 07:00 UTC.
- Non-EU jurisdictions: maintained manually from national sources, with official sources preferred and required for new corrections. Per-entry source URLs are not yet embedded in the current dataset; treat that as a provenance limitation.
- Normalization: TEDB's
ELcode is normalized toGR; numeric rates, rate types, currencies, membership, and VAT-number format metadata use one stable shape. - Validation: CI checks the JSON structure, country counts and codes, rate ranges, regex syntax, sorted reduced rates, and history continuity before publication.
- Publication: data is committed automatically after a successful source check. Language packages publish only when actual rate values change.
No dataset can decide which VAT treatment applies to a transaction. Product or service category, customer status, location, place-of-supply rules, exemptions, and effective dates may change the result. The format helpers check only the shape of a VAT number; they do not confirm registration through VIES. This dataset is for software integration and is not tax or legal advice.
Full methodology and limitations: vatnode.dev/data.
EU-27: AT BE BG CY CZ DE DK EE ES FI FR GR HR HU IE IT LT LU LV MT NL PL PT RO SE SI SK
Non-EU and special VAT jurisdictions: AD AL BA CH GB GE IS LI MC MD ME MK NO RS TR UA XI XK
| Capability | VATNode dataset | Hand-maintained constants | Runtime tax API |
|---|---|---|---|
| Automatic official-source checks | Yes, daily for EU-27 | Depends on maintainer | Provider-dependent |
| Direct JSON | Yes | Sometimes | Usually no |
| Offline use | Yes | Yes | No |
| Standard + reduced rate types | Yes | Implementation-dependent | Provider-dependent |
| Standard-rate history | Yes, EU-27 | Rarely | Provider-dependent |
| TypeScript types | Yes, npm package | Implementation-dependent | SDK-dependent |
| Five language packages | Yes | Usually separate projects | SDK-dependent |
This compares distribution approaches, not named competitors; capabilities of individual projects and services vary.
Found an incorrect rate or missing jurisdiction? Read CONTRIBUTING.md and open the matching issue template with the country, rate type, effective date, claimed value, and official source URL. Do not edit generated JSON directly.
For vulnerability reports and the support boundary, see SECURITY.md.