Tax Rules API
The Tax Rules API answers two questions: which tax regions are there, and what are the rates. It only reads. The rates are the same for every tenant and are maintained by Extenda, so there is nothing to create or change through it.
Base URL: https://tax-rules.retailsvc.com/api/v1
Every call needs a Hii Retail access token. The full reference is the Tax Rules API reference.
| To find out… | call | Permission |
|---|---|---|
| which tax regions exist, to set one on a business unit | GET /tax-regions | tax.tax-rule.get-regions |
| the rates, for all countries, one country or one region | GET /tax-rules | tax.tax-rule.get-rules |
Hii Retail services already receive every change as a message, and the tills get the rates from Store Data. The API is for everything else: a back office, an ERP that prices with tax, a tool that checks that each store's region and each item's group make sense.
Tax regions
GET https://tax-rules.retailsvc.com/api/v1/tax-regions
{
"taxRegions": [
{ "countryCode": "ES", "taxRegionId": "ES" },
{ "countryCode": "ES", "taxRegionId": "ES-CN" },
{ "countryCode": "ES", "taxRegionId": "ES-CE" },
{ "countryCode": "ES", "taxRegionId": "ES-ML" },
{ "countryCode": "ES", "taxRegionId": "ES-TE" },
{ "countryCode": "ES", "taxRegionId": "ES-CN-TE" },
...
]
}
Every region and its tax-exempt twin, the one ending in -TE, is
in the list. A taxRegionId from here is what goes on a business unit.
Tax rates
GET https://tax-rules.retailsvc.com/api/v1/tax-rules?countryCode=FI
| Query parameter | |
|---|---|
countryCode | one country, as its two-letter ISO code in capitals: FI, not fi. Leave it out for every country. |
taxRegionId | one region, such as PT-MA. It can be used with or without countryCode. |
isActive | true, the default: only the rate that applies today. false: every rate. See below. |
The answer has one entry for each rule, with the rate that applies today:
{
"taxRules": [
{
"id": "FI_Reduced_2026",
"countryCode": "FI",
"taxRegionId": "FI",
"taxableGroupId": "Reduced",
"rate": 13.5,
"validFrom": "2026-01-01T00:00:00.000Z"
},
{
"id": "FI-TE_Reduced",
"countryCode": "FI",
"taxRegionId": "FI-TE",
"taxableGroupId": "Reduced",
"rate": 0,
"validFrom": "2018-08-09T00:00:00.000Z"
},
...
]
}
| Field | Means |
|---|---|
taxRegionId + taxableGroupId | the store's region and the item's group: together they pick the rule |
rate | the percentage. 25 is 25 %. |
validFrom | the date the rate applies from, at midnight UTC |
id | the id of this rate, not of the rule: FI_Reduced_2026 and FI_Reduced_2018 are two rates of one rule. It changes when the rate changes. Key on taxRegionId + taxableGroupId to find a rule, and use id to tell its rates apart. |
fiscalTaxGroupId | the code a fiscal signing integration needs, in countries that have one. See Fiscal tax groups. |
countryCode | the region's country |
Where the country has exemptions, an exemptions list follows, with id
(such as NonEU), countryCode, taxRegionId and validFrom. An exemption is always 0 %, so it has no rate.
⚠ exemptions is left out when there are none, as for Finland above. Treat a missing list as empty.
⚠ An unknown country gives an empty answer, not an error. countryCode=XX returns {"taxRules": []}. Check that
a region you expect is in GET /tax-regions before concluding that it has no rates.
Current rate or the whole list
isActive=true, the default, gives one entry per rule: the rate that applies today. A rule whose only rate is
announced for a later date is left out until that date.
isActive=false gives one entry per rate: the old ones, the current one and any announced for later. This is
what a system that taxes sales needs, because a sale is taxed at the rate of its own date:
- a till that keeps the rates can switch at midnight on the day a new rate applies, without calling the API that night
- a return, a correction or a sale registered late uses the rate from the original sale's date
- a rate announced in advance can be loaded before its date. See A rate announced in advance is sent before it applies.
To choose a rate from the whole list: take the rates of the rule, drop those whose validFrom is after the sale's
date, and use the one with the latest validFrom.
⚠ "Today" is the date in UTC. With isActive=true, a rate from 2026-01-01 is returned from 00:00 UTC, which
is 02:00 in Helsinki. A system taxing sales in the first hours of a new rate's day, or west of UTC, should use
isActive=false and choose by its own local date.
Tenant aliases
If your company has aliases for taxable groups, the answer has each
aliased rule twice: once with the global group id and once with your alias as taxableGroupId, at the same rate.
The alias also replaces the group's name in the rate's id. Other companies never see your aliases.
A system that counts or lists rules should expect the extra entries. A system that looks up one rate by group finds it under either id.