> This page is for version v6.0 (default).
> For other versions, use one of these documentation indexes:
> - v6.0 (default): https://docs.zip.tax/v-6-0/llms.txt
> - v5.0: https://docs.zip.tax/v-5-0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.zip.tax/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.zip.tax/_mcp/server.

# Cart Tax Calculation

Calculate the tax due on a cart of items for one of your
[TaxCloud-connected merchants](taxcloud-connected-merchants).
Use this before you record an order so you can display an accurate tax total at
checkout. The calculation reflects the merchant's own compliance configuration
(registrations, product rules, and exemptions).

> **Info**
>
> This is the **merchant-scoped** cart calculation at `/merchant/cart/calculate`.
> It is different from the general-purpose `/calculate/cart` rate-lookup endpoint,
> which is not tied to a merchant.

## One endpoint, two engines

`/merchant/cart/calculate` serves both [compliance models](merchant-management).
The request body is the same for both, and Ziptax picks the engine from the
`merchantId` you send — you never branch on merchant type when building a
request.

|                                                | TaxCloud-connected merchant                                             | Self-managed merchant                                          |
| ---------------------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------- |
| **Engine**                                     | Forwarded to TaxCloud using the merchant's stored credentials           | Calculated by Ziptax's own rate engine, no TaxCloud call       |
| **Documented on**                              | This page                                                               | [Self-Managed Cart Calculation](self-managed-cart-calculation) |
| **Plan**                                       | Enterprise                                                              | Pro and Enterprise                                             |
| **Discounts, exemptions, `deliveredBySeller`** | Supported                                                               | Rejected with `400`                                            |
| **`tic` vocabulary**                           | TaxCloud codes, e.g. `11010` for shipping                               | Ziptax codes, e.g. `10001` for shipping                        |
| **Result can become an order**                 | Yes, via [`order/create-from-cart`](orders#create-an-order-from-a-cart) | No — the calculation is stateless                              |

> **Warning**
>
> If you serve both merchant types, read
> [Self-Managed Cart Calculation](self-managed-cart-calculation) before you reuse
> this page's payloads. Taxability codes mean different things on the two paths,
> and a TaxCloud shipping code sent for a self-managed merchant is taxed as an
> ordinary product rather than as freight.

The rest of this page describes the TaxCloud-connected path. A connected
merchant with no valid credentials returns `404` (`credentials not found`) —
Ziptax does not fall back to its own engine, because the resulting tax would not
match what the merchant's TaxCloud account files.

## Endpoint

```http
POST https://api.zip-tax.com/merchant/cart/calculate
```

## Request body

| Field             | Type                          | Required | Description                                                                                                                             |
| ----------------- | ----------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `merchantId`      | string (UUID)                 | Yes      | The connected merchant whose TaxCloud connection is used. Must be owned by the calling account. Consumed for routing and not forwarded. |
| `items`           | array of [Cart](#cart-object) | Yes      | The carts to calculate tax for (1–100). Most integrations send a single cart.                                                           |
| `transactionDate` | string (RFC3339 date-time)    | No       | The datetime the carts are calculated for, e.g. `2026-07-13T14:00:00Z`. Defaults to the current time.                                   |

### Cart object

| Field               | Type                                    | Required | Description                                                                                                                                                                                   |
| ------------------- | --------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cartId`            | string (1–50 chars)                     | No       | Your identifier for this cart. If omitted, one is generated and returned; either way, pass it to [`order/create-from-cart`](orders#create-an-order-from-a-cart) to record the sale.           |
| `customerId`        | string (1–50 chars)                     | Yes      | Your identifier for the customer in your own system. Used to match exemption certificates and order history.                                                                                  |
| `origin`            | [Address](#address-object)              | Yes      | The ship-from address of the sale. Used with `destination` to determine sourcing and the applicable jurisdictions.                                                                            |
| `destination`       | [Address](#address-object)              | Yes      | The ship-to address of the sale. Tax is generally calculated for this address in destination-sourced states.                                                                                  |
| `currency`          | object                                  | Yes      | `{ "currencyCode": "USD" }`. The `currency` object itself is required; the inner `currencyCode` (ISO 4217 code the prices are denominated in, `USD` or `CAD`) defaults to `USD` when omitted. |
| `lineItems`         | array of [Line item](#line-item-object) | Yes      | The line items in the cart. Tax is calculated and returned per item.                                                                                                                          |
| `deliveredBySeller` | boolean                                 | No       | Whether the seller delivers the order directly (own vehicles) rather than via common carrier. Affects taxability of delivery charges in some states.                                          |
| `discounts`         | [Discounts](#discounts-object)          | No       | Optional line-item and order-level discounts. If omitted, prices are used as is.                                                                                                              |
| `exemption`         | object                                  | No       | `{ "exemptionId": "...", "isExempt": true }`. Reference an [exemption certificate](exemption-certificates) by id (`isExempt` is then assumed true), or set `isExempt` directly.               |

### Address object

| Field         | Type                   | Required | Description                                                                                                             |
| ------------- | ---------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `line1`       | string (1–128 chars)   | Yes      | First line of the address: street number and name, PO Box, or building. Values longer than 50 characters are truncated. |
| `line2`       | string (max 128 chars) | No       | Second line, if any (apartment, suite, unit). Values longer than 50 characters are truncated.                           |
| `city`        | string (1–50 chars)    | Yes      | City or post-town.                                                                                                      |
| `state`       | string                 | Yes      | Two-letter state or province abbreviation, e.g. `MN`, `CA`, `ON`.                                                       |
| `zip`         | string (1–16 chars)    | Yes      | Postal or ZIP code. Five-digit (`55401`) and ZIP+4 (`55401-2427`) formats are accepted.                                 |
| `countryCode` | string                 | No       | ISO 3166-1 alpha-2 country code: `US` or `CA`. Defaults to `US`.                                                        |

### Line item object

| Field       | Type                  | Required | Description                                                                                                                                                        |
| ----------- | --------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `index`     | integer (0–500)       | Yes      | Zero-based position of the item within the cart. Each item must have a unique index.                                                                               |
| `itemId`    | string (1–50 chars)   | Yes      | Your unique identifier for the line item (e.g. SKU or line reference). Used to match items in later order, refund, and discount operations.                        |
| `price`     | number (≥ 0)          | Yes      | Unit price of the item in the cart's currency. When discounts are provided, this must be the **pre-discount** (original) price.                                    |
| `quantity`  | number (0–99999.9999) | Yes      | Quantity of the item. Fractional quantities are allowed. For larger quantities, send a single line with quantity `1` and the extended (total) amount as the price. |
| `tic`       | integer (0–100000)    | No       | Taxability Information Code classifying the product for product-specific tax rules (e.g. `11010` for shipping). Defaults to `0` (general tangible goods).          |
| `productId` | string                | No       | ID of the product in the merchant's TaxCloud product catalog. Must match an existing catalog product when provided.                                                |

### Discounts object

| Field               | Type   | Required | Description                                                                                                                                                                                                          |
| ------------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lineItemDiscounts` | array  | No       | Discounts applied to specific line items, before any order-level discount. Each entry is `{ "itemId": "...", "type": "percentage" \| "amount", "value": 0.1 }` and must reference a valid `itemId` from `lineItems`. |
| `orderDiscount`     | object | No       | `{ "type": "percentage" \| "amount", "value": 0.1 }`. Applied to the whole order after line-item discounts. Shipping items (TICs 11010–11015) and Colorado retail delivery fees (TIC 11098) are excluded.            |

For `percentage` discounts, `value` is a decimal fraction between 0 and 1
(`0.1` = 10% off); for `amount` discounts it is a fixed currency amount. When
you provide discounts, line-item prices must be pre-discount originals — if
your prices are already discounted, omit the `discounts` field.

## Example

#### cURL

```bash
curl -X POST "https://api.zip-tax.com/merchant/cart/calculate" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "6b3c1f5e-2a8d-4c9b-9f2e-1d7a4b6c8e10",
    "transactionDate": "2026-07-13T14:00:00Z",
    "items": [
      {
        "cartId": "cart-2026-000123",
        "customerId": "customer-453",
        "currency": { "currencyCode": "USD" },
        "origin": { "line1": "1 Market St", "city": "San Francisco", "state": "CA", "zip": "94105" },
        "destination": { "line1": "200 Spectrum Center Dr", "city": "Irvine", "state": "CA", "zip": "92618" },
        "lineItems": [
          { "index": 0, "itemId": "sku-1001", "price": 49.99, "quantity": 2, "tic": 0 }
        ]
      }
    ]
  }'
```

#### Python

```python
import requests

res = requests.post(
    "https://api.zip-tax.com/merchant/cart/calculate",
    headers={"X-API-KEY": "YOUR_API_KEY"},
    json={
        "merchantId": "6b3c1f5e-2a8d-4c9b-9f2e-1d7a4b6c8e10",
        "transactionDate": "2026-07-13T14:00:00Z",
        "items": [
            {
                "cartId": "cart-2026-000123",
                "customerId": "customer-453",
                "currency": {"currencyCode": "USD"},
                "origin": {"line1": "1 Market St", "city": "San Francisco", "state": "CA", "zip": "94105"},
                "destination": {"line1": "200 Spectrum Center Dr", "city": "Irvine", "state": "CA", "zip": "92618"},
                "lineItems": [
                    {"index": 0, "itemId": "sku-1001", "price": 49.99, "quantity": 2, "tic": 0},
                ],
            }
        ],
    },
)
res.raise_for_status()
cart = res.json()
```

#### Node.js

```javascript
const res = await fetch("https://api.zip-tax.com/merchant/cart/calculate", {
  method: "POST",
  headers: {
    "X-API-KEY": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    merchantId: "6b3c1f5e-2a8d-4c9b-9f2e-1d7a4b6c8e10",
    transactionDate: "2026-07-13T14:00:00Z",
    items: [
      {
        cartId: "cart-2026-000123",
        customerId: "customer-453",
        currency: { currencyCode: "USD" },
        origin: { line1: "1 Market St", city: "San Francisco", state: "CA", zip: "94105" },
        destination: { line1: "200 Spectrum Center Dr", city: "Irvine", state: "CA", zip: "92618" },
        lineItems: [
          { index: 0, itemId: "sku-1001", price: 49.99, quantity: 2, tic: 0 },
        ],
      },
    ],
  }),
});
const cart = await res.json();
```

## Response

Returns the calculated carts with tax computed per line item.

| Field                                    | Type                       | Description                                                                                                   |
| ---------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `connectionId`                           | string                     | The TaxCloud connection the calculation ran under.                                                            |
| `transactionDate`                        | string (RFC3339 date-time) | The datetime the carts were calculated for.                                                                   |
| `items`                                  | array                      | One calculated cart per submitted cart, in the same order.                                                    |
| `items[].cartId`                         | string                     | Identifier of the calculated cart. Pass it to [`order/create-from-cart`](orders#create-an-order-from-a-cart). |
| `items[].customerId`                     | string                     | Your customer identifier, as submitted.                                                                       |
| `items[].deliveredBySeller`              | boolean                    | Whether the seller delivers the order directly, as submitted.                                                 |
| `items[].origin` / `items[].destination` | [Address](#address-object) | The addresses, as submitted.                                                                                  |
| `items[].exemption`                      | object                     | The exemption information applied to the calculation.                                                         |
| `items[].currency`                       | object                     | The currency the prices and tax amounts are denominated in.                                                   |
| `items[].lineItems[].index`              | integer                    | Zero-based position of the item within the cart.                                                              |
| `items[].lineItems[].itemId`             | string                     | Your line item identifier, as submitted.                                                                      |
| `items[].lineItems[].tic`                | integer or null            | The TIC the item was calculated under.                                                                        |
| `items[].lineItems[].price`              | number                     | The unit price tax was calculated on (discounted, when discounts applied).                                    |
| `items[].lineItems[].originalPrice`      | number                     | The original pre-discount unit price, as submitted.                                                           |
| `items[].lineItems[].quantity`           | number                     | Quantity of the item.                                                                                         |
| `items[].lineItems[].tax.rate`           | number                     | The combined tax rate applied, as a decimal fraction (e.g. `0.08125` = 8.125%).                               |
| `items[].lineItems[].tax.amount`         | number                     | The calculated tax amount for the line item.                                                                  |

```json
{
  "connectionId": "25eb9b97-5acb-492d-b720-c03e79cf715a",
  "transactionDate": "2026-07-13T14:00:00Z",
  "items": [
    {
      "cartId": "cart-2026-000123",
      "customerId": "customer-453",
      "deliveredBySeller": false,
      "origin": { "line1": "1 Market St", "city": "San Francisco", "state": "CA", "zip": "94105", "countryCode": "US" },
      "destination": { "line1": "200 Spectrum Center Dr", "city": "Irvine", "state": "CA", "zip": "92618", "countryCode": "US" },
      "exemption": { "exemptionId": null, "isExempt": null },
      "currency": { "currencyCode": "USD" },
      "lineItems": [
        {
          "index": 0,
          "itemId": "sku-1001",
          "tic": 0,
          "price": 49.99,
          "originalPrice": 49.99,
          "quantity": 2,
          "tax": { "rate": 0.0775, "amount": 7.75 }
        }
      ]
    }
  ]
}
```

> **Warning**
>
> If you do not receive a response, it is safe to call `cart/calculate` again:
> calculation has no lasting side effect. Do **not**, however, retry
> [order](orders) or [refund](refunds) writes blindly. See
> [Retries and idempotency](transactions#retries-and-idempotency).

## Related

#### [Self-Managed Cart Calculation](self-managed-cart-calculation)

The same endpoint for a self-managed merchant, calculated by Ziptax.

#### [Orders](orders)

Turn a calculated cart into a recorded order.

#### [Merchant Transactions](transactions)

Shared conventions, errors, and usage.