Docs / API Reference / v1
API v1Current

Sales Tax Calculator API

Create an immutable sales tax calculation from seller, customer, item-classification, location, currency, and billing facts. Each response gives your application a stable outcome and the amounts it may use.

Base URLhttps://api.salestaxcalculatorapi.com

Call the API from trusted server code. Never put a secret API key in browser or mobile code.

POST/v1/calculations

Create one immutable sales tax calculation.

Create API key

Quickstart

Send JSON with a bearer key and an idempotency key tied to the business operation. The examples set connection and response timeouts and stop when the API returns a non-determinate outcome.

POST/v1/calculations
curl \
--request POST \
--url "https://api.salestaxcalculatorapi.com/v1/calculations" \
--connect-timeout 5 \
--max-time 15 \
--header "Authorization: Bearer $STCA_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: checkout-order-1001" \
--data '{
30 collapsed lines
"reference": "order-1001",
"transaction_date": "2026-08-29",
"currency": "CAD",
"tax_behavior": "exclusive",
"billing_event": "subscription_start",
"seller": {
"country": "CA",
"channel_role": "direct_legal_supplier",
"registrations": [
{
"country": "CA",
"state": "ON",
"type": "gst_hst",
"effective_from": "2026-01-01"
}
]
},
"customer": {
"type": "consumer",
"address": {
"country": "CA",
"state": "ON",
"postal_code": "M5V 2T6"
}
},
"lines": [
{
"reference": "subscription",
"amount": "100.00",
"quantity": "1",
"tax_code": "saas"
}
]
}'
201 Created
{
"id": "calc_01J6A3S8Z6K4M6T2Y2W9M5X8Q0",
"object": "calculation",
"reference": "order-1001",
"outcome": "calculated",
"currency": "CAD",
"subtotal": "100.00",
"taxable_amount": "100.00",
"tax": "13.00",
"total": "113.00",
"lines": [
13 collapsed lines
{
"id": "line_01J6A3T26X8BS4Y8XJKZ0H8F3P",
"reference": "subscription",
"outcome": "calculated",
"subtotal": "100.00",
"taxable_amount": "100.00",
"tax": "13.00",
"total": "113.00",
"explanation": "Tax was calculated for this sale."
}
],
"explanation": "Tax was calculated for this sale.",
"request_id": "req_01J6A3RZ1HT2K3W2X8R7P1J4C9",
"created_at": "2026-08-29T12:00:00Z"
}

Example sales tax calculation

This example is a CAD 100.00 tax-exclusive SaaS subscription sold directly to a consumer in Ontario by a seller with an effective Ontario GST/HST registration. The response applies 13% HST: CAD 100.00 subtotal + CAD 13.00 tax = CAD 113.00 total.

The example rate matches the Canada Revenue Agency GST/HST rate table. It demonstrates the request and response shape. Another transaction can return a different amount or outcome.

Sales tax calculation request fields

Unknown fields and JSON numbers for money are rejected. Use uppercase country, subdivision, and currency codes. Use lowercase API enum and tax-code values.

FieldUseMeaning
referenceRecommendedYour order, invoice, or cart reference. Returned with the sales tax calculation.
transaction_dateRecommendedCommercial date in YYYY-MM-DD form. It defaults to the current UTC date, so send it explicitly when results must be reproducible.
currencyRequiredThree-letter uppercase ISO 4217 code. All money values are decimal strings in this currency.
tax_behaviorRequiredUse exclusive when line amounts exclude tax. Use inclusive when line amounts already include tax.
billing_eventRequiredThe commercial event, such as one_time_charge, subscription_start, subscription_renewal, or metered_usage.
sellerRequiredSeller country, channel role, and effective-dated tax registrations that apply to this sale.
customerRequiredCustomer type and location. Add tax IDs or independent location evidence only when they apply.
ship_from / ship_toConditionalSupply-chain locations when shipping facts affect the transaction.
linesRequiredBetween 1 and 100 lines. Each line needs a unique reference, total line amount, and tax code. Quantity defaults to 1.
Line amount and quantity: amount is the total monetary amount for the line, not a unit price. quantity records how many units that total represents and supports proportional quantity adjustments later.

Sales tax calculation response fields

A created sales tax calculation returns HTTP 201 even when its tax outcome is review_required or unsupported. Check outcome before using tax or total.

FieldHow to use it
outcomeThe decision for the complete sales tax calculation. Branch on this before using any amount.
subtotalTax-exclusive amount represented by the response.
taxable_amountAmount to which tax was applied.
taxCalculated tax amount. This is 0.00 for non-determinate and valid zero-tax outcomes.
totalSubtotal plus tax for exclusive pricing, or the submitted gross amount for inclusive pricing.
linesPer-line outcome and final amounts. Keep these with the order for later adjustments.
explanationCustomer-readable reason for the returned outcome.
id / request_idStable identifiers for retrieval, logs, and support.
created_atUTC timestamp at which the immutable sales tax calculation was created.

For tax-exclusive pricing, the submitted line amount is the subtotal and tax is added. For tax-inclusive pricing, the submitted line amount is the total and the response separates its subtotal and tax. Use the returned decimal strings instead of recalculating from a displayed rate.

Sales tax calculation outcomes

HTTP 201

The HTTP status says the resource was created. The outcome says whether the returned amounts are a final tax decision.

OutcomeMeaningApplication action
calculatedTax was calculated from the supplied seller and transaction facts.Use the returned tax and total.
not_taxableThe supplied item is not taxable for this transaction.Use the returned zero-tax result.
not_obligatedThe seller is not the party required to collect tax.Use the returned zero-tax result.
reverse_charge_or_self_assessThe customer is responsible for the tax treatment.Use the returned result and preserve the explanation.
exemptAccepted evidence supports an exemption.Use the returned zero-tax result.
no_general_taxThe jurisdiction has no general transaction tax for this sale.Use the returned zero-tax result.
review_requiredThe supplied facts cannot support a final answer.Stop automatic tax handling and review the transaction.
unsupportedThis exact combination is not currently supported.Do not infer a rate or treat 0.00 as a tax decision.

Production handling

  1. Keep credentials server-side. Send the bearer key only from infrastructure you control.
  2. Make the request reproducible. Send the commercial transaction date, a stable reference, effective seller registrations, and the location and item-classification facts available at checkout.
  3. Tie idempotency to the operation. Reuse the same key and body when retrying the same order. Create a new key for a new operation.
  4. Branch on the top-level outcome. Treat review_required and unsupported as non-determinate even when individual lines contain amounts.
  5. Store the response. Keep the sales tax calculation ID, request ID, line IDs, outcome, amounts, and explanation with the order.
  6. Use returned amounts. Use the returned decimal strings to charge, display, finalize, and adjust amounts. Do not rebuild tax from rounded display values.
  7. Retry deliberately. Retry only retryable failures, honor the supplied delay, and preserve the original idempotency key and request body.

Errors and retries

Errors use RFC 9457 application/problem+json. Branch on the stable lowercase code, retain request_id, and inspect retryable. Field errors include a JSON Pointer.

HTTPTypical codeClient action
400invalid_request / unknown_field / invalid_idempotency_keyCorrect the listed request fields or header.
401invalid_api_keyUse an active account API key.
403forbiddenCheck the account entitlement and API-key permissions.
404resource_not_foundCheck the resource ID and account access.
409idempotency_conflict / request_in_progressReuse the original request or retry after the indicated delay.
413request_too_largeReduce the request or batch size.
422unsupported_currency / calculation_not_finalizableChange the unsupported value or resolve the resource state.
429rate_limit_exceededWait for Retry-After, then retry. This response does not consume an API call.
429usage_cap_reachedReview or change the account usage limit before retrying.
503tax_data_ambiguousRetry only when retryable is true.

When a retry is allowed, wait for Retry-After or retry_after_seconds when present and resend the identical body with the same idempotency key. A different body with that key returns 409 idempotency_conflict.

Authentication

Send an stca_ API key, shown only once when created, as a bearer token. Your API key continues to work when you move from evaluation to a paid plan.

Authorization: Bearer stca_••••••••

Send every request to the base URL shown above. You do not need tenant, mode, or environment headers.

Idempotency

Every create request needs an Idempotency-Key containing 8 to 255 safe ASCII characters and matching [A-Za-z0-9][A-Za-z0-9_.:-]{7,254}.

Repeating the same canonical request with the same key returns the original resource and Idempotent-Replayed: true. JSON whitespace or property order does not create a conflict.

Sales tax calculation audit details

Add ?expand=audit when your application needs the dated coverage basis, effective period, jurisdiction components, rates, taxable amounts, tax amounts, and evidence status returned for the sales tax calculation.

POST /v1/calculations?expand=audit

The expansion contains customer-facing sales tax calculation evidence. Store it with the result when your invoice, support, or reconciliation workflow needs those details.

API endpoints

All customer resources are scoped to the account authenticated by the bearer key.

Coverage

Use GET /v1/coverage to check a specific country, region, tax code, transaction type, customer type, and date without creating a sales tax calculation. A sales tax calculation request does not require a preceding coverage request and always returns its own outcome.

Service scope

The API calculates and records supported indirect-tax results. It does not file returns, remit tax, register businesses, or provide legal advice. Unsupported or incomplete combinations fail closed without inventing a tax amount.

OpenAPI specification

The OpenAPI 3.1.2 document defines request schemas, responses, errors, examples, and compatibility behavior for the public API.