> ## Documentation Index
> Fetch the complete documentation index at: https://docs.commenda.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tax Calculations

> Calculates the tax amount for a given transaction.

## Overview

The `/calculate` endpoint allows you to determine the amount of indirect tax to charge on a transaction. By providing details such as customer information, line items, and pricing, you'll receive accurate tax calculations based on applicable jurisdictions and rates.

## Supported countries

The calculation engine currently supports the following countries:

| Country        | Code | Ship-from address required |
| -------------- | ---- | -------------------------- |
| United States  | `US` | No                         |
| United Kingdom | `GB` | Yes                        |

<Note>
  For UK (`GB`) calculations, you must include a `ship_from` address in your request. If omitted, the API returns a `400` error.
</Note>

### Address validation

When you submit a calculation request, the API validates your addresses against the destination country's requirements. Only `country` is required at the schema level for all addresses. Other fields such as `postal_code` and `state` are conditionally required depending on the destination country. For example, US addresses require both `postal_code` and `state`, while GB addresses require `postal_code` but treat `state` as optional. You can look up which fields are required for a given country using the [address requirements endpoint](/engine/indirect-tax/address-requirements/address-requirements-GET) before making a calculation request.

## Factors affecting tax rates

Our system considers the following factors to determine the appropriate tax for a transaction:

1. **Seller Information**

   * **State Registrations**:
     * If your corporation is not registered to pay taxes in a state, the `/calculate` endpoint will return a tax amount of 0 for that state.
     * If your corporation is registered in a state, we calculate the tax amount based on that state’s rates and rules.

2. **Product-Specific Information**

   * **Product Taxability**:
     * **Product Configuration**: Each corporation can define and manage its product catalog via our `/products` endpoints. (Coming soon)
     * **Product Code Assignment**: For every product in the catalog, you can assign a specific product code using the API.
     * **Tax Rate Computation**: When the `/calculate` endpoint is called, each line item includes a product id. We use this id to retrieve the pre-configured product code for that product, determining its taxability for the transaction.
       * If a product is classified as non-taxable based on its product code, the tax amount for that specific line item will be 0.
       * If a product is taxable, the tax is calculated based on the product’s price and applicable tax rates.

3. **Customer Information**
   * **Shipping address**: We compute the tax rate based on the ship-to address provided for each transaction.
   * **Ship-from address**: For some countries (e.g., `GB`), the ship-from address is required and factors into the tax calculation.
   * **Customer exemptions**: Transactions can be exempted from sales tax based on properties of the customer making the purchase. You can read more about these exemptions [here](/engine/indirect-tax/core-concepts/exemptions#purpose-exemptions).

## Address resolution and validation

The `/calculate` endpoint validates addresses against country-specific requirements before computing tax.

### Ship-to address resolution

The destination address is resolved in the following order:

1. **`addresses.ship_to`** from the request body (highest priority).
2. **Customer's default shipping address** — used when `ship_to` is omitted and a `customer_id` is provided with a shipping address on file.
3. **Error** — if neither is available, the request returns a `400` error with sub-type `MISSING_SHIP_TO_ADDRESS`.

### Ship-from address

The `ship_from` address is optional for most countries but required for certain destination countries (e.g., GB). If required but missing, the request returns a `400` error with sub-type `MISSING_SHIP_FROM_ADDRESS`.

When a ship-from address is provided for US destinations, the state must be a valid US state code and the postal code must be a valid US ZIP format.

### Country-specific field validation

Each address is validated against per-country requirements that define which fields are required, optional, or ignored. Only `country` is always required. All other fields — including `postal_code` and `state` — may be required, optional, or ignored depending on the country. Validation includes:

* **Field presence** — required fields (e.g., `address_line_1`, `city` for US) must be provided and non-empty.
* **State code validation** — the state must match one of the valid ISO 3166-2 subdivision codes for the country.
* **Postal code format** — when a postal code is provided, it must match the country's expected format (e.g., `^\d{5}(-\d{4})?$` for US ZIP codes). The `postal_code` field is required for the US, EU countries (such as DE and FR), and GB. For CA, `postal_code` is optional but providing it improves tax jurisdiction accuracy.

Use the [`/address-requirements`](/engine/indirect-tax/address-requirements/address-requirements) endpoint to query which fields and formats are expected for each country before calling `/calculate`.

## Multi-currency support

The `/calculate` endpoint supports transactions in any [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency. You specify the currency of your transaction using the `transaction_currency` field, and all monetary values in the response are returned in that same currency.

### How it works

When you submit a calculation, the engine applies tax rates in the **destination country's local currency**. If your `transaction_currency` differs from the destination country's default currency, the system automatically:

1. Converts your line item amounts into the destination country's currency.
2. Looks up and applies the correct tax rates in that local currency.
3. Converts the calculated tax amounts back into your `transaction_currency`.

This means tax rates are always applied accurately in the jurisdiction's native currency, regardless of the currency your transaction is denominated in.

### Currency fields in the response

| Field                  | Description                                                                                                                                                              |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `transaction_currency` | The currency you specified in the request. All amounts in the response (`total_amount`, `total_tax`, `total_due`, and line item amounts) are expressed in this currency. |
| `tax_currency`         | The currency in which tax amounts are expressed. This matches `transaction_currency`.                                                                                    |
| `calculation_currency` | The destination country's default currency used internally to look up tax rates. Only present when a currency conversion occurred.                                       |
| `exchange_rate`        | The exchange rate applied between `transaction_currency` and `calculation_currency`. Only present when a currency conversion occurred.                                   |

<Note>
  If you omit `transaction_currency` from your request, it defaults to the destination country's local currency (e.g., `USD` for the US, `GBP` for the UK, `EUR` for Germany).
</Note>

### Monetary value rounding

Amounts are rounded according to the ISO 4217 standard for each currency:

* **Two decimal places** — most currencies (e.g., `USD`, `EUR`, `GBP`)
* **Zero decimal places** — `JPY`, `KRW`, `HUF`, `CLP`, `IDR`, `VND`, `ISK`, `TWD`
* **Three decimal places** — `BHD`, `KWD`, `OMR`

### Example: cross-currency calculation

If you sell a product in `EUR` to a customer in the US, set `transaction_currency` to `EUR`. The engine converts the amounts to `USD` to calculate US sales tax, then converts the results back to `EUR`:

```json theme={null}
{
  "transaction_currency": "EUR",
  "calculation_currency": "USD",
  "exchange_rate": 1.08,
  "total_amount": 100.00,
  "total_tax": 8.79,
  "total_due": 108.79
}
```

When both the transaction and destination use the same currency (e.g., `USD` transaction to a US address), no conversion occurs and `calculation_currency` and `exchange_rate` are omitted.

## Sample calculation object

The `/calculate` endpoint returns a JSON object containing the transaction details and calculated taxes.

Example response:

```json theme={null}
{
  "data": {
    "id": "a7850851-be24-4c71-b9a3-3035e2d0c617",
    "corporation_id": "74df772f-9260-42cf-9c20-3b613b60fecd",
    "transaction_date": "2025-07-01",
    "transaction_currency": "USD",
    "discount": 0,
    "total_amount": 14338.01,
    "total_tax": 1190.05,
    "total_due": 15528.06,
    "customer_details": {},
    "tax_currency": "USD",
    "addresses": {
      "ship_from": null,
      "ship_to": {
        "address_line_1": "123 N Central Ave",
        "address_line_2": "",
        "address_line_3": "",
        "postal_code": "85004",
        "city": "Phoenix city",
        "state": "AZ",
        "country": "US"
      }
    },
    "line_items": [
      {
        "line_item_id": "51f4ac30-e4f6-42e9-bb34-80305ea870b2",
        "amount": 14338.01,
        "taxable_amount": 14338.01,
        "quantity": 1,
        "tax_code": "TPP",
        "product_id": "",
        "line_number": 1,
        "effective_tax_rate": 8.3,
        "base_tax_rate": 9.1,
        "tax_breakdown": [
          {
            "jurisdiction_name": "ARIZONA",
            "jurisdiction_type": "STATE_OR_PROVINCE",
            "rate": 5.6,
            "base_rate": 5.6,
            "tax_class": "TAXABLE",
            "tax_class_reason": "TAX_APPLIED"
          },
          {
            "jurisdiction_name": "MARICOPA COUNTY",
            "jurisdiction_type": "COUNTY",
            "rate": 0.7,
            "base_rate": 0.7,
            "tax_class": "TAXABLE",
            "tax_class_reason": "TAX_APPLIED"
          },
          {
            "jurisdiction_name": "PHOENIX CITY",
            "jurisdiction_type": "CITY",
            "rate": 2,
            "base_rate": 2.8,
            "tax_class": "TAXABLE",
            "tax_class_reason": "TAX_APPLIED"
          }
        ],
        "total_tax_due": 1190.05,
        "tax_collected": 0,
        "is_tax_included": false,
        "product_source_platform": "",
        "product_source_platform_id": ""
      }
    ]
  }
}
```
