Skip to main content

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…callPermission
which tax regions exist, to set one on a business unitGET /tax-regionstax.tax-rule.get-regions
the rates, for all countries, one country or one regionGET /tax-rulestax.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
countryCodeone country, as its two-letter ISO code in capitals: FI, not fi. Leave it out for every country.
taxRegionIdone region, such as PT-MA. It can be used with or without countryCode.
isActivetrue, 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"
},
...
]
}

Reading one entry of a Tax Rules API response. taxRegionId FI is where the store is, taxableGroupId Reduced is the kind of goods, rate 13.5 means 13.5 percent, and validFrom 2026-01-01 is the day it applies from. The id FI_Reduced_2026 names this one rate, not the rule: the earlier rate of the same rule is FI_Reduced_2018.

FieldMeans
taxRegionId + taxableGroupIdthe store's region and the item's group: together they pick the rule
ratethe percentage. 25 is 25 %.
validFromthe date the rate applies from, at midnight UTC
idthe 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.
fiscalTaxGroupIdthe code a fiscal signing integration needs, in countries that have one. See Fiscal tax groups.
countryCodethe 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.