Hotels & hotel groups

You take direct bookings, run one or many properties, and your finance team issues the invoices. This is the end-to-end TaxLens workflow tuned for that: set up once, calculate at booking time, persist the booking, issue an EN 16931 invoice, and report your liability each month.

Why this workflow fits you

As a hotel or hotel group you are almost always the merchant of record for a direct booking: the guest pays you, you collect every tax, and you issue the invoice in your own legal entity's name. That makes you the simplest persona to model — no commission lines, no platform routing — but you carry the full stack of taxes a stay attracts: national VAT plus whatever state, provincial, city, and tourist levies sit above the property.

The two facts that shape everything below are additive stacking (every authority's tax is its own line and they all add up) and the invoice lifecycle (a calculation becomes a persisted booking becomes an immutable fiscal document). Read those two and the rest of this page is just sequencing.

One property or one hundred
The flow is identical whether you run a single boutique hotel or a 200-property group. The difference is purely how you store property defaults — covered in step 2. A group typically registers every property once and lets each booking inherit its tax drivers.

One-time setup

Before your first invoice you configure the two things TaxLens cannot infer: who is legally issuing the invoice, and where each property sits.

  1. 1
    Create your account and pick test vs live
    Set up the account, then decide your environment. Build and validate everything against test mode first — issued test invoices burn a separate fiscal sequence you can throw away. Invite your finance team and set roles: issuing invoices and editing legal entities is org-admin gated.
  2. 2
    Register your legal issuer(s)
    A legal issuer is the seller on the invoice — its name, address, VAT registration, and the fiscal number sequences it owns. A single hotel has one issuer; a group may have one per operating company. The issuer drives the gapless invoice numbering and the issuer-local invoice date, so get its registered details right before you issue anything live.
  3. 3
    Register each property and let TaxLens map it
    Add each property in Properties (or via the API). TaxLens geocodes the address and maps it to a jurisdiction — that mapping is what pulls in the right VAT and city taxes automatically. Set the tax-driver defaults on the property (property type, classification, star rating, tax postal code) and attach the default_legal_issuer_id so bookings inherit the seller. See Register your first property.
Check the mapping before you trust the number
Geocoding occasionally lands a property in the wrong sub-city. Open the property and confirm its mapping_status and resolved jurisdiction path. A property mapped to the country instead of the city silently drops the city occupancy tax. The coverage map and jurisdictions browser let you see exactly which taxes a jurisdiction carries.

Calculate tax at booking time

When a guest books, calculate the tax. If the stay is at a registered property, pass property_id and let it fill the jurisdiction, property type, and issuer defaults — you only supply what's specific to this stay (dates, nightly rate, guests). Otherwise pass a jurisdiction_code directly.

POST/v1/tax/calculate
Sign in to run

A direct hotel booking — the legacy shape, no extra fields needed. Runs read-only against your session.

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

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

The response is a full itemized breakdown: a VAT line on the room, the regional and city tourist-tax lines, the total, the effective rate, and every rule that was evaluated. Each line names the jurisdiction it came from, so finance can see the stack. Run the request above to see the live figures for Barcelona, including how Spain folds its operator-borne tourist tax into the VAT base.

The hotel tax stack — illustrative, room-only VAT
Room (3 × €200)€600Italy VAT (10%) · on the room · recoverable+ €60.00Tourist tax · per guest/night · outside the VAT base+ €18.00** illustrative — your city sets the per-person/night amount
Illustrative only. Where VAT is charged on the room alone (e.g. Italy), the tourist tax sits OUTSIDE the VAT base as a separate guest-borne line. They all stack on the folio.
VAT vs the lodging levies
VAT is the recoverable, invoice-grade tax that lands on the EN 16931 document. Occupancy and tourist taxes are different legal animals — they show in the calculation and on the guest folio but are excluded from the VAT view of the issued invoice (classified as non-VAT, category O). See VAT-only invoicing and tax categories.

Persist the booking, then issue the invoice

A calculation alone isn't a record. Persist it as a booking (the system-of-record line item), then, when the stay is send-ready, issue the invoice — which freezes the EN 16931 projection and burns a gapless fiscal number.

# POST /v1/bookings — persists the calc result as your record of the stay.
# idempotency_key makes a retry safe: a repeat returns the same booking.
curl -X POST https://api.taxlens.getdynamiq.ai/v1/bookings \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "property_id": 41,
    "external_reference": "PMS-2026-00917",
    "idempotency_key": "PMS-2026-00917",
    "calculation": {
      "stay_date": "2026-07-01",
      "nights": 3,
      "nightly_rate": 200,
      "currency": "EUR",
      "number_of_guests": 2,
      "buyer_name": "Acme GmbH",
      "buyer_address": { "city": "Berlin", "country_code": "DE" }
    }
  }'
Issued invoices are immutable; the booking freezes
Once a live invoice (380/389) exists, the booking is frozen — adjust, void, refund, and invoice-details all return 409. Corrections go through a credit note (a 381 that reverses the original and links back to it), not by editing the document. Capture buyer_name and buyer_address before you issue, or set them with invoice-details while the booking is still open. See numbering & immutability.

Prefer to do this by hand for a few properties? The dashboard's Bookings and Invoices screens drive the exact same flow — calculate, save, issue, credit-note — with no code.

Report your liability each month

At period close, pull the invoice tax report. It's a read-only view over your issued fiscal documents — 380/389 invoices add positive lines, 381 credit notes subtract — keyed by issue date, so unissued-but-calculated bookings are correctly excluded.

GET/v1/invoices
Sign in to run

List your issued invoices for the period. The liability summary and CSV export sit alongside it.

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

For the aggregated figures use the liability summary, lines, and CSV export described in Reports (API) and the dashboard's Tax report. Every issued number and credit note is also traceable in the audit log.

Dashboard or API — for hotels

Most hotel groups run a hybrid. A rule of thumb:

  • Booking volume is low or manual (boutique, events team) → operate entirely in the dashboard.
  • Your booking engine or PMS creates the stay → call calculate at checkout and create the booking automatically, then issue from code or let finance issue from the dashboard.
  • High volume, finance-led close → automate calculate + booking + issuance via the API, and use the dashboard purely to inspect, credit-note, and report.

See Dashboard or API for the full comparison, and API authentication to get a key. Selling through channels other than direct? Read Property managers for multi-channel and OTAs & marketplaces for merchant-of-record routing.