US sales tax for platforms that bill for other businesses.
Dilo is a sales-tax calculation API for marketplaces, vertical SaaS and billing platforms that put tax on their merchants' invoices. One platform key covers every merchant. The API follows Stripe's shapes, and the price is on this site.
curl https://api.learndilo.com/v1/quotes \
-H "Authorization: Bearer sk_test_…" \
-H "Tax-Merchant: mer_8Hq2…" \
-d '{
"currency": "usd",
"tax_date": "2026-11-07",
"addresses": { "ship_to": {
"line1": "1 Main St", "city": "Columbus",
"state": "OH", "postal_code": "43215",
"country": "US" } },
"lines": [{ "id": "li_1",
"product": "ext:prod_saas_pro",
"amount": 50000 }]
}'
# → 200
{ "amount_tax": 4000,
"address": { "confidence": "rooftop" },
"lines": [{ "taxes": [ /* state, county, special */ ] }] }
Your merchants never see us. Your invoices show the right tax.
Most tax engines assume one seller per account. A platform has hundreds or thousands of sellers and calls tax from inside its own checkout and billing code. We built the API around that case.
One key, every merchant
Use one platform key and pick the merchant with a Tax-Merchant header, the way Stripe-Account works. Create merchants through the API as you onboard them.
Quotes are free
Recalculate a cart or a draft invoice as often as you like. We bill only when you commit a transaction, so a quote-heavy checkout doesn't raise your bill.
Stripe IDs work as-is
Commit with an invoice or PaymentIntent ID as your transaction ID. Stripe's address shape, integer cents, and a per-line, per-jurisdiction breakdown that maps onto Stripe's taxes[]. Stripe integration →
Refunds without resending lines
We keep the original transaction. Refund a full invoice, a line, a quantity or an amount. The tax comes from what was charged, not from today's rates.
Corrections that follow state rules
Wrong address or tax code on a past sale? One corrections call recalculates it and records the difference in the right period. It also tells you what you owe the customer.
Your data, in raw form
Liability, nexus and reconciliation reports, plus a line-level export to CSV or Parquet. Build the view your merchants need, or hand it to a filing partner.
The complaints we keep reading, and what we do about each
These come from public reviews of the incumbent tax engines. Each answer below is part of the product design, not an add-on.
| The complaint | How Dilo handles it |
|---|---|
| Annual contracts that auto-renew, with 1-year minimums and no proration. | Monthly terms by default. Annual is an opt-in discount, never a trap. You can cancel yourself, from the dashboard or the API. |
| Pricing behind a demo call, and big jumps at renewal. | Published pricing. Per-transaction rates are on the pricing page. You can see what you'll pay before you talk to anyone. |
| A four-figure overage bill because a plugin update looped on the API. | Hard spend caps. Quotes are free, and only committed transactions count. Set a monthly cap that alerts or blocks commits (quotes keep working). You get alerts at 50, 80 and 100%, and whenever volume jumps past 3× its 7-day average. |
| Address validation so strict it breaks checkout. | Rooftop-level addresses that never break checkout. We resolve addresses with our own address data (Texas and California first), state address files, and a geocoder as fallback. A weak address still gets the best match, with a confidence field and a warning. Strict mode is opt-in. |
| One key per seller, and around 10 requests per second. | Platform keys and platform-scale limits. One key covers all your merchants. Rate limits are set per platform (we're designing for a default of 1,000 req/s), not per seller. |
| Integrations break and fixes are slow. | Date-pinned API versions. Behaviour changes ship as a dated version (Tax-Version), so nothing breaks under you. We run our Stripe connector ourselves, on the same public API you use. |
| Support is hard to reach and can't explain a number. | Answers in every response. Each tax line carries the rule and legal citation behind it, and each response has a request_id we can trace. Engineers handle support for platform accounts. |
Quote, commit, then refund or correct
Quote and commit are separate calls. Commit is idempotent on your own transaction ID, so retries are always safe.
Quote
POST /v1/quotes while the customer is on the cart or the invoice is a draft. It's free, nothing is stored, and the result is deterministic for a given content release.
Commit
POST /v1/transactions when the invoice is finalized or the payment succeeds. Pin the quote's content release so the tax you record is the tax the customer saw.
Refund or correct
Refunds are for goods or service given back. Corrections are for tax that was wrong. Both link to the original and land in the right reporting period.
What's in v1
- Calculation for every US state with a sales tax
- Transaction ledger with versions, voids, refunds and corrections
- Economic nexus tracking per state, with threshold webhooks
- Exemption certificates, checked against each state's rules
- Liability reports and raw exports for your filer
- Stripe Billing connector and Stripe history import
Not in v1: filing and remittance (we give your filing partner or accountant the data they need) and non-US VAT/GST.
Run us next to your current provider
We're looking for 2–3 platforms to shadow-call Dilo alongside their current tax engine and compare the results line by line. Design partners help set the coverage priorities and get engineering support directly.