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

# Tax on a line item

> Report sales tax your billing system put on a line item instead of the tax field

Some billing systems record collected sales tax as a line item, for example a "Sales Tax" item on an invoice, instead of in the transaction's tax field. Mark such a line with the `SALES_TAX` product tax code and Taxwire treats its amount as tax collected, not as something sold.

```json theme={null}
{
    "id": "tax_line",
    "quantity": "1",
    "product": {
        "tax_attributes": ["SALES_TAX"]
    },
    "unit_price": "635"
}
```

## What happens to the line

**Transactions.** When you create or update a transaction, Taxwire removes every `SALES_TAX` line from `line_items` and adds its amount (`unit_price` × `quantity`) to the transaction's `tax_amount`. The line is never taxed and never counts toward the taxable base, gross sales or economic nexus thresholds. The response shows the remaining line items and the combined `tax_amount`. It does not return the removed lines, so keep your own copy if you need to send them again.

Any `SALES_TAX` line, even one of `0`, gives the transaction a provided tax: `filing_tax_amount` is the combined `tax_amount` with `filing_tax_amount_source: "provided"`, not the tax Taxwire calculates. Transaction-level discounts apply to the remaining line items only.

**Calculations.** `POST /calculations` accepts the line and leaves it out of the taxable base. The response lists it by `id` with a `tax_amount` of `0`, and the calculation's total `tax_amount` does not include it. A calculation has no provided tax to add the line to, so sum your `SALES_TAX` lines yourself if you need the total collected.

## Send the tax in one place

The tax field and `SALES_TAX` lines are added together. If `tax_amount` already includes the tax on a `SALES_TAX` line, don't also send the line: Taxwire adds both, and your returns report the sum as tax collected.

## Rules

A `SALES_TAX` line must:

* carry `SALES_TAX` as its only tax attribute: no other code beside it (`["SALES_TAX", "TANGIBLE_PERSONAL_PROPERTY"]`) and no attribute suffix (`SALES_TAX._B2B`)
* have no discount: no non-zero `discounts`, `discount_amount` or `vendor_discount_amount`; send the tax actually collected
* have a non-negative amount; for a refund, use a `credit` transaction with positive amounts, as with any other line. If your system records a correction as a second, negative tax line, net the tax lines into one before sending.
* have an `id` no other line in the transaction uses

The code is case-sensitive: `sales_tax` is not recognised.

A line that breaks a rule is refused with HTTP 422 and the error code `validation_error`:

* On transactions, `detail` names the line and the rule, for example `line item 'tax_line': a SALES_TAX line cannot carry a discount`.
* On `POST /calculations`, `detail` is `Validation failed: invalid_sales_tax_line`, or `Validation failed: multiple errors` if the request has other validation errors too (`Processing failed: multiple errors` if one of them is a calculation error). It does not name the line.

## Marking a product

If your line items reference products through [presets](/api-reference/guides/presets), you can mark the product instead of each line. In the [Taxwire App](https://app.taxwire.com), open the product on the [Products](https://app.taxwire.com/products) page and choose **Collected sales tax** (`SALES_TAX`) as its only tax code. It is not offered in bulk assign and can't be your default tax code.

Every line that references the product through its preset is then treated as a `SALES_TAX` line, on transactions and on calculations. Tax attributes sent on the line itself take precedence over the product's.

A marked product's line may carry discounts: Taxwire uses the line's amount less its own discounts, rounded to the smallest currency unit. The other rules apply as above. If that amount is negative:

* on transactions, the line is refused with HTTP 422, like a line you declared yourself;
* on `POST /calculations`, the line is left out of the calculation and returned with a `tax_amount` of `0`, and the request does not fail.

On QuickBooks, NetSuite and Stripe invoices, a negative marked line is netted with the document's other marked lines instead. A net of 0 or more is kept as one line. A negative net lowers the document's tax, never below 0, and leaves its goods lines unchanged. A sale, or a credit with no parent, whose only lines are marked lines netting below 0 is not recorded on NetSuite or Stripe; on QuickBooks it is stored with no line items and its tax stays off returns. Stripe credit notes are not netted.

### When a mark takes effect

* Marking or un-marking a product changes how Taxwire records the transactions it receives after the change.
* Transactions Taxwire already stored are not converted until the source sends them again: any re-sync for Stripe and NetSuite, a newer version of the order for Shopify, the document again for QuickBooks. For a transaction you created through the API, that means sending its `line_items` again (see [Updating a transaction](#updating-a-transaction)). If a stored transaction is recalculated before then, the marked line is left out of its sales but not added to its collected tax.
* QuickBooks lines keep the tax code they arrived with, so a QuickBooks transaction stored before the mark keeps the line as a taxed sale, on recalculation and in nexus studies, until QuickBooks sends it again.
* Un-marking a product does not turn transactions already recorded as collected tax back into sales until the source sends them again.
* Nexus studies apply the product's current mark to the line items of stored transactions from the next study. Un-marking counts a line as a sale again only on transactions that still list it; lines already recorded as collected tax stay out of nexus until the source sends the transaction again.

## Updating a transaction

* **Sending `line_items`** (draft transactions only): send the full list again, including the `SALES_TAX` lines. The tax amount is recomputed from these lines plus the `tax_amount` you send, or the one you sent before if you omit it. A `SALES_TAX` line you leave out is removed from the tax amount. If no `SALES_TAX` line and no `tax_amount` are left, the transaction has no provided tax and Taxwire uses the tax it calculates.
* **Sending only `tax_amount`**: it replaces the `tax_amount` you sent before. `SALES_TAX` lines already counted in the tax amount stay counted.

<Warning>
  The `tax_amount` in a transaction response already includes the `SALES_TAX` lines. Don't send it back as `tax_amount` on an update, or those lines are added again. Send only the tax you collected outside the lines.
</Warning>

To change the line items of a finalized transaction, set its status to `draft`, then send `line_items` with `status: finalized` in a second call. A filed transaction's line items can't be changed.

## Tax-only transactions

A sale, or a credit sent without `parent_transaction_id` or `parent_reference_id`, whose only line items are `SALES_TAX` lines is stored with no line items. Taxwire reports its tax on your returns in the jurisdictions of the customer address on the `SALES_TAX` lines, with gross and taxable sales of 0. The tax is split equally across the jurisdictions that address reaches where you are registered. Lines at several addresses share the total equally across the jurisdictions they reach where you are registered, whatever each line held. If you are registered in none of them, the tax is on no return.

Every `SALES_TAX` line on a tax-only transaction needs a customer address. Without one, Taxwire stores the transaction but holds it off returns.

A tax-only credit that names a parent transaction is not reported yet; see [Limitations](#limitations).

## Examples

Amounts are in the smallest currency unit, so `635` is \$6.35. The "Tax in both places" example leaves customer addresses out.

<CodeGroup>
  ```jsonc Sale with a tax line theme={null}
  // POST /transactions
  {
      "type": "sale",
      "status": "finalized",
      "currency": "USD",
      "transaction_date": "2026-09-01T12:00:00Z",
      "line_items": [
          {
              "id": "item_1",
              "quantity": "1",
              "product": { "tax_attributes": ["TANGIBLE_PERSONAL_PROPERTY"] },
              "customer": { "address": { "line1": "100 Main St", "city": "Hartford", "state": "CT", "postal_code": "06103", "country": "US" } },
              "unit_price": "10000"
          },
          {
              "id": "tax_line",
              "quantity": "1",
              "product": { "tax_attributes": ["SALES_TAX"] },
              "customer": { "address": { "line1": "100 Main St", "city": "Hartford", "state": "CT", "postal_code": "06103", "country": "US" } },
              "unit_price": "635"
          }
      ]
  }

  // Response: line_items = [item_1], tax_amount = "635",
  // filing_tax_amount = "635", filing_tax_amount_source = "provided"
  ```

  ```jsonc Tax in both places theme={null}
  // POST /transactions: tax_amount and the line both carry $6.35
  {
      "type": "sale",
      "status": "finalized",
      "currency": "USD",
      "transaction_date": "2026-09-01T12:00:00Z",
      "tax_amount": "635",
      "line_items": [
          { "id": "item_1", "quantity": "1", "product": { "tax_attributes": ["TANGIBLE_PERSONAL_PROPERTY"] }, "unit_price": "10000" },
          { "id": "tax_line", "quantity": "1", "product": { "tax_attributes": ["SALES_TAX"] }, "unit_price": "635" }
      ]
  }

  // Response: tax_amount = "1270"; returns report $12.70 collected
  ```

  ```jsonc Tax-only sale theme={null}
  // POST /transactions: an invoice that only collects tax
  {
      "type": "sale",
      "status": "finalized",
      "currency": "USD",
      "transaction_date": "2026-09-01T12:00:00Z",
      "line_items": [
          {
              "id": "tax_line",
              "quantity": "1",
              "product": { "tax_attributes": ["SALES_TAX"] },
              "customer": { "address": { "line1": "100 Main St", "city": "Hartford", "state": "CT", "postal_code": "06103", "country": "US" } },
              "unit_price": "635"
          }
      ]
  }

  // Response: line_items = [], tax_amount = "635"
  // Reported in Connecticut as $6.35 collected, with gross and taxable sales of 0,
  // if you are registered in Connecticut
  ```

  ```jsonc Tax-only refund theme={null}
  // POST /transactions: refund of the tax alone, linked to the original sale
  {
      "type": "credit",
      "status": "finalized",
      "currency": "USD",
      "transaction_date": "2026-09-05T12:00:00Z",
      "parent_transaction_id": "txn_01J...",
      "line_items": [
          {
              "id": "tax_line",
              "quantity": "1",
              "product": { "tax_attributes": ["SALES_TAX"] },
              "customer": { "address": { "line1": "100 Main St", "city": "Hartford", "state": "CT", "postal_code": "06103", "country": "US" } },
              "unit_price": "635"
          }
      ]
  }

  // Response: line_items = [], tax_amount = "635", linked to the parent sale
  // Not reported on returns yet: see Limitations
  ```
</CodeGroup>

## Limitations

* **A credit without line items does not reverse `SALES_TAX` lines.** A credit with a `parent_transaction_id` and no `line_items` copies the parent's stored line items, which no longer include its `SALES_TAX` lines. Its tax is calculated on those line items, so it reverses the tax Taxwire calculates on them, not the tax the parent carried in `tax_amount` or as `SALES_TAX` lines. To reverse all of it, send the credit's `tax_amount` yourself, or send the same `line_items` and `tax_amount` you sent on the sale. A tax-only sale can't be reversed this way: its stored line items are empty, so the credit copies nothing and stays off returns. If you marked a product after the sale was calculated, the copied line on that product is left out of the credit, so the credit does not reverse the tax the sale calculated on it.
* **A tax-only credit that names a parent is not reported yet.** Taxwire stores a credit whose only line items are `SALES_TAX` lines and that has a `parent_transaction_id` or `parent_reference_id`, even one that never matches a transaction, but holds it off returns.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.