Quickstart
pip install taxqlfrom taxql import TaxQL
client = TaxQL(api_key="your-key-here")
response = client.lookup( state="tx", address="123 Barton Creek Lane", city="Frisco", zip="75068",)
print(f"Rate: {response.combined_rate * 100:.2f}%")print(f"Resolved to: {response.resolved_place.name}")# Rate: 6.50%# Resolved to: Denton County (unincorporated)
# Warnings tell you when other providers would be wrong:for warning in response.warnings: print(warning)What just happened
Section titled “What just happened”The client.lookup() call returned a TaxResponse for the address.
The SDK convenience property .combined_rate returns the total
applicable sales tax rate (6.5% in this case) by reading the single
row in the response.
The interesting bit: the customer-supplied city was “Frisco,” but the actual jurisdiction at that address is unincorporated Denton County (rate: 6.5% — county only, no city tax). Providers that trust customer-supplied city names would return ~8.25% here. TaxQL surfaces the mismatch as a warning so you know.
Multi-row responses
Section titled “Multi-row responses”A 5-digit ZIP can overlap multiple jurisdictions; address-mode in
states with stacked Special Purpose Districts can also surface
multiple candidates. The SDK returns rows[] so you can see every
candidate, and .combined_rate raises AmbiguousLookupError when
there’s more than one row — by design:
from taxql import TaxQL, AmbiguousLookupError
response = client.lookup(state="wa", zip="98039")
try: rate = response.combined_rateexcept AmbiguousLookupError: print(f"{response.row_count} candidates:") for row in response.rows: print(f" {row.location:30s} {row.combined_total_rate * 100:.4f}%")The pattern: ZIP-mode is for “I don’t have the full address” cases; address-mode is the precise answer. See the Python SDK reference for the full multi-row pattern.
Other input modes
Section titled “Other input modes”from datetime import date
# Location name (DoR-published place name — fast, no geocoding)client.lookup(state="wa", location="Seattle")
# ZIP only (lower confidence; may return multiple rows)client.lookup(state="ca", zip="94110")
# Lat/lng (rooftop precision where polygon data exists)client.lookup(state="nm", lat=35.6870, lng=-105.9378)
# Historical query (rate in effect on a past date)client.lookup(state="wa", zip="98039", as_of=date(2026, 4, 15))Raw HTTP equivalent
Section titled “Raw HTTP equivalent”curl -H "X-API-Key: your-key-here" \ "https://api.taxql.com/v1/tax/tx?address=123%20Barton%20Creek%20Lane&city=Frisco&zip=75068"Next steps
Section titled “Next steps”- Authentication — key management
- API Reference — every endpoint
- Python SDK — sync + async, retries, error handling
- Guides — when to use each input mode