Troubleshooting

Symptom, cause, fix. Find your symptom, confirm the likely cause, apply the fix. Each entry links to the deeper reference.

Zero (or missing) tax returned

The calculation succeeded but the total tax is 0 or the breakdown is empty. The engine found no matching rate, or every rate was exempted. Work through these in order:

  1. 1
    Check the jurisdiction actually resolved
    Confirm the response's jurisdiction is the one you expected. If you passed lat/lng, geocoding may have landed on a parent or neighbouring jurisdiction. Pass an explicit jurisdiction_code to rule this out, or see geocoding misses below.
  2. 2
    Confirm the place is modeled at that level
    A country may be modeled without every city broken out. Check the jurisdictions browser or Coverage for what's attached at each level of the chain.
  3. 3
    Check the stay date
    Rates are time-aware. A stay date before a rate's start or after its end means the rate doesn't apply. Try a date inside the rate's active window.
  4. 4
    Read the evaluated rules
    The response lists every rule it evaluated and whether each one applied, exempted, or was skipped. If a rule exempted the tax (long-stay exemption, B2B reverse charge, bare FR rental), zero is correct — not a gap.

Geocoding miss or low confidence

You passed coordinates or an address and the resolved jurisdiction is wrong, too coarse, or flagged low-confidence.

  • Cause: the geocoder returned a partial or ambiguous result, or the address is near a boundary, or an alias for the place isn't mapped.
  • Fix: pass an explicit jurisdiction_code when you know it — that bypasses geocoding entirely and is the most reliable path. For managed inventory, set the property's jurisdiction mapping once so every booking inherits it (see your first property and Properties). To debug an address directly, use address validation.
Detail
Failed lookups are not cached, so a transient geocoder outage won't poison a location permanently — retrying later can succeed.

Jurisdiction not found

A call returns a not-found for a jurisdiction code.

  • Cause: the code is mistyped, uses the wrong separator, or names a level that isn't modeled. Codes are hierarchical and dash-separated (US-NY-NYC, ES-CT-BCN).
  • Fix: look the code up in the jurisdictions browser, or list children of the parent to find the exact code. Calculating against the nearest modeled ancestor still returns that ancestor's taxes.

422 on the UBL or issue endpoint

You tried to render UBL or issue an invoice and got a 422.

  • Cause: the document isn't send-ready — a mandatory Business Term is missing (buyer name/address, an issuer/tax registration, or another required field). The pre-check is the single source of truth for send-readiness and blocks the document rather than emit something non-compliant.
  • Fix: read the validation block in the 422 (it names the missing terms), then supply them — capture buyer_name/buyer_address on the calculation, or set them later via edit-invoice-details, and attach a legal issuer. The full checklist is in Send-readiness.

409 on adjust, void, or refund

An adjust, void, or refund call returns 409 Conflict.

  • Cause: the booking is frozen because a live invoice (380 or 389) has been issued against it. Issued invoices are immutable, so the booking behind them can't be mutated.
  • Fix: don't edit the booking — issue a credit note (381) to reverse the original, which references its number and frees void/refund/edit-invoice-details on the booking. You can't re-issue the same document type on the credited booking (it still 409s); to bill a corrected amount, create a new booking and issue against it. See Numbering & immutability.

409 on booking creation (idempotency)

A booking POST returns 409 even though no obvious duplicate exists.

  • Cause: you reused an idempotency_key with a different request body. A retry with the same key and same body returns the original booking; the same key with changed facts is a conflict on purpose, so a typo can't silently overwrite a prior booking.
  • Fix: use a fresh idempotency key for a genuinely new booking, or resend the exact original body to fetch the existing one. See Errors & idempotency.

Tax is present but the amount looks wrong

A tax fired but the number is higher or lower than you expected.

  • Too high / double-counted: remember taxes stack additively — a state and a city tax are two lines that sum. Check the breakdown's per-component jurisdictions before assuming a duplicate. See Additive stacking.
  • Per-person tax too high: per-person taxes multiply by guest count. To exclude minors, pass adults. See Tiered & per-person.
  • VAT base looks off: in some jurisdictions VAT is charged on the room plus an operator-levied tourist tax. That's intentional — see VAT base.
  • Star-tiered tax fell to a floor: a booking with no star rating routes a star-banded tax to a conservative floor band. Pass star_rating for the exact tier.
Tip
The fastest way to diagnose any amount is the evaluated-rules list in the response — it shows exactly which rates and rules contributed. Reproduce the case in the live calculator and read it line by line.