Sales Tax Isn't a Lookup Table: What Building on Avalara Actually Taught Me
Somewhere in the first design review for the tax service we built at Quince, a PM asked a completely reasonable question: “Can’t we just hardcode the state rates? California is 7.25%, we add the county piece, done.” I understood why it sounded reasonable. It’s also wrong in about four different ways, and every one of those ways turns into a production incident if you skip it.
Sales tax in the US isn’t a rate. It’s the output of three independent decisions — do we even owe tax here, which of the ~12,000 overlapping jurisdictions applies to this specific address, and is this specific product taxable in that jurisdiction — and only after all three are resolved does “calculate the number” become a simple multiplication. Bolt-on tax API integrations tend to treat the API as a rate lookup and get surprised when the number is wrong. It’s not wrong because the API is bad. It’s wrong because the integration only fed it a fraction of what it needed to know.
Nexus is not a fixed rule, it’s 50 separate rules that change
The first mistake is treating “do we owe tax in this state” as a static fact about your business. It isn’t. Since South Dakota v. Wayfair in 2018, states can require you to collect and remit sales tax even with zero physical presence, as long as you cross an economic nexus threshold — a combination of revenue and/or transaction count in that state, on a rolling basis. Avalara defines it plainly: nexus is “the connection between a seller and a state that requires the seller to register then collect and remit sales tax in the state,” and crucially, “their definitions of remote sales and what establishes nexus can vary” state by state.
And they really do vary, not just cosmetically:
- Alabama: $250,000 in sales, no transaction count involved.
- Colorado: $100,000 in sales, also no transaction count.
- Connecticut: $100,000 and 200 transactions — both conditions have to be met.
- New York: $500,000 in sales and 100 transactions.
- Hawaii: $100,000 or 200 transactions — either one trips it.
So the same growing DTC brand can have nexus in Colorado after $100K in sales but not in New York until it also clears 100 orders there, even at a much higher revenue figure. And states keep changing the rules under you — Avalara’s own blog was tracking 16-plus states eliminating the transaction-count leg of their thresholds going into 2026, leaving pure revenue tests behind. If your integration hardcodes “we collect in these 12 states” as a config value someone updates twice a year, you will eventually either fail to collect where you’re legally obligated to, or worse, collect where you no longer need to and create a refund headache. Nexus has to be a maintained, per-state, revenue-and-transaction-aware state machine, not a flag.
This is also the part that’s easy to underinvest in because it feels like a legal/finance problem, not an engineering one. It isn’t. Somebody’s system has to track rolling revenue and transaction counts per state, per year, against thresholds that move, and decide whether to start collecting before finance even notices the number crossed a line.
Jurisdiction resolution: the same street can have two answers
Assume nexus is settled and you owe tax in a state. Now: which of the overlapping city, county, and special district taxes actually applies to this order? This is the part that trips up engineers who assume ZIP code is good enough, because ZIP codes are postal delivery boundaries, not tax jurisdiction boundaries, and the two do not line up.
Avalara’s own developer docs on address validation are explicit that precision matters and isn’t guaranteed uniformly: they note the system “cannot guarantee a specific level of precision for all addresses,” and expose a resolutionQuality field on the response specifically so you can tell whether you got a rooftop-level match or something coarser, like an intersection or a city-level fallback. Their guidance is direct about the fallback path too — “taxing jurisdictions can usually be determined if city, state and zip code are provided” even when a full street-level match fails, but “usually” is doing real work in that sentence. Usually is not always.
Here’s the concrete case that makes this real: two buildings three blocks apart, same ZIP code, one inside a city’s special transit or stadium taxing district and one just outside it. Same product, same order size, same ZIP — different combined rate, because the special district boundary runs down the middle of a street, not along a postal code line. If your integration resolves tax using ZIP-to-rate tables (a common shortcut before anyone plugs in a real tax engine), you will get one of those two addresses wrong, silently, on every order. Rooftop-level geocoding is the thing that actually catches this, which is exactly why Avalara built out proprietary address resolution instead of shipping a ZIP-rate table and calling it done.
Practically, this means your integration needs to actually pass a full street address to the API and check the resolution quality it gets back, rather than treating “address” as an optional nice-to-have field you populate when convenient. A tax engine can only be as precise as the input you hand it.
Product taxability: the same t-shirt is two different products
The third piece, and the one most integrations skip entirely: taxability isn’t just a function of jurisdiction, it’s a function of jurisdiction plus category, and sometimes plus price.
The clothing exemption is the textbook case. In New York, clothing and footwear under $110 per item are exempt from state sales tax; cross that $110 line and the entire price becomes taxable, not just the amount over the threshold. Massachusetts runs it differently: clothing and footwear are exempt up to $175, and above that, tax applies only to the amount over $175 — so a $200 jacket in Massachusetts is taxed on $25, while a $200 jacket in New York is taxed on the full $200. Same product, same price, two states, two completely different calculations, and neither one is “just apply the state rate.”
This is what Avalara’s tax code system exists to solve — every line item you send gets tagged with a TaxCode that puts it into a taxability category (apparel, groceries, digital goods, freight, and so on), and the engine applies the jurisdiction-specific rules for that category rather than a flat rate. If you don’t map your catalog to tax codes and just send everything as generic tangible personal property, you lose every category-specific exemption and threshold rule in every state that has one. For an apparel-heavy catalog that’s not a rounding error, that’s systematically overcharging customers in a chunk of your addressable states.
What an actual tax calculation call needs
Once nexus, jurisdiction, and taxability are handled as real inputs rather than assumptions, the calculation call itself is almost boring — which is the point. Avalara’s transaction-creation endpoint (CreateTransaction) wants, at minimum: a transaction date, ship-from and ship-to addresses (full street address, not just ZIP), a company code identifying which of your registered entities is the seller of record, and a set of line items, each with an item code, a description, an amount, and — this is the field people forget — a TaxCode. Leave TaxCode off and every line defaults to standard tangible personal property, silently discarding any exemption logic tied to category. Freight gets its own line with its own tax code, because whether shipping charges are taxable is itself a jurisdiction-specific rule, not a universal yes or no.
None of those fields are exotic. The point is that all four categories — nexus, jurisdiction, taxability, and the request itself — have to be fed real data, continuously maintained, for the number that comes back to mean anything. The API doesn’t know your nexus footprint unless your system tracks it. It can’t resolve a jurisdiction from a ZIP code alone with full confidence. It can’t apply a clothing exemption to a product you never tagged. “Calculate tax” is the last, easiest step in a pipeline where the first three steps are where the actual engineering work — and the actual bugs — live.
If you’re scoping a tax integration and the plan is “add the API call,” you’ve scoped about a quarter of the problem.
Sources
- Avalara Developer Guide — AvaTax
- Address Validation — Avalara Developer
- Calculating Tax — Avalara Developer
- What is economic nexus? Guide to sales tax nexus rules — Avalara
- State-by-state guide to economic nexus laws — Avalara
- States eliminating economic nexus transaction thresholds in 2025 — Avalara
- How to handle sales tax on clothing: a state-by-state guide — Avalara
- CreateTransaction — AvaTax API Reference