---
title: "POST /tax/calculations"
method: POST
path: "/tax/calculations"
---

# POST /tax/calculations

`POST /tax/calculations`

Get tax information for a given product and address or IP

## Headers

- `X-API-Version` '2026-03-01', required

## Request body

- CalculationRequest
  - `customer` CustomerDetails, required — Customer details. At least one of address or ip must be provided.
    - `id` string — The ID of the customer that you created in our system. Can be used to log customer information or indicate that a purchaser is tax exempt. Pair with the top-level `default_customer_type` to avoid a 400 when the ID has not yet been created in Numeral.
    - `type` 'CONSUMER' | 'BUSINESS' — `CONSUMER` are private individuals who are not registered for VAT/GST. `BUSINESS` are companies, sole-proprietors, or other legal entities registered for VAT/GST. Defaults to `CONSUMER` when omitted.
    - `tax_ids` TaxId[] — Array of tax identification numbers. Required when `type` is `BUSINESS` and the address is outside the US (not enforced for IP-only requests).
      - `type` string, required — Country-specific Stripe-style tax ID type (e.g., `us_ein`, `eu_vat`, `gb_vat`, `au_abn`, `ca_gst_hst`). See [Tax IDs](/essentials/tax-ids) for the full list of supported types.
      - `value` string, required — The tax ID value (1-100 characters).
    - `skip_tax_id_validation` boolean — When `true`, skips validation of the provided `tax_ids` (format and registry checks). Defaults to `false`.
    - `address` object — The customer (destination) address. Optional when `ip` is provided — with an IP present, address-quality problems fall back to IP resolution instead of returning a 400. Supports 82 destination countries: US, CA, EU member states, plus CY, CH, NO, GB, AU, NZ, SG, ID, VN, PH, TH, KR, JP, IN, TR, SA, AE, AR, CL, EG, HK, MO, IL, AL, TW, MY, BD, ZA, KE, UG, MA, BH, OM, CI, CM, GH, NG, BJ, NE, CV, IS, RS, GE, MD, MK, ME, CO, PE, UY, BB, BS, LA, LI, KZ, TZ. For US and CA, `address_postal_code` is required and `address_province` is required — a valid uppercase USPS state code for US, province code for CA. Fallback only: if `address_province` is missing or empty on a US address, Thomas attempts to infer the state from a valid 5-digit ZIP; an unrecognized ZIP returns a 400 `MALFORMED_ADDRESS`. Do not rely on this — always send the state.
      - `address_line_1` string, required
      - `address_line_2` string
      - `address_city` string, required
      - `address_province` string, required — The state, province, or region of the transaction. Must be a valid 2 digit ISO 3166-2 subdivision code.
      - `address_postal_code` string, required
      - `address_country` string, required — The country code of the transaction. Must be a valid ISO 3166-1 alpha-2 country code.
      - `address_type` 'shipping' | 'billing', required — The type of address. For physical goods, `shipping` should be used. For software and digital goods, `billing` is more appropriate. Only valid on `customer.address` — including it on `origin_address` returns a 400 `UNRECOGNIZED_FIELD` error.
    - `ip` object — IP address for geo-based tax resolution. Either address or ip (or both) must be provided. If both are given, the address is used first and the IP acts as a fallback for address-quality errors. An invalid IP format returns a 400 `INVALID_IP_FORMAT`.
      - `value` string, required — A valid IPv4 or IPv6 address. Only required when an `ip` object is provided — omit `ip` entirely for address-only calculations.
      - `resolution` 'strict' | 'zero' | 'approximate' | 'best_effort' — How to handle insufficient IP resolution. strict (default): error if insufficient. zero: return zero-rate. approximate: attempt to resolve using heuristics. best_effort: try approximate, fall back to zero.
  - `origin_address` Address
    - `address_line_1` string, required
    - `address_line_2` string
    - `address_city` string, required
    - `address_province` string, required — The state, province, or region of the transaction. Must be a valid 2 digit ISO 3166-2 subdivision code.
    - `address_postal_code` string, required
    - `address_country` string, required — The country code of the transaction. Must be a valid ISO 3166-1 alpha-2 country code.
  - `order_details` OrderDetails, required
    - `customer_currency_code` string, required — The ISO-4217 currency code of the transaction. Supports 126 currencies (the full Stripe-supported list): AED, ALL, AMD, AOA, ARS, AUD, AWG, AZN, BAM, BBD, BDT, BGN, BIF, BMD, BND, BOB, BRL, BSD, BWP, BZD, CAD, CDF, CHF, CLP, CNY, COP, CRC, CVE, CZK, DJF, DKK, DOP, DZD, EGP, ETB, EUR, FJD, FKP, GBP, GEL, GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HTG, HUF, IDR, ILS, INR, ISK, JMD, JPY, KES, KGS, KHR, KMF, KRW, KYD, KZT, LAK, LKR, LRD, LSL, MAD, MDL, MGA, MKD, MNT, MOP, MUR, MVR, MWK, MXN, MYR, MZN, NAD, NGN, NIO, NOK, NPR, NZD, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR, RON, RSD, RWF, SAR, SBD, SCR, SEK, SGD, SOS, SRD, SZL, THB, TJS, TOP, TRY, TTD, TWD, TZS, UAH, UGX, USD, UYU, UZS, VND, VUV, WST, XAF, XCD, XCG, XOF, XPF, YER, ZAR, ZMW.
    - `tax_included_in_amount` boolean, required — For the line items in this transaction, does the amount include tax? This should typically be `false` for most North American sales, but may vary by jurisdiction and business model.
    - `automatic_tax` 'auto' | 'disabled', required — Controls automatic tax behavior. `auto`: return real rates if client is registered/enabled in that jurisdiction. `disabled`: always return 0 tax rates regardless of registration status. Required, and must be `auto` when the customer address is in the US.
    - `line_items` LineItem[], required — Each line item should represent one type of product. For compliance, we require either a `reference_product_id` or a `product_category`.
      - `reference_line_item_id` string — The ID of the line item from your system. This field is optional and will be primarily used for record keeping.
      - `reference_product_id` string — The product ID is used to uniquely reference this product in your system as well as in Numeral. Required if no `product_category`.
      - `product_category` string — A tax category from our category taxonomy. Required if no `reference_product_id`.
      - `fallback_product_category` string — Optional fallback product category used when `reference_product_id` is provided but no matching product exists in Numeral. Lets integration partners always pass a product ID without first ensuring the product has been created. Must be a valid product category from the Numeral taxonomy — an invalid value returns a 400. If a matching product is found, its stored category takes precedence.
      - `amount` integer, required — The **per-unit price** in the currency's smallest unit. The taxable base is calculated as `amount x quantity`. (e.g., if USD then 2000 = $20.00 per unit; with `quantity: 3` the taxable base is $60.00.) Before 2026-01-01, `amount` was the total for the line.
      - `quantity` integer, required — The quantity of this product being sold. The taxable base is `amount x quantity`.
  - `metadata` Metadata — You can store arbitrary keys and values in the metadata. At most 50 keys; each key at most 255 characters; each value must be a string of at most 255 characters (non-string values are rejected).
    - `example_key` string — Storing things like an order number may be useful for reporting and reconciliation.
  - `transacted_at` integer — Optional. The time the transaction occurred, as a Unix timestamp in **seconds** (not milliseconds). Used to determine which tax rates and rules apply at the time of the transaction (for example, during sales tax holidays), as well as other time-dependent inputs such as out-of-state-seller status. If omitted, the calculation uses the current time. Available in API version `2026-03-01` and later.
  - `default_customer_type` 'CONSUMER' | 'BUSINESS' — Optional fallback customer type used when `customer.id` is provided but no matching customer exists in Numeral. Lets integration partners always pass a customer ID without first ensuring the customer has been created. When the lookup misses, this value drives tax-exemption logic and business tax-ID validation as if it were `customer.type`. If a matching customer is found, the stored `customer.type` takes precedence. Available in API version `2026-03-01` and later.
  - `invalid_tax_id_customer_fallback_type` 'CONSUMER' — Optional. When business tax ID validation fails, fall back to treating the customer as this type instead of returning a 400. `CONSUMER` is the only accepted value. Available in API version `2026-01-01` and later.

## Response `200`

Calculate response

- CalculationResponse
  - `id` string — The ID of the `calculation`. You will use this to create a `transaction`.
  - `object` string — The type of object: `tax.calculation`.
  - `customer_currency_code` string — The ISO-4217 currency code of the transaction.
  - `customer` object — Customer information returned in the response. `type` reflects the effective customer type used for the calculation (e.g., after `default_customer_type` or `invalid_tax_id_customer_fallback_type` is applied).
    - `type` 'CONSUMER' | 'BUSINESS' — The type of customer. `CONSUMER` are private individuals. `BUSINESS` are companies or legal entities registered for VAT/GST.
    - `tax_ids` TaxId[] — Echo of the `tax_ids` provided in the request, when present.
      - `type` string, required — Country-specific Stripe-style tax ID type (e.g., `us_ein`, `eu_vat`, `gb_vat`, `au_abn`, `ca_gst_hst`). See [Tax IDs](/essentials/tax-ids) for the full list of supported types.
      - `value` string, required — The tax ID value (1-100 characters).
  - `automatic_tax` 'auto' | 'disabled' — The automatic tax setting for this calculation.
  - `line_items` TransactionLineItem[]
    - `product` object
      - `reference_product_name` string
      - `reference_line_item_id` string
      - `reference_product_id` string
      - `product_tax_code` string
    - `tax_jurisdictions` object[]
      - `tax_rate` number — The tax rate percentage applied to this transaction.
      - `tax_due_decimal` number — Tax amount due for this jurisdiction in the currency's smallest unit.
      - `rate_type` string — Descriptive rate classification for this jurisdiction.
      - `fee_amount` number — The flat fee that is added to this transaction. Like all numeric values, this will be returned in cents and should be added directly to the tax amount independent of other percentages. For example, a $100 transaction taxed at 5% and with a `fee_amount: 50` will lead to `($100 * 5% + 0.50) = $5.50` in tax being charged
      - `tax_authority_name` string — Name of the tax authority.
      - `tax_authority_type` string — Type of tax authority (e.g., STATE, COUNTY, CITY, DISTRICT).
      - `tax_type` string — Type of tax: SALES, USE, VAT, or GST.
    - `quantity` number
    - `tax_amount` number
    - `amount_excluding_tax` number
    - `amount_including_tax` number
  - `tax_included_in_amount` boolean
  - `total_tax_amount` integer — Total tax to charge on this `calculation`, in the currency's smallest unit (rounded to an integer).
  - `total_amount_excluding_tax` integer — Total sale charge excluding tax, in the currency's smallest unit (rounded to an integer).
  - `total_amount_including_tax` integer — Total sale charge plus tax, in the currency's smallest unit (rounded to an integer). What you should charge your customer.
  - `expires_at` integer — Unix timestamp in **seconds** at which the quoted tax rates expire — 24 hours after the calculation is created.
  - `testmode` boolean — `True` if using a production API key. `False` if using a test API key.
  - `address_resolution_status` 'EXACT' | 'POSTAL_FALLBACK_1' | 'POSTAL_ONLY' — Status of address resolution for the customer address. `EXACT`: exact address match found, `POSTAL_FALLBACK_1`: used postal code fallback, `POSTAL_ONLY`: only postal code was used for tax calculation.
  - `address_used` Address
    - `address_line_1` string, required
    - `address_line_2` string
    - `address_city` string, required
    - `address_province` string, required — The state, province, or region of the transaction. Must be a valid 2 digit ISO 3166-2 subdivision code.
    - `address_postal_code` string, required
    - `address_country` string, required — The country code of the transaction. Must be a valid ISO 3166-1 alpha-2 country code.
  - `metadata` Metadata — You can store arbitrary keys and values in the metadata. At most 50 keys; each key at most 255 characters; each value must be a string of at most 255 characters (non-string values are rejected).
    - `example_key` string — Storing things like an order number may be useful for reporting and reconciliation.
  - `location_source` 'address' | 'ip' — Which input was used for tax determination.
  - `resolution_precision` 'STREET' | 'POSTAL_PLUS' | 'POSTAL' | 'PROVINCE' | 'COUNTRY' | 'APPROXIMATED' — The precision level of the resolved location.

## Other responses

- `400` — Validation error
- `404` — Resource not found
- `422` — IP resolution error - the IP address could not be resolved to sufficient detail

---

[API](https://skmtc.net/numeral-com/apis/numeral-api.md) · [All operations](https://skmtc.net/numeral-com/apis/numeral-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/numeral-com/numeral-api/versions/f0af51c3f9b9/schema)
