Tiered & per-person rates

Tourist taxes are rarely a single flat number. They step up by hotel class or nightly price, and they multiply by guests and nights. This page covers tiered rates and per-person/per-night taxes — including the coarse lever for excluding minors and the precise per-guest path that charges each occupant at its own rate.

Tiered rates

A tiered rate's amount depends on a band — most often the hotel star rating or property class, sometimes the nightly price. A 5★ hotel pays more per person per night than a 2★ one. Tiers are stored on the rate itself; the engine picks the band the booking falls into.

The rate carries a tier_type discriminator that selects the banding logic — one of:

FieldTypeDescription
property_classtier_typeA flat amount keyed by property type / class (and optionally star rating). The dominant live shape.
single_amounttier_typeA flat amount for everything in the matched band, banded by star rating or nightly price.
thresholdtier_typeThe rate changes entirely above a threshold — the band the nightly rate clears wins.
marginal_ratetier_typeA rate applied only to the portion of the base within each band (marginal, like income-tax brackets) — for price-tiered percentage taxes. Supported but rare in the live data.

Within a tier_type, each individual tier is a small object. The fields the engine reads are value (the flat amount) or rate (the percentage), min / max for the band bounds, and star_rating / property_class for the band key.

Tiering by star rating is the Barcelona pattern: the regional Catalan tax and the municipal recargo both step by hotel class, so a 5★ stay draws the top band of each. Pass star_rating (or property_classification) so the engine can land on the right tier.

Tiered by star rating
2★€1.00/ person / night4★€3.00/ person / night5★€4.50/ person / nightbooking'sstar_rating
The same tourist tax charges a different per-person-per-night amount depending on the property's class.

Per-person, per-night

A large class of tourist taxes is a flat cash amount charged per guest per night. The category codes carry the basis right in the name — tourism_flat_person_night, occ_flat_person_night, eco_flat_person_night. The engine multiplies the per-unit amount by the chargeable guests and the number of nights.

amount  =  per_unit  ×  chargeable_guests  ×  nights

e.g. €4.50  ×  2 guests  ×  3 nights  =  €27.00

Adults vs. number_of_guests — the minors lever

Many per-person taxes exempt children. By default the engine charges every occupant: it multiplies by number_of_guests. To exclude minors, pass adults — the chargeable count becomes adults when set, falling back to number_of_guests when it isn't.

FieldTypeDescription
number_of_guestsnumberTotal occupants. Used as the chargeable count when adults is absent (legacy behaviour — everyone charged).
adultsnumberThe chargeable count for per-person taxes when set. A 4-occupant booking with adults: 2 is charged for 2 — the surgical lever for the common minors-exempt case.

So a family of four (two adults, two children under the local exemption age) booking a per-person tourist tax should send number_of_guests: 4 and adults: 2 — the tax then lands on two people, not four.

POST/v1/tax/calculate
Sign in to run

A 5★ Barcelona stay: the tiered per-person tourist tax lands on the top band and charges 2 adults, not 4 occupants.

Request body
{
  "jurisdiction_code": "ES-CT-BCN",
  "stay_date": "2026-07-01",
  "nights": 3,
  "nightly_rate": 200,
  "currency": "EUR",
  "property_type": "hotel",
  "star_rating": 5,
  "number_of_guests": 4,
  "adults": 2
}

Sign in to run this against the live API. Read-only — nothing is saved.

Per-guest evaluation — the precise path

When you know each occupant, send the guests[] array instead of (or alongside) the counts. Each guest is evaluated in its own sub-context and charged at its own resulting rate — by age band, residency, disability percentage, or guest type — and the per-person amounts are summed across the party. An individually-exempt guest (a child under the exemption age, a certified-disabled guest, a resident) simply contributes zero and drops out of the total, rather than being approximated by a count.

FieldTypeDescription
guests[].agenumberThe guest's age, for age-band exemptions and reductions (e.g. children under a local exemption age, senior rates).
guests[].typestringThe guest's type from the canonical vocabulary — resident, disabled, diplomat, student, senior, and so on. Caller-attested; the property verifies eligibility at check-in.
guests[].disability_percentagenumberCertified disability percentage, for threshold exemptions and reductions (e.g. exempt above a stated percentage).
When to use guests[] vs. adults
Use adults when you only know how many occupants are chargeable — it changes the chargeable count for the common minors-exempt case. Use guests[] when you know each occupant and need them charged at their own rate (different age bands, residency, or disability thresholds within one party). Sending guests[] overrides the scalar guest fields and the guest count.

What isn't modeled

Still narrow
Per-commune disability thresholds that differ within a single country, and multi-axis municipal tourist taxes that combine date, zone, and class on one levy, are not yet fully modeled. For the current edges see Limitations.

Where to go next

The category vocabulary (which codes are per-person, per-night, tiered) is in Tax categories. When a per-person tourist tax folds into the VAT base, see VAT base composition. And exemptions or caps on a tiered tax are Rules.