{"openapi":"3.1.0","info":{"title":"OpenTaxRate API","version":"1","license":{"name":"MIT License","url":"https://github.com/equated-org/opentaxrate/blob/main/LICENSE"},"description":"The sales tax rate at a US street address, from the states' own published data. Without a key, lookups are limited per IP address."},"servers":[{"url":"https://api.opentaxrate.com"}],"security":[{},{"bearer":[]},{"apiKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key from the dashboard."},"apiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"The same key, as a header."}},"schemas":{"AddressRate":{"type":"object","properties":{"state":{"type":"string","example":"WA"},"rate":{"type":"number","description":"The combined rate on a general sale, as a decimal: 0.1055 is 10.55%. With code=, the sale's own rate is taxability.rate.","example":0.1055},"stateRate":{"type":"number","description":"The state's part.","example":0.065},"localRate":{"type":"number","description":"Everything else.","example":0.0405},"byType":{"$ref":"#/components/schemas/RatesByType"},"parts":{"type":"array","items":{"$ref":"#/components/schemas/RatePart"}},"match":{"type":"string","enum":["statewide","street","zip4","zip5","map","zip_area","authority"],"description":"How the address was placed: one rate statewide, a street range, a ZIP+4 range, a ZIP whose ranges agree, map outlines, a ZIP area with one rate, or the state's own lookup."},"locationCode":{"type":["string","null"],"description":"OpenTaxRate's key for the combination of taxes. Not a filing code.","example":"53-000-63000"},"jurisdictions":{"type":"string","enum":["settled","uncertain"],"description":"Whether 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 (listed in alternatives), or the state's lookup gave one local part for every local tax."},"alternatives":{"type":"array","items":{"type":"object","properties":{"locationCode":{"type":["string","null"]},"parts":{"type":"array","items":{"$ref":"#/components/schemas/RatePart"}}},"required":["locationCode","parts"]},"description":"The other combinations of jurisdictions the address could be in, each with the same total; empty when settled."},"locationIds":{"type":"object","properties":{"Composite SER Code":{"type":"string","description":"Streamlined states' location code. In Washington, the DOR location code zero-padded to five digits: 01726 is 1726.","example":"01726"},"Location Code":{"type":"string","description":"Washington: the DOR's four-digit location code a Combined Excise Tax Return files under; Composite SER Code without its padding zero.","example":"1726"},"Jurisdiction Code":{"type":"string","description":"Missouri's jurisdiction code for the location.","example":"15670-019-000"},"Tax Area Code":{"type":"string","description":"California: CDTFA's 12-character tax area code.","example":"19034D900000"},"Local Tax Area Code":{"type":"string","description":"California: the five-digit county and city code (998 unincorporated) a CDTFA return's schedules ask for; the first five characters of Tax Area Code.","example":"19034"}},"additionalProperties":{"type":"string"},"description":"The state's own codes for the whole location, keyed by the name its data gives them; values are strings, leading zeros kept. {} where its data gives none, or the address could be in areas whose ids differ: read a key as possibly absent.","example":{"Composite SER Code":"01726","Location Code":"1726"}},"zip4":{"type":["string","null"],"description":"The address's ZIP+4, where a Streamlined state's files give it."},"source":{"type":"string","description":"The files or service the rate came from, and the date."},"reporting":{"$ref":"#/components/schemas/Reporting"},"taxability":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Taxability"},"description":"With code=: one entry per code asked, keyed by the code (goods.general, food.grocery, food.prepared, food.catering, software.saas, software.custom, service.professional, construction.real_property, delivery, nontaxable)."},"regions":{"$ref":"#/components/schemas/Regions"},"trace":{"$ref":"#/components/schemas/Trace"}},"required":["state","rate","stateRate","localRate","byType","parts","match","locationCode","jurisdictions","alternatives","locationIds","zip4","source","reporting"]},"RatesByType":{"type":"object","properties":{"general":{"type":"number","description":"A general sale from within the state."},"generalInterstate":{"type":["number","null"],"description":"A general sale from out of state."},"foodDrug":{"type":["number","null"],"description":"Food and drugs, where the state taxes them at its food rate."},"foodDrugInterstate":{"type":["number","null"],"description":"Food and drugs from out of state."}},"required":["general","generalInterstate","foodDrug","foodDrugInterstate"],"description":"A rate for each kind of sale the state's files rate apart; null where the publisher gives none."},"RatePart":{"type":"object","properties":{"kind":{"type":"string","enum":["state","county","city","district"]},"name":{"type":["string","null"],"description":"As the state's data writes it, else the Census outline's; null where no source names it.","example":"Seattle"},"code":{"type":"string","description":"The publisher's jurisdiction type and code.","example":"01:63000"},"rate":{"type":"number","description":"This part's rate.","example":0.065},"byType":{"$ref":"#/components/schemas/RatesByType"},"ids":{"type":"object","additionalProperties":{"type":"string"},"description":"The state's own ids for this tax, keyed by its data's column names and unchanged; {} where it publishes none.","example":{"Locality Code":"9454"}}},"required":["kind","code","rate"],"description":"One tax adding up to the rate."},"Reporting":{"type":["object","null"],"properties":{"agency":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string"}},"required":["name","url"],"description":"Who the state's return goes to."},"form":{"type":["string","null"],"description":"The return most sellers file there."},"notes":{"type":"array","items":{"type":"string"},"description":"Filing that doesn't go through that return: self-collected cities, a remote sellers' program."},"locationKey":{"type":["string","null"],"description":"The locationIds key the return files this location under: read locationIds[locationKey]. Null where the state's data gives no location code; the key may still be missing from locationIds where the address could be in areas whose codes differ.","example":"Location Code"}},"required":["agency","form","notes","locationKey"]},"Taxability":{"type":"object","properties":{"treatment":{"type":"string","enum":["taxable","partial","not_taxed","conditional","not_researched"],"description":"taxable: every part at its rate. partial: some parts, or a reduced rate. not_taxed: no part. conditional: the outcome turns on facts the code doesn't fix, listed in the rules' conditions. not_researched: a part has no researched rule for this code on this date; never use the general rate instead."},"rate":{"type":["number","null"],"description":"The combined rate on this sale; null exactly when conditional or not researched.","example":0.08875},"taxes":{"type":"array","items":{"$ref":"#/components/schemas/TaxGroup"}}},"required":["treatment","rate","taxes"],"description":"How one kind of sale is taxed at the address on the date: the parts grouped by the rule that decided them, with the rules and their official sources."},"TaxGroup":{"type":"object","properties":{"tax":{"type":"string","description":"What 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.","example":"NY"},"parts":{"type":"array","items":{"type":"string"},"description":"The codes of the answer's parts this rule decides; together the entries cover every part once."},"treatment":{"type":"string","enum":["taxable","exempt","zero_rated","conditional","not_a_sale","not_researched"]},"rate":{"type":["number","null"],"description":"What these parts add to the sale's rate; null when conditional or not researched."},"rule":{"$ref":"#/components/schemas/TaxabilityRule"}},"required":["tax","parts","treatment","rate","rule"]},"TaxabilityRule":{"type":["object","null"],"properties":{"from":{"type":"string","description":"First day the rule answers for.","example":"2019-04-08"},"to":{"type":"string","description":"Last day in force; open-ended when absent."},"fromIs":{"type":"string","enum":["effective","earliest_verified"],"description":"effective: the sources give from as the day the rule took effect. earliest_verified: the rule is likely older, but earlier dates are not researched."},"treatment":{"type":"string","enum":["taxable","exempt","zero_rated","conditional","not_a_sale"]},"summary":{"type":"string","example":"Catering is taxable, including staff, rentals and service charges on the bill."},"conditions":{"type":"array","items":{"type":"object","properties":{"when":{"type":"string"},"treatment":{"type":"string","enum":["taxable","exempt","zero_rated"]},"rate":{"type":"number","description":"The part's rate in this case, where it isn't the part's full rate."}},"required":["when","treatment"]},"description":"For a conditional rule, each fact the outcome turns on; for a settled one, exceptions worth knowing."},"citations":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"url":{"type":"string"},"quote":{"type":"string"}},"required":["title","url"]},"description":"The official pages the rule was read from."}},"required":["from","fromIs","treatment","summary","conditions","citations"],"description":"Null only when not researched."},"Regions":{"type":"object","properties":{"matches":{"type":"array","items":{"$ref":"#/components/schemas/RegionMatch"}},"coverage":{"type":"array","items":{"$ref":"#/components/schemas/RegionCoverage"}}},"required":["matches","coverage"],"description":"With include=regions: published areas the address is in. Evidence only; they don't change the rate."},"RegionMatch":{"type":"object","properties":{"kind":{"type":"string","enum":["transit","tax_area","special_district","civil","boundary_change","police_jurisdiction","incentive_zone"]},"type":{"type":"string"},"name":{"type":["string","null"]},"ids":{"type":"object","additionalProperties":{"type":"string"}},"featureId":{"type":"string","description":"The feature's id within its snapshot."},"attributes":{"type":"object","additionalProperties":{},"description":"The publisher's attributes, names and units unchanged."},"source":{"$ref":"#/components/schemas/RegionSource"}},"required":["kind","type","name","ids","featureId","attributes","source"]},"RegionSource":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"snapshotId":{"type":"string"},"edition":{"type":["string","null"]},"observedAt":{"type":"string"},"startsOn":{"type":["string","null"]},"endsOn":{"type":["string","null"]},"dateBasis":{"type":"string","enum":["published_edition","latest_snapshot"],"description":"latest_snapshot: an undated source's latest copy; its observedAt is not a legal effective date."},"note":{"type":["string","null"]}},"required":["id","url","snapshotId","edition","observedAt","startsOn","endsOn","dateBasis","note"]},"RegionCoverage":{"type":"object","properties":{"source":{"type":"string"},"status":{"type":"string","enum":["evaluated","unavailable","date_uncovered","location_uncertain","incomplete","error"],"description":"Only evaluated with no match means the address is outside that source's areas."},"details":{"$ref":"#/components/schemas/RegionSource"}},"required":["source","status"]},"Trace":{"type":"object","properties":{"geocoders":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"lon":{"type":"number"},"lat":{"type":"number"},"accuracy":{"type":"string","enum":["rooftop","parcel","point","interpolated"]}},"required":["source","lon","lat","accuracy"]},"description":"Every point a geocoder returned."},"point":{"type":"object","properties":{"lon":{"type":"number"},"lat":{"type":"number"},"accuracy":{"type":"string","enum":["rooftop","parcel","point","interpolated"]},"source":{"type":"string"},"marginMetres":{"type":"number"},"spreadMetres":{"type":"number"}},"required":["lon","lat","accuracy","source","marginMetres","spreadMetres"],"description":"The point used, and the margin a boundary must be beyond."},"outlines":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["county","place","cousub","district"]},"fips":{"type":"string"},"name":{"type":"string"},"inside":{"type":"boolean"},"edgeMetres":{"type":"number"},"foot":{"type":"object","properties":{"lon":{"type":"number"},"lat":{"type":"number"}},"required":["lon","lat"]},"levies":{"type":"boolean"},"geometry":{"type":"object","properties":{"type":{"type":"string","enum":["Polygon","MultiPolygon"]},"coordinates":{"type":"array","items":{}}},"required":["type","coordinates"],"description":"GeoJSON, clipped and simplified for display."}},"required":["kind","fips","name","inside","edgeMetres","foot","levies"]}},"range":{"type":"object","properties":{"street":{"type":"string"},"low":{"type":"number"},"high":{"type":"number"},"side":{"type":"string","enum":["odd","even","both"]},"zip":{"type":["string","null"]},"file":{"type":"string"}},"required":["street","low","high","side","zip","file"],"description":"The street range that decided, when one did."}},"required":["geocoders","outlines"],"description":"With include=trace: how the address was placed. Never changes the answer."},"Error":{"type":"object","properties":{"error":{"type":"string","description":"Why, as a person reads it.","example":"This address is within 12 m of a city line ..."},"code":{"type":"string","enum":["UNSUPPORTED_STATE","ADDRESS_NEEDS_CONFIRMATION","UPSTREAM_UNAVAILABLE","UPSTREAM_TIMEOUT","RATE_LIMITED","INVALID_API_KEY","KEY_LIMITED","NO_CREDITS","BAD_REQUEST","INTERNAL"],"description":"Stable, for a program."},"trace":{"allOf":[{"$ref":"#/components/schemas/Trace"},{"description":"On a 422, with include=trace."}]}},"required":["error","code"]},"Coverage":{"type":"array","items":{"type":"object","properties":{"state":{"type":"string"},"method":{"type":["string","null"],"enum":["statewide","ranges","map","authority",null]},"geocoders":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"sources":{"type":"array","items":{"type":"string"}},"typicalAccuracy":{"type":"string","enum":["rooftop","parcel","point","interpolated"]},"dailyCap":{"type":"number"},"ratePerSecond":{"type":"number"},"storable":{"type":"boolean"}},"required":["id","sources","typicalAccuracy","dailyCap","ratePerSecond","storable"]}},"regionSources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["transit","tax_area","special_district","civil","boundary_change","police_jurisdiction","incentive_zone"]},"type":{"type":"string"},"note":{"type":"string"}},"required":["id","kind","type","note"]}},"taxabilityCodes":{"type":"array","items":{"type":"string"},"description":"The codes with a researched rule here today, for code=; others answer not_researched."},"files":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["rates","boundaries"]},"file":{"type":"string"},"rows":{"type":"number"},"loadedAt":{"type":"string"}},"required":["kind","file","rows","loadedAt"]}}},"required":["state","method","geocoders","regionSources","taxabilityCodes","files"]}}},"parameters":{}},"paths":{"/v1/rate":{"get":{"operationId":"getRate","summary":"The sales tax rate at an address","description":"Give the address as one line (address) or as fields (state, street, city, zip). Rates are decimals: 0.1055 is 10.55%.","parameters":[{"schema":{"type":"string","maxLength":300,"description":"The whole address on one line. Commas are optional; the state can be a code or its name. The fields below win over it.","example":"1410 E Pine St, Seattle, WA 98122"},"required":false,"description":"The whole address on one line. Commas are optional; the state can be a code or its name. The fields below win over it.","name":"address","in":"query"},{"schema":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter state code. Required without address.","example":"WA"},"required":false,"description":"Two-letter state code. Required without address.","name":"state","in":"query"},{"schema":{"type":"string","maxLength":200,"default":"","description":"House number and street.","example":"1410 E Pine St"},"required":false,"description":"House number and street.","name":"street","in":"query"},{"schema":{"type":"string","maxLength":100,"default":"","example":"Seattle"},"required":false,"name":"city","in":"query"},{"schema":{"type":"string","pattern":"^(?:\\d{5}(?:-?\\d{4})?|[A-Za-z]\\d[A-Za-z][ -]?\\d[A-Za-z]\\d)$","description":"Five digits or ZIP+4. Recommended: without it the address is geocoded, and a few more are refused.","example":"98122"},"required":false,"description":"Five digits or ZIP+4. Recommended: without it the address is geocoded, and a few more are refused.","name":"zip","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"YYYY-MM-DD; today when absent.","example":"2026-10-22"},"required":false,"description":"YYYY-MM-DD; today when absent.","name":"date","in":"query"},{"schema":{"type":"string","maxLength":300,"description":"What was sold, one or more codes separated by commas, from: goods.general, food.grocery, food.prepared, food.catering, software.saas, software.custom, service.professional, construction.real_property, delivery, nontaxable. Adds taxability to the answer, one entry per code; an unknown code is a 400.","example":"food.catering,nontaxable"},"required":false,"description":"What was sold, one or more codes separated by commas, from: goods.general, food.grocery, food.prepared, food.catering, software.saas, software.custom, service.professional, construction.real_property, delivery, nontaxable. Adds taxability to the answer, one entry per code; an unknown code is a 400.","name":"code","in":"query"},{"schema":{"type":"string","maxLength":100,"description":"Comma-separated: trace, regions. Others are ignored.","example":"regions"},"required":false,"description":"Comma-separated: trace, regions. Others are ignored.","name":"include","in":"query"}],"responses":{"200":{"description":"The rate, split into the taxes that make it up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressRate"}}}},"400":{"description":"A parameter failed validation, or address couldn't be read; the message says what's missing (BAD_REQUEST).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The key isn't one we issued (INVALID_API_KEY).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The key's credit doesn't cover the lookup (NO_CREDITS).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The data can't place the address in one rate (ADDRESS_NEEDS_CONFIRMATION), or the state isn't covered (UNSUPPORTED_STATE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many lookups; wait the Retry-After seconds (RATE_LIMITED, KEY_LIMITED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"A state's data isn't loaded, or its service is down (UPSTREAM_UNAVAILABLE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"A state's service timed out (UPSTREAM_TIMEOUT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/coverage":{"get":{"operationId":"getCoverage","summary":"Each state, how its addresses are placed, and the data loaded for it","responses":{"200":{"description":"Every covered state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Coverage"}}}},"401":{"description":"The key isn't one we issued (INVALID_API_KEY).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{}}