Batch & address validation
Calculate many stays in one call, and turn a free-text address into a jurisdiction code you can calculate against.
Batch calculate
POST /v1/tax/calculate/batch takes an array of calculation requests — each one the same shape as single calculate — and returns one result per item, calculated independently. It's the right tool for comparing jurisdictions side by side or processing a backlog of bookings without one HTTP round-trip each.
| Field | Type | Description |
|---|---|---|
| calculations[]required | list | Array of TaxCalculationRequest objects. Each item is independent — one item failing doesn't fail the batch; its result carries an error instead. |
curl -X POST https://api.taxlens.getdynamiq.ai/v1/tax/calculate/batch \
-H "X-API-Key: $TAXLENS_KEY" \
-H "Content-Type: application/json" \
-d '{
"calculations": [
{
"jurisdiction_code": "ES-CT-BCN",
"stay_date": "2026-06-15",
"nightly_rate": 180,
"currency": "EUR",
"nights": 2,
"property_type": "hotel"
},
{
"jurisdiction_code": "CA-ON-TOR",
"stay_date": "2026-06-15",
"nightly_rate": 220,
"currency": "CAD",
"nights": 2,
"property_type": "hotel"
}
]
}'{
"results": [
{
"id": "0",
"total_tax": "51.40",
"effective_rate": "0.1427777777777777777777777778",
"components": [ /* … same component shape as single calculate … */ ],
"error": null
},
{
"id": "1",
"total_tax": "99.46",
"effective_rate": "0.2260454545454545454545454545",
"components": [ /* … */ ],
"error": null
}
]
}id is the item's index as a string ("0", "1" …), so you can line responses back up with the request order. A per-item error is non-null only when that one stay couldn't be calculated.merchant_of_record — the engine returns the right collection split for each. See Channels & merchant of record.Validate an address
When you have a street address but no jurisdiction_code or coordinates, use POST /v1/addresses/validate. It forward-geocodes the text, resolves the closest TaxLens jurisdiction, and returns coordinates, the matched jurisdiction, its ancestor chain, and a confidence band. The resulting code feeds straight into calculate or a property.
| Field | Type | Description |
|---|---|---|
| addressrequired | string | Free-text address (3–500 chars). More specific resolves higher confidence — '350 5th Ave, New York, NY' beats 'New York'. |
| country_hint | string | ISO 3166-1 alpha-2 code (US, HR …). Biases the geocoder toward that country to avoid ambiguity (Paris, France vs Paris, Texas). |
curl -X POST https://api.taxlens.getdynamiq.ai/v1/addresses/validate \
-H "X-API-Key: $TAXLENS_KEY" \
-H "Content-Type: application/json" \
-d '{
"address": "350 5th Ave, New York, NY 10118",
"country_hint": "US"
}'{
"normalized_address": "Empire State Building, 350, 5th Avenue, Manhattan, New York, 10118, United States",
"lat": 40.748432,
"lng": -73.985656,
"country_code": "US",
"city": "New York",
"jurisdiction": {
"code": "US-NY-NYC",
"name": "New York City",
"jurisdiction_type": "city",
"path": "US.NY.NYC"
},
"ancestors": [
{ "code": "US", "name": "United States", "jurisdiction_type": "country", "path": "US" },
{ "code": "US-NY", "name": "New York", "jurisdiction_type": "state", "path": "US.NY" }
],
"confidence": "high"
}confidence (high / medium / low) before trusting a resolved code for a tax-bearing booking, and prefer passing country_hint. An address that can't be geocoded at all returns 422. There is no separate autocomplete/search endpoint today — this is the one address endpoint.Try it live
Resolve a Manhattan address to its TaxLens jurisdiction.
{
"address": "350 5th Ave, New York, NY 10118",
"country_hint": "US"
}Sign in to run this against the live API. Read-only — nothing is saved.
Once you have a code, head to Calculate tax, or store the address as a reusable record in Properties.