{"id":13492286,"url":"https://github.com/kdeldycke/vat-rates","last_synced_at":"2026-02-11T22:44:10.151Z","repository":{"id":24319402,"uuid":"27715840","full_name":"kdeldycke/vat-rates","owner":"kdeldycke","description":"💸 {Digital,Cloud,Electronic,Online} Services VAT Rate Database","archived":false,"fork":false,"pushed_at":"2025-07-01T07:50:41.000Z","size":97,"stargazers_count":94,"open_issues_count":8,"forks_count":12,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-07-01T08:38:54.940Z","etag":null,"topics":["csv","european-businesses","european-customers","tax","tax-rate","territory","vat","vat-database","vat-number","vat-rule"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kdeldycke.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/funding.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"kdeldycke"}},"created_at":"2014-12-08T13:22:32.000Z","updated_at":"2025-07-01T07:50:45.000Z","dependencies_parsed_at":"2025-04-10T00:31:04.472Z","dependency_job_id":null,"html_url":"https://github.com/kdeldycke/vat-rates","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kdeldycke/vat-rates","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdeldycke%2Fvat-rates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdeldycke%2Fvat-rates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdeldycke%2Fvat-rates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdeldycke%2Fvat-rates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kdeldycke","download_url":"https://codeload.github.com/kdeldycke/vat-rates/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdeldycke%2Fvat-rates/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274095416,"owners_count":25221433,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csv","european-businesses","european-customers","tax","tax-rate","territory","vat","vat-database","vat-number","vat-rule"],"created_at":"2024-07-31T19:01:04.714Z","updated_at":"2026-02-11T22:44:05.111Z","avatar_url":"https://github.com/kdeldycke.png","language":null,"funding_links":["https://github.com/sponsors/kdeldycke"],"categories":["Taxes"],"sub_categories":["Currencies"],"readme":"# 💸 {Digital,Cloud,Electronic,Online} Services VAT Rate Database\n\nSome countries requires businesses to apply, for any sales of online/electronic/digital/cloud services to\nconsumers (B2C), a [value-added tax\n(VAT)](https://en.wikipedia.org/wiki/Value-added_tax) on all purchases made by their citizen. This impose all foreign companies to track the\nresidency of all their customers, to apply the right tax.\n\nThis trend started January 1st 2015 with all European country, and is about to be\nimplemented by others too.\n\nAs the rate depends on the locality of the customer, this project aims to centralize,\nin a machine-readable format (currently a\nplain CSV file), the list of applicable rates for each country of\nresidence, and all their territorial exceptions.\n\nThis is a painful job, worth sharing with a community, so please help me keep this database up to date! :)\n\n\n## Testimonials\n\n\u003e I'm impressed with your BFPO detail.\n-- [Tim Whitlock](https://twitter.com/timwhitlock/status/652464484578144256)\n\n\u003e I'm glad to see independently researched data confirming mine!\n-- [Will Bond](https://twitter.com/wbond/status/560532109304291331)\n\n\n## VAT Application Rules\n\nAll B2C customers matching the locality in that file are subject to the corresponding tax.\n\nYour B2B customers are exempted of VAT, as long as they provide a\nregistered VAT number. You can check their validity on the [VAT Information\nExchange System (VIES)](https://ec.europa.eu/taxation_customs/vies/). I\nrecommend using a third-party library to automate the process, like\n[pyvat](https://github.com/iconfinder/pyvat) for Python. A B2B customer without VAT\nnumber is considered as a simple B2C customer, so local rate applies.\n\nNote that starting January 1st, 2015, these [rules applies to all non-European SaaS\nbusinesses](https://ec.europa.eu/taxation_customs/taxation/vat/how_vat_works/telecom/index_en.htm#new_rules)\nwith European customers.\n\n\n## Status\n\nThis matrix expose the current completeness of the database:\n\nAdministrative family | [EU member states](https://en.wikipedia.org/wiki/Member_state_of_the_European_Union) | [Special territories](https://en.wikipedia.org/wiki/Special_member_state_territories_and_the_European_Union), states, countries, collectivities, islands, departments, towns, …\n:--- |:--- |:---\nNumber | :white_check_mark: 28 / 28 | :white_check_mark: 57 / (?)\nStandard rates | :white_check_mark: All | :white_check_mark: All\nReduced rates | :x: None | :x: None\nIncreased rates | :x: None | :x: None\nParking rates | :x: None | :x: None\nCurrency codes | :white_check_mark: All | :white_check_mark: All\nHistorical standard rates | :white_check_mark: All | :x: None\nHistorical reduced rates | :x: None | :x: None\nHistorical increased rates | :x: None | :x: None\nHistorical parking rates | :x: None | :x: None\nHistorical currency codes | :warning: Wrongly aligned to current one | :warning: Wrongly aligned to current one\n\n\n## Schema\n\n`start_date` is an inclusive [ISO 8601 calendar\ndate](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates) from which the rate\nstarts to apply.\n\n`stop_date` is an inclusive [ISO 8601 calendar\ndate](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates) from which the rate is\nno longer valid.\n\n`territory_codes` is a list of (eventually mixed):\n  * [ISO 3166-1 alpha-2 country\n  codes](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2),\n  * [European Commission country\n  codes](http://publications.europa.eu/code/pdf/370000en.htm#pays),\n  * [ISO 3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2),\n  * [normalized postal\n  code](https://en.wikipedia.org/wiki/Postal_code#Country_code_prefixes) with a\n  leading ISO 3166-1 alpha-2 country codes.\n\n`currency_code` is the [*de jure*](https://en.wikipedia.org/wiki/De_jure)\n[ISO 4217 currency code](https://en.wikipedia.org/wiki/ISO_4217) (a.k.a.\nlegal tender), not *de facto*'s one.\n\n`rate` is the decimal rate.\n\n`rate_type` is the kind of rate. Either:\n  * `standard`\n  * `increased`\n  * `reduced`\n  * `parking`\n\n`description` human-readable description of the territory the rate applies to,\nand eventual rationale behind the application.\n\nRows are sorted by `territory_codes`, then `start_date`.\n\n\n## Interpretation\n\nStarting from this database, your next step is to interpret the data.\n\nBy looking at the dates, you can compute if a rate is either current,\nhistorical or future. Beware, some rates changes in the middle of a month.\nThat means on theory, your billing system should support pro-rata application\nof several rates on a monthly invoice.\n\nTo choose the right rate, you then need to guess the location of your customer.\nI advise you to derive this data from the billing address, as it's the most\ncommon element with the necessary administrative granularity. An address that\nis properly normalized is precise enough, down to the postal code, to select\nthe right VAT rule, including territorial exceptions. To solve the territory\ncomplex, I wrote a [Python module to parse and normalize postal\naddresses](https://github.com/online-labs/postal-address).\n\n\n## Sources\n\nThe process of building up this database is somewhat fuzzy.\n\nThis database is unequivocally founded on the latest [official VAT\nRates](https://ec.europa.eu/taxation_customs/resources/documents/taxation/vat/how_vat_works/rates/vat_rates_en.pdf)\ndocument from the EC portal. It provides all member states' rates and their\nhistorical values. You'll also find there a description of regions and\nterritories where special or no VAT rates applies.\n\nStill, the hardest part of establishing this database lies in the\ncharacterization of locality. Member states and some regions are easy: they\nhave a dedicated country code. For these we rely on [ISO 3166-1\nalpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2), with an extra compatibility\nlayer for [European Commission country\ncodes](http://publications.europa.eu/code/pdf/370000en.htm#pays) (i.e. the `GB`/`UK`\nand `GR`/`EL` pairs).\n\nWhen this is not enough, we go down to a lower administrative level and\nleverage subdivision codes from [ISO\n3166-2](https://en.wikipedia.org/wiki/ISO_3166-2).\n\nThings get messy once VAT rules only applies to areas as small as a town. In\nwhich case I guesstimated the geographic zone with postal codes fetched from\nindividual Wikipedia pages.\n\nFinally, for completeness, I compiled the catalog of [member's states special\nterritories](https://en.wikipedia.org/wiki/Special_member_state_territories_and_the_European_Union#Summary)\nand restarted the locality characterization process for these. I was able to\nadd the missing entries based on the list of included and excluded zones of the\n[EU VAT area](https://en.wikipedia.org/wiki/European_Union_Value_Added_Tax_Area#EU_VAT_area).\n\n\n## Other resources\n\n* [official\ndocumentation](https://ec.europa.eu/taxation_customs/taxation/vat/how_vat_works/index_en.htm)\n* [List of electronically supplied services](https://ec.europa.eu/taxation_customs/sites/taxation/files/resources/documents/common/buying_online/electronically_supplied_services.pdf)\n* [Rachel Andrew's micro-site](https://rachelandrew.github.io/eu-vat/)\n* [Awesome Billing and Payments](https://github.com/kdeldycke/awesome-billing) - 💰 Billing \u0026 Payments Knowledge Base for Cloud Providers.\n\n\n## History\n\nI decided to create this database because all the [current VAT libs were quite\nnaive](https://github.com/kdeldycke/vat-rates/issues/2#issuecomment-67084124)\nabout the territory definition. Most of the time it's only based on the\ncountry, while the territory a tax applies to, in a fiscal context, is a much\nmore insidious concept carrying administrative, political and historical\nweight.\n\nTo match the place the supply takes place against the VAT database, I created a\n[Python module to normalize and parse postal\naddressed](https://github.com/online-labs/postal-address) of my customers.\n\n\n## License\n\nThe content of this repository is licensed under a [BSD 2-Clause\nLicense](./LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkdeldycke%2Fvat-rates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkdeldycke%2Fvat-rates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkdeldycke%2Fvat-rates/lists"}