API Reference

Complete documentation for the Sefro sales tax API. One request, one header, every US jurisdiction.

Authentication

All requests require an X-API-Key header with your API key:

curl -H "X-API-Key: YOUR_API_KEY" \ https://tax-rates-api-production.up.railway.app/rates?zip=94102

Obtain your API key by signing up for a plan at sefro.app. Keys are long hexadecimal strings (32+ characters). Never share your key — treat it like a password.

Base URL

All endpoints are served from:

https://tax-rates-api-production.up.railway.app

The path prefix /v1 is aliased to the root for future-proofing.

Rates

Look up the combined sales tax rate for any US jurisdiction by ZIP code or full address (state, county, city).

GET /rates

GET /rates

Retrieve combined tax rate by ZIP or jurisdiction. Returns state, county, city, and special district rates summed into a total.

Query Parameters
ParameterTypeDescription
zip string 5-digit US ZIP code (e.g., 94102). Returns the best-match rate for that ZIP.
state string 2-letter state code (e.g., CA, NY, TX). Required if zip is not provided.
county string County name (e.g., "Los Angeles"). Optional; requires state.
city string City name (e.g., "Los Angeles"). Optional; requires state and county.
Example: Lookup by ZIP
curl -H "X-API-Key: YOUR_API_KEY" \ "https://tax-rates-api-production.up.railway.app/rates?zip=94102"
Response
{ "state_code": "CA", "zip": "94102", "county": "San Francisco", "city": "San Francisco", "tax_region_name": "San Francisco", "rates": { "state": 7.25, "county": 1.43, "city": 1.25, "special": 0.0, "total": 8.68 }, "source": "geo-zip", "rate_type": "authoritative", "effective_date": "2026-01-01", "updated_at": "2026-06-15T10:30:00Z", "disclaimer": "Rates are reference data, not tax advice..." }
Example: Lookup by state, county, city
curl -H "X-API-Key: YOUR_API_KEY" \ "https://tax-rates-api-production.up.railway.app/rates?state=CA&county=Los+Angeles&city=Los+Angeles"

GET /rates/states

GET /rates/states

List all 51 states + DC with their base state sales tax rates.

Example
curl -H "X-API-Key: YOUR_API_KEY" \ "https://tax-rates-api-production.up.railway.app/rates/states"
Response
{ "count": 51, "states": [ { "state_code": "AL", "name": "State of Alabama", "rate": 4.0, "source": "state-revenue-dept", "updated_at": "2026-01-15T00:00:00Z" }, { "state_code": "CA", "name": "State of California", "rate": 7.25, "source": "state-revenue-dept", "updated_at": "2026-01-15T00:00:00Z" } ] }

Calculate

Compute sales tax on a subtotal or line items, with taxability and exemption certificate support.

POST /calculate

POST /calculate

Calculate tax on a sale to a jurisdiction, accounting for product categories, exemptions, and exemption certificates.

Request Body
FieldTypeDescription
to_zip string 5-digit ZIP code. Required if to_state is not provided.
to_state string 2-letter state code. Required if to_zip is not provided.
to_county string County name. Optional.
to_city string City name. Optional.
subtotal number Subtotal in dollars (e.g., 99.99). Required if line_items is not provided.
line_items array Array of items with id, description, quantity, unit_price, category, exempt. Required if subtotal is not provided.
exemption_certificate_id string UUID of an exemption certificate to apply. Optional.
customer_exempt boolean Mark entire order as exempt from tax. Optional (default false).
Example: Calculate on subtotal
curl -X POST -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"to_zip":"94102", "subtotal":99.99}' \ https://tax-rates-api-production.up.railway.app/calculate
Response
{ "jurisdiction": { "state_code": "CA", "tax_region_name": "San Francisco", "zip": "94102", "rate_type": "authoritative", "rates": { "state": 7.25, "county": 1.43, "city": 1.25, "special": 0.0, "total": 8.68 } }, "subtotal": 99.99, "exempt_amount": 0.0, "taxable_amount": 99.99, "tax_amount": 8.68, "effective_rate": 8.68, "total_with_tax": 108.67, "disclaimer": "Rates are reference data, not tax advice..." }
Example: Calculate with line items
curl -X POST -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to_state": "TX", "line_items": [ { "id": "item-1", "description": "Laptop", "quantity": 1, "unit_price": 1200.00, "category": "general" }, { "id": "item-2", "description": "SaaS subscription", "quantity": 1, "unit_price": 29.99, "category": "saas" } ] }' \ https://tax-rates-api-production.up.railway.app/calculate

GET /calculate/history

GET /calculate/history

Retrieve your calculation history. Paginated; sorted by recency (newest first).

Query Parameters
ParameterTypeDescription
limit integer Number of records to return (max 200, default 50).
Example
curl -H "X-API-Key: YOUR_API_KEY" \ "https://tax-rates-api-production.up.railway.app/calculate/history?limit=10"
Response
{ "count": 2, "calculations": [ { "id": "calc-uuid-1", "to_zip": "94102", "to_state": "CA", "subtotal": 99.99, "tax_amount": 8.68, "effective_rate": 8.68, "created_at": "2026-06-15T14:30:00Z" } ] }

Validate

Normalize and validate addresses; confirm jurisdiction and confidence level.

POST /validate/address

POST /validate/address

Validate and normalize an address, return matching jurisdiction and confidence score (high/medium/low).

Request Body
FieldTypeDescription
zip string ZIP code (5-digit or ZIP+4). Optional if state provided.
state string State name or 2-letter code. Required.
county string County name. Optional.
city string City name. Optional.
Example
curl -X POST -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"zip":"94102", "state":"CA", "county":"San Francisco", "city":"San Francisco"}' \ https://tax-rates-api-production.up.railway.app/validate/address
Response
{ "valid": true, "confidence": "high", "normalized": { "zip": "94102", "state_code": "CA", "county": "San Francisco", "city": "San Francisco", "tax_region_name": "San Francisco" }, "rates": { "state": 7.25, "county": 1.43, "city": 1.25, "special": 0.0, "total": 8.68 }, "jurisdiction_source": "geo-zip", "warnings": [] }

GET /validate/zip/:zip

GET /validate/zip/:zip

Quick ZIP code validation. Returns all jurisdictions matching that ZIP with their rates.

Path Parameters
ParameterTypeDescription
zip string 5-digit or ZIP+4 format (e.g., 94102 or 94102-1234).
Example
curl -H "X-API-Key: YOUR_API_KEY" \ https://tax-rates-api-production.up.railway.app/validate/zip/94102
Response
{ "valid": true, "zip": "94102", "state_code": "CA", "jurisdictions": [ { "county": "San Francisco", "city": "San Francisco", "tax_region_name": "San Francisco", "total_rate": 8.68 } ] }

Taxability

Query whether specific product categories are taxable in a state, with optional rate modifiers and thresholds.

GET /taxability

GET /taxability

Look up taxability for a product category in a state.

Query Parameters
ParameterTypeDescription
state string 2-letter state code (e.g., CA). Required.
category string Product category (e.g., saas, groceries, clothing). Required. See /taxability/categories for valid values.
Example
curl -H "X-API-Key: YOUR_API_KEY" \ "https://tax-rates-api-production.up.railway.app/taxability?state=CA&category=saas"
Response
{ "state": "CA", "category": "saas", "taxable": true, "rate_modifier": null, "threshold_amount": null, "notes": null }

GET /taxability/categories

GET /taxability/categories

List all product categories in the database.

Example
curl -H "X-API-Key: YOUR_API_KEY" \ https://tax-rates-api-production.up.railway.app/taxability/categories
Response
{ "categories": ["general", "groceries", "saas", "clothing", "digital", "services", "alcohol", "tobacco", "fuel", "prepared_food"] }

GET /taxability/matrix

GET /taxability/matrix

Retrieve the full taxability matrix for one state or all states.

Query Parameters
ParameterTypeDescription
state string 2-letter state code (e.g., CA). If omitted, returns all states.
Example (single state)
curl -H "X-API-Key: YOUR_API_KEY" \ "https://tax-rates-api-production.up.railway.app/taxability/matrix?state=CA"
Response
{ "state": "CA", "rules": { "saas": { "taxable": true, "rate_modifier": null, "threshold_amount": null, "notes": null }, "groceries": { "taxable": false, "rate_modifier": null, "threshold_amount": null, "notes": "Grocery items exempt in CA" } } }

Exemptions

Create, retrieve, update, and delete exemption certificates scoped to your account.

POST /exemptions

POST /exemptions

Create an exemption certificate for a buyer (reseller, nonprofit, etc.).

Request Body
FieldTypeDescription
certificate_number string Your internal certificate number. Optional.
buyer_name string Name of the exempt buyer. Required.
buyer_ein string EIN or tax ID. Optional.
buyer_email string Contact email. Optional.
exempt_states array States where exemption applies (e.g., ["CA", "TX"]). Required.
categories array Product categories exempt (empty = all categories). Optional.
expires_at string Expiration date in ISO format (YYYY-MM-DD). Optional.
Example
curl -X POST -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "buyer_name": "Acme Corp", "buyer_ein": "12-3456789", "exempt_states": ["CA", "TX"], "categories": [], "expires_at": "2027-12-31" }' \ https://tax-rates-api-production.up.railway.app/exemptions
Response (201)
{ "id": "cert-uuid", "certificate_number": null, "buyer_name": "Acme Corp", "buyer_ein": "12-3456789", "buyer_email": null, "exempt_states": ["CA", "TX"], "categories": [], "expires_at": "2027-12-31", "is_active": true, "api_key_id": "key-uuid", "created_at": "2026-06-15T14:30:00Z" }

GET /exemptions

GET /exemptions

List all exemption certificates in your account.

Example
curl -H "X-API-Key: YOUR_API_KEY" \ https://tax-rates-api-production.up.railway.app/exemptions
Response
{ "count": 1, "certificates": [ { "id": "cert-uuid", "buyer_name": "Acme Corp", "exempt_states": ["CA", "TX"], "categories": [], "is_active": true, "created_at": "2026-06-15T14:30:00Z" } ] }

GET /exemptions/:id

GET /exemptions/:id

Retrieve a single exemption certificate by ID.

PATCH /exemptions/:id

PATCH /exemptions/:id

Update an exemption certificate (buyer name, email, states, categories, expiration, or is_active status).

Example: Deactivate a certificate
curl -X PATCH -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"is_active": false}' \ https://tax-rates-api-production.up.railway.app/exemptions/cert-uuid

DELETE /exemptions/:id

DELETE /exemptions/:id

Deactivate (soft delete) an exemption certificate.

Example
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" \ https://tax-rates-api-production.up.railway.app/exemptions/cert-uuid
Response
{"success": true}

Errors

All errors return JSON with an error field describing the problem. Rate limits reset at midnight UTC daily.

400
Bad Request. Invalid parameter or malformed JSON. Check your query string or request body.
401
Unauthorized. Missing or invalid X-API-Key header.
403
Forbidden. Your API key does not have permission for this resource.
404
Not Found. No tax jurisdiction or resource found for your query.
413
Payload Too Large. Request body exceeds size limit (4 KB for signup forms).
429
Too Many Requests. You've exceeded your daily limit. Trial: 100/day. Limits reset at midnight UTC.
500+
Server Error. Something went wrong on our end. Check status.sefro.app or contact support.
Example error response:
{ "error": "Invalid ZIP code format. Use 5-digit or ZIP+4." }

Plans & Limits

Every plan includes all five endpoints. Limits are requests per day, reset daily at midnight UTC.

Plan Price Daily Limit Duration
Trial Free 100 req/day 5 days (card required)
Starter $29 2,000 req/day Monthly
Growth $49 12,000 req/day Monthly
Pro $79 50,000 req/day Monthly
Scale $149 150,000 req/day Monthly
Enterprise Custom Custom Custom SLA

No per-transaction fees. No monthly minimum. No implementation fees. Cancel anytime.