API reference

One call gives the sales tax rate at a US street address, split into the state, county, city and district taxes that make it up. Every answer comes from the state's own published data; when that can't place an address in one rate, the API refuses with the reason instead of guessing.

Base URLhttps://api.opentaxrate.com
AuthAuthorization: Bearer <key> or x-api-key: <key>. Create keys in the dashboard; lookups are paid from your credit (pricing), 120 a minute per key.
Without a keyFree, 10 lookups a minute and 300 a day per IP address. Addresses are placed only by the geocoders we host (Pelias and Photon, built from open address data). When neither can place one, the API answers only if its whole ZIP has one rate, and declines otherwise.
With a keyThe same data and rules, plus commercial geocoders as further witnesses, so fewer addresses are declined or answered from the ZIP alone.
RatesDecimals: 0.1055 is 10.55%.
OpenAPI/v1/openapi.json, for generating a client or importing into Postman.

GET /v1/rate

The rate at an address on a given day.

Sent from this page without a key, limited per IP address.

Request

curl "https://api.opentaxrate.com/v1/rate?address=1410+E+Pine+St%2C+Seattle%2C+WA+98122" \
  -H "Authorization: Bearer otr_live_..."

Parameters

Give the address one of two ways. Both answer the same; with both, the fields win over the line.

GET /v1/rate?address=1410+E+Pine+St,+Seattle,+WA+98122
GET /v1/rate?state=WA&street=1410+E+Pine+St&city=Seattle&zip=98122
NameDescription
As one line
addressThe whole address: 1410 E Pine St, Seattle, WA 98122. Commas are optional; the state can be a code or its name; the ZIP is optional. A line that can't be read is a 400 saying what's missing.
Or as fields
stateTwo-letter state code. Required without address.
streetHouse number and street, e.g. 1410 E Pine St.
cityCity name.
zipFive digits or ZIP+4. Recommended in either form: without it the address is geocoded, and a few more are refused.
Either way
dateYYYY-MM-DD; today when absent.
codeWhat was sold, one or more taxability codes separated by commas: food.catering,food.grocery. Adds taxability, one entry per code. An unknown code is a 400 listing the valid ones.
includetrace adds placement evidence; regions adds regional data. Combine as trace,regions.

Response

{
  "state": "WA",
  "rate": 0.1055,
  "stateRate": 0.065,
  "localRate": 0.0405,
  "byType": {
    "general": 0.1055,
    "generalInterstate": 0.1055,
    "foodDrug": 0.1055,
    "foodDrugInterstate": 0.1055
  },
  "parts": [
    { "kind": "state", "name": "Washington", "code": "45:53", "rate": 0.065, "ids": {} },
    { "kind": "city", "name": "Seattle", "code": "01:63000", "rate": 0.0405, "ids": {} }
  ],
  "match": "street",
  "locationCode": "53-000-63000",
  "jurisdictions": "settled",
  "alternatives": [],
  "locationIds": { "Composite SER Code": "01726", "Location Code": "1726" },
  "zip4": "98109-4607",
  "source": "Streamlined Sales Tax files WAB2026Q4AUG27 + WAR2026Q4AUG27, street match on 2026-10-22",
  "reporting": {
    "agency": { "name": "Washington Department of Revenue", "url": "https://dor.wa.gov/..." },
    "form": "Combined Excise Tax Return",
    "notes": []
  }
}
FieldDescription
rateThe combined rate on a general sale. With code, each sale's own rate is in taxability.
stateRate, localRateThe state's part, and everything else.
byTypeRates on interstate and food-and-drug sales; null where the state publishes none.
partsEach tax adding up to rate: kind (state, county, city, district), name, code (the publisher's type and code, e.g. 01:63000), rate, byType, and ids.
matchHow the address was placed: statewide, street, zip4, zip5, map (geocoded into outlines), zip_area (the whole ZIP has one rate) or authority (the state's own lookup).
locationCodeOur identifier for the combination of taxes. Not a filing code.
jurisdictions, alternativesWhether parts name the jurisdictions the tax is paid to. The rate is settled either way; uncertain where the address could be in another combination of jurisdictions with the same total, each listed in alternatives as { locationCode, parts }, or the state's own lookup gave one local part for every local tax.
locationIds, parts[].idsThe state's own codes, as published. See State codes and filing.
zip4The address's ZIP+4 where a Streamlined state's files give it; else null.
sourceThe files or service the rate came from, and the date.
reportingThe agency, return, and any local filing. See Reporting.
taxabilityWith code: how each code asked is taxed here, keyed by the code. See Taxability.
regionsWith include=regions. See Regional data.

Taxability

Name what was sold with code and the answer says whether that sale is taxed at the address on the date, at what rate, and the government page that says so. The general rate and parts don't change. Rules are researched for Washington, New York, California and every Canadian province and territory; everywhere else, and any code without a rule there, answers not_researched. See Taxability codes for the codes and what each covers.

GET /v1/rate?address=488+14th+St,+Brooklyn,+NY+11215&date=2026-10-08&code=food.catering,food.grocery
{
  "state": "NY",
  "rate": 0.08875,
  "parts": [
    { "kind": "state", "name": "New York", "code": "45:36", "rate": 0.04, "ids": {} },
    { "kind": "county", "name": "Kings", "code": "00:047", "rate": 0.04875, "ids": {} }
  ],
  ...
  "taxability": {
    "food.catering": {
      "treatment": "taxable",
      "rate": 0.08875,
      "taxes": [
        {
          "tax": "NY",
          "parts": ["45:36", "00:047"],
          "treatment": "taxable",
          "rate": 0.08875,
          "rule": {
            "summary": "A caterer's entire charge for a customer's event is taxable, including food, beverages, staff, rentals, room charges and service charges, even when separately stated.",
            "from": "2019-04-08",
            "fromIs": "earliest_verified",
            "treatment": "taxable",
            "conditions": [],
            "citations": [
              {
                "title": "TB-ST-110 (issued April 8, 2019)",
                "url": "https://www.tax.ny.gov/pubs_and_bulls/tg_bulletins/st/caterers_and_catering_services.htm"
              }
            ]
          }
        }
      ]
    },
    "food.grocery": {
      "treatment": "not_taxed",
      "rate": 0,
      "taxes": [
        {
          "tax": "NY",
          "parts": ["45:36", "00:047"],
          "treatment": "exempt",
          "rate": 0,
          "rule": { "summary": "Unprepared food for home consumption sold by food stores is exempt from state and local sales tax under Tax Law §1115(a)(1).", ... }
        }
      ]
    }
  }
}

Read each entry in three lines. When rate is null, never charge the general rate instead.

const t = answer.taxability[code];
if (t.rate !== null) charge(amount * t.rate);          // taxable, partial, not_taxed
else if (t.treatment === 'conditional') ask(t.taxes);  // show each rule's conditions; a person picks
else sendElsewhere();                                   // not_researched: never use the general rate
FieldDescription
treatmentThe sale as a whole: taxable (every part at its rate), partial (some parts, or a reduced rate), not_taxed (no part), conditional (it turns on facts the code doesn't fix) or not_researched (a part has no researched rule for this code on this date).
rateThe combined rate to charge on this sale; null exactly when conditional or not_researched.
taxes[].taxWhat the rule covers: a state (every part there), CA:GST/HST, a province's HST change (ON/CA:HST), a provincial tax (BC:PST), or * for a nontaxable line.
taxes[].partsThe codes of the answer's parts this rule decides; together the entries cover every part once.
taxes[].treatmentThe legal treatment: taxable, exempt, zero_rated, conditional, not_a_sale or not_researched. Exempt and zero-rated both mean no tax, but a Canadian return reports them on different lines.
taxes[].rateWhat these parts add to the sale's rate; null when conditional or not researched.
taxes[].ruleThe rule that decided them; null only when not researched.
rule.from, rule.to, rule.fromIsThe days the rule answers for; no to means still in force. effective: from is the day it took effect. earliest_verified: it's likely older, but earlier dates aren't researched and answer not_researched.
rule.summary, rule.treatmentThe rule in one sentence, and what it decides.
rule.conditionsFor a conditional rule, each fact the outcome turns on: { when, treatment, rate? }. For a settled one, exceptions worth knowing.
rule.citationsThe official pages the rule was read from: title, url, and sometimes a quote.

Errors

{ "error": "This address is within 12 m of a city line ...", "code": "ADDRESS_NEEDS_CONFIRMATION" }
StatusCodeMeaning
400BAD_REQUESTA parameter failed validation, or address couldn't be read; the message says what's missing.
401INVALID_API_KEYThe key isn't one we issued.
402NO_CREDITSThe key's credit doesn't cover the lookup.
422ADDRESS_NEEDS_CONFIRMATIONThe data can't place the address in one rate; the message says why.
422UNSUPPORTED_STATENo rates for this state yet.
429RATE_LIMITED, KEY_LIMITEDToo many lookups; wait the Retry-After seconds.
502UPSTREAM_UNAVAILABLEA state's data isn't loaded, or its service is down.
504UPSTREAM_TIMEOUTA state's service timed out.

GET /v1/coverage

Each state, how its addresses are placed, the files loaded for it, and its registered regionSources. See Sources for where each state's data comes from, or run the API yourself.

Sent from this page without a key, limited per IP address.

Request

curl "https://api.opentaxrate.com/v1/coverage" \
  -H "Authorization: Bearer otr_live_..."