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

# Transactions

> Record sales and refunds for filing

A transaction records a completed sale. Numeral files and remits tax based on the transactions recorded in each jurisdiction and period. Create one from a [calculation](https://docs.numeral.com/v2026-11-01/objects/calculations.md) after the customer pays. Record returns against it as refunds.

```text Where transactions fit theme={null}
Sale
├─ POST /tax/calculations    → calculation id
├─ Customer pays
├─ POST /tax/transactions    → transaction id   (store it)
└─ Customer returns an item
      └─ POST /tax/refunds   → refund id
```

Endpoints
[Create a transactionPOST/tax/transactions](#create-a-transaction)
[Retrieve a transactionGET/tax/transactions/:id](#retrieve-a-transaction)
[List transactions for an orderGET/tax/transactions?reference\_order\_id=](#list-transactions-for-an-order)
[Delete a transactionDELETE/tax/transactions/:id](#delete-a-transaction)
[Create a refundPOST/tax/refunds](#create-a-refund)
[List refunds for a transactionGET/tax/transactions/:id/refunds](#list-refunds-for-a-transaction)
[Reverse a refundPOST/tax/refund\_reversals](#reverse-a-refund)

## The Transaction object

### Attributes

**id** `string`

The ID of the transaction, `tr_…`. Store it: refunds and lookups use it.

**object** `string, value is "tax.transaction"`

String representing the object's type.

**calculation\_id** `string`

The calculation this transaction was created from.

**reference\_order\_id** `string`

Your order ID, as sent when creating the transaction.

**reference\_payment\_id** `string`

Your payment ID. Empty when not set. Returned by the GET endpoints.

**customer\_currency\_code** `string`

ISO 4217 currency the customer paid in.

**filing\_currency\_code** `string`

Currency the tax on this transaction will be filed in.

**filing\_currency\_code\_rate** `number`

Exchange rate from the customer currency to the filing currency. `0` when they're the same. Returned by the GET endpoints.

**address\_line\_1** `string`

The address the tax was calculated for. `address_line_2` (can be `null`), `address_city`, `address_province`, `address_postal_code` and `address_country` follow the same pattern. Returned by the GET endpoints.

**line\_items** `array of objects`

The line items from the calculation.

**line\_items\[].line\_item\_id** `string`

Numeral-generated ID for this line item. Use it in partial refunds.

**line\_items\[].product** `object`

`reference_line_item_id`, `reference_product_id`, `reference_product_name` and `product_tax_code`, as on the [calculation](https://docs.numeral.com/v2026-11-01/objects/calculations.md#the-calculation-object).

**line\_items\[].tax\_jurisdictions** `array of objects`

One row per taxing jurisdiction: `tax_rate`, `tax_due_decimal`, `fee_amount`, `rate_type`, `tax_authority_name`, `tax_authority_type`, `tax_type`, and `note`. Same fields as on the [calculation](https://docs.numeral.com/v2026-11-01/objects/calculations.md#the-calculation-object).

**line\_items\[].tax\_jurisdictions\[].note** `string`

**New in 2026-11-01.** Why this row came out the way it did. Empty string for normally calculated tax. See [Notes](https://docs.numeral.com/v2026-11-01/objects/calculations.md#notes). Transactions created before this version was released may return an empty note.

**line\_items\[].tax\_amount** `integer`

Tax on the line, in the currency's smallest unit.

**line\_items\[].amount\_excluding\_tax** `integer`

Line amount before tax.

**line\_items\[].amount\_including\_tax** `integer`

Line amount including tax.

**line\_items\[].quantity** `number`

Quantity sold.

**line\_items\[].type** `string`

Sale type for the line, e.g. `b2c`.

**transaction\_processed\_at** `timestamp`

Unix seconds when the sale was made.

**transaction\_type** `string`

`PURCHASE` for a sale. Returned by the GET endpoints.

**created\_at** `timestamp`

Unix seconds when the transaction was recorded. `updated_at` follows the same pattern. Returned by the GET endpoints.

**testmode** `boolean`

`true` if made with a test API key. Live transactions count toward your nexus totals, and Numeral files them where you're registered.

**metadata** `object`

Key-value pairs from the request, echoed unchanged. Only present when sent.

> [!NOTE]
>
> Transactions don't have an `effective_tax_rate`. Use the one on the calculation, or divide `tax_amount` by `amount_excluding_tax`.

```json The Transaction object theme={null}
{
  "object": "tax.transaction",
  "id": "tr_1793039302001",
  "calculation_id": "calc_1793039299123",
  "customer_currency_code": "USD",
  "filing_currency_code": "USD",
  "filing_currency_code_rate": 0,
  "reference_order_id": "order-1001",
  "reference_payment_id": "",
  "address_line_1": "233 S Wacker Dr",
  "address_line_2": null,
  "address_city": "Chicago",
  "address_province": "IL",
  "address_postal_code": "60606",
  "address_country": "US",
  "line_items": [
    {
      "line_item_id": "li_1793039299101",
      "product": {
        "reference_line_item_id": "widget",
        "reference_product_id": "default-general-merchandise",
        "reference_product_name": "Default GENERAL_MERCHANDISE Product",
        "product_tax_code": "GENERAL_MERCHANDISE"
      },
      "tax_jurisdictions": [
        {
          "tax_rate": 0.0625,
          "tax_due_decimal": 625,
          "fee_amount": 0,
          "rate_type": "GENERAL STATE SALES TAX",
          "tax_authority_name": "Illinois",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        },
        {
          "tax_rate": 0.03,
          "tax_due_decimal": 300,
          "fee_amount": 0,
          "rate_type": "GENERAL COUNTY LOCAL SALES TAX",
          "tax_authority_name": "Cook County",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        },
        {
          "tax_rate": 0.0125,
          "tax_due_decimal": 125,
          "fee_amount": 0,
          "rate_type": "GENERAL CITY LOCAL SALES TAX",
          "tax_authority_name": "Chicago",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        }
      ],
      "tax_amount": 1050,
      "amount_excluding_tax": 10000,
      "amount_including_tax": 11050,
      "quantity": 2,
      "type": "b2c"
    },
    {
      "line_item_id": "li_1793039299102",
      "product": {
        "reference_line_item_id": "shipping",
        "reference_product_id": "default-shipping",
        "reference_product_name": "Default SHIPPING Product",
        "product_tax_code": "SHIPPING"
      },
      "tax_jurisdictions": [
        {
          "tax_rate": 0.0625,
          "tax_due_decimal": 62.5,
          "fee_amount": 0,
          "rate_type": "GENERAL STATE SALES TAX",
          "tax_authority_name": "Illinois",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        },
        "... Cook County and Chicago rows ..."
      ],
      "tax_amount": 105,
      "amount_excluding_tax": 1000,
      "amount_including_tax": 1105,
      "quantity": 1,
      "type": "b2c"
    }
  ],
  "transaction_processed_at": 1793039302,
  "transaction_type": "PURCHASE",
  "created_at": 1793039302,
  "updated_at": 1793039302,
  "testmode": true
}
```

## Create a transaction

Records a sale from a calculation. Create it after the customer pays and before the calculation expires (24 hours). [Try it in the API reference](https://docs.numeral.com/api-reference/v2026-11-01/endpoint/transactions).

The transaction comes back in the shape of the `X-API-Version` you send now, whatever version the calculation was made on.

### Parameters

**calculation\_id** `string` *required*

The `id` of the calculation to record.

**reference\_order\_id** `string` *required*

Your order ID. Must be unique across your transactions.

**transaction\_processed\_at** `integer`

When the sale was made, Unix **seconds**. Defaults to now.

**metadata** `object`

String key-value pairs, echoed back in the response.

### Returns

A [Transaction object](#the-transaction-object), without the GET-only fields.

```bash POST /tax/transactions theme={null}
curl https://api.numeralhq.com/tax/transactions \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Version: 2026-11-01' \
  -d '{
    "calculation_id": "calc_1793039299123",
    "reference_order_id": "order-1001"
  }'
```

```json Response theme={null}
{
  "testmode": true,
  "id": "tr_1793039302001",
  "object": "tax.transaction",
  "calculation_id": "calc_1793039299123",
  "filing_currency_code": "USD",
  "customer_currency_code": "USD",
  "line_items": [
    {
      "line_item_id": "li_1793039299101",
      "product": { "...": "..." },
      "tax_jurisdictions": [
        {
          "tax_rate": 0.0625,
          "tax_due_decimal": 625,
          "fee_amount": 0,
          "rate_type": "GENERAL STATE SALES TAX",
          "tax_authority_name": "Illinois",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        },
        "..."
      ],
      "tax_amount": 1050,
      "amount_excluding_tax": 10000,
      "amount_including_tax": 11050,
      "quantity": 2,
      "type": "b2c"
    },
    "..."
  ],
  "reference_order_id": "order-1001",
  "transaction_processed_at": 1793039302
}
```

## Retrieve a transaction

Returns a transaction by its `id`.

**transaction\_id** `string` *required*

The transaction's `id`.

### Returns

A [Transaction object](#the-transaction-object).

```bash GET /tax/transactions/:id theme={null}
curl https://api.numeralhq.com/tax/transactions/tr_1793039302001 \
  -H 'Authorization: Bearer <token>' \
  -H 'X-API-Version: 2026-11-01'
```

## List transactions for an order

Returns the transactions recorded with a given `reference_order_id`.

**reference\_order\_id** `string` *required*

Your order ID.

### Returns

An object with a `transactions` array of [Transaction objects](#the-transaction-object).

```bash GET /tax/transactions theme={null}
curl 'https://api.numeralhq.com/tax/transactions?reference_order_id=order-1001' \
  -H 'Authorization: Bearer <token>' \
  -H 'X-API-Version: 2026-11-01'
```

```json Response theme={null}
{
  "transactions": [
    {
      "object": "tax.transaction",
      "id": "tr_1793039302001",
      "reference_order_id": "order-1001",
      "...": "see The Transaction object"
    }
  ]
}
```

## Delete a transaction

Deletes a transaction, for example one recorded by mistake. To record a return, [create a refund](#create-a-refund) instead.

**transaction\_id** `string` *required*

The transaction's `id`.

### Returns

The deleted object type and when it was deleted.

```bash DELETE /tax/transactions/:id theme={null}
curl -X DELETE https://api.numeralhq.com/tax/transactions/tr_1793039302001 \
  -H 'Authorization: Bearer <token>' \
  -H 'X-API-Version: 2026-11-01'
```

```json Response theme={null}
{
  "object": "tax.transaction",
  "deleted_at": 1793040000
}
```

## The Refund object

A refund records money returned to the customer against a transaction. Amounts are negative.

### Attributes

**id** `string`

The ID of the refund, `ref_tr_…`. Store it: reversing the refund needs it.

**object** `string, value is "tax.refund"`

String representing the object's type.

**refund\_type** `enum`

`full` or `partial`. Returned when the refund is created.

**refund\_processed\_at** `timestamp`

Unix seconds when the refund was made.

**testmode** `boolean`

`true` if made with a test API key.

**line\_items** `array of objects`

The refunded line items. Same fields as the transaction's line items.

**line\_items\[].tax\_jurisdictions** `array of objects`

The original sale's rows, including `note`, with the sale's rates and `tax_due_decimal`.

**line\_items\[].tax\_amount** `integer`

Tax refunded on this line (negative).

**line\_items\[].amount\_excluding\_tax** `integer`

Sale amount refunded on this line (negative).

**line\_items\[].amount\_including\_tax** `integer`

Total refunded on this line (negative).

**line\_items\[].quantity** `number`

Quantity refunded.

```json The Refund object theme={null}
{
  "object": "tax.refund",
  "id": "ref_tr_1793039302101",
  "refund_processed_at": 1793039302,
  "refund_type": "partial",
  "testmode": true,
  "line_items": [
    {
      "line_item_id": "li_1793039299101",
      "product": {
        "reference_line_item_id": "widget",
        "reference_product_id": "default-general-merchandise",
        "reference_product_name": "Default GENERAL_MERCHANDISE Product",
        "product_tax_code": "GENERAL_MERCHANDISE"
      },
      "tax_jurisdictions": [
        {
          "tax_rate": 0.0625,
          "tax_due_decimal": 625,
          "fee_amount": 0,
          "rate_type": "GENERAL STATE SALES TAX",
          "tax_authority_name": "Illinois",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        },
        {
          "tax_rate": 0.03,
          "tax_due_decimal": 300,
          "fee_amount": 0,
          "rate_type": "GENERAL COUNTY LOCAL SALES TAX",
          "tax_authority_name": "Cook County",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        },
        {
          "tax_rate": 0.0125,
          "tax_due_decimal": 125,
          "fee_amount": 0,
          "rate_type": "GENERAL CITY LOCAL SALES TAX",
          "tax_authority_name": "Chicago",
          "tax_authority_type": "",
          "tax_type": "SALES",
          "note": ""
        }
      ],
      "tax_amount": -525,
      "amount_excluding_tax": -5000,
      "amount_including_tax": -5525,
      "quantity": 1,
      "type": "b2c"
    }
  ]
}
```

## Create a refund

Records a full or partial refund against a transaction. [Try it in the API reference](https://docs.numeral.com/api-reference/v2026-11-01/endpoint/refunds).

### Parameters

**transaction\_id** `string` *required*

The `id` of the transaction to refund.

**type** `enum` *required*

`full` refunds everything. `partial` refunds the `line_items` you send.

**refund\_processed\_at** `integer`

When the refund was made, Unix **seconds**. Defaults to now.

**line\_items** `array of objects`

Required for `partial` refunds.

**line\_items\[].line\_item\_id** `string`

The transaction line to refund. Or identify it by `reference_product_id`.

**line\_items\[].reference\_product\_id** `string`

The product to refund, matched against the original transaction's lines.

**line\_items\[].sales\_amount\_refunded** `integer` *required*

Sale amount refunded, excluding tax, as a negative number in the currency's smallest unit.

**line\_items\[].tax\_amount\_refunded** `integer` *required*

Tax refunded, as a negative number.

**line\_items\[].quantity** `number` *required*

Quantity refunded.

**line\_items\[].reference\_line\_item\_id** `string`

Your line item ID, used only for reporting.

### Returns

A [Refund object](#the-refund-object).

```bash POST /tax/refunds theme={null}
curl https://api.numeralhq.com/tax/refunds \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Version: 2026-11-01' \
  -d '{
    "transaction_id": "tr_1793039302001",
    "type": "partial",
    "line_items": [
      {
        "line_item_id": "li_1793039299101",
        "sales_amount_refunded": -5000,
        "tax_amount_refunded": -525,
        "quantity": 1
      }
    ]
  }'
```

## List refunds for a transaction

Returns every refund recorded against a transaction.

**transaction\_id** `string` *required*

The transaction's `id`.

### Returns

An object with a `refunds` array of [Refund objects](#the-refund-object), without `refund_type`.

```bash GET /tax/transactions/:id/refunds theme={null}
curl https://api.numeralhq.com/tax/transactions/tr_1793039302001/refunds \
  -H 'Authorization: Bearer <token>' \
  -H 'X-API-Version: 2026-11-01'
```

```json Response theme={null}
{
  "refunds": [
    {
      "object": "tax.refund",
      "id": "ref_tr_1793039302101",
      "refund_processed_at": 1793039302,
      "testmode": true,
      "line_items": ["..."]
    }
  ]
}
```

## Reverse a refund

Undoes a refund you created, for example one recorded by mistake.

**refund\_id** `string` *required*

The `id` of the refund to reverse.

### Returns

A [Refund object](#the-refund-object) for the reversal.

```bash POST /tax/refund_reversals theme={null}
curl https://api.numeralhq.com/tax/refund_reversals \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Version: 2026-11-01' \
  -d '{ "refund_id": "ref_tr_1793039302101" }'
```

## Errors

Errors return `code`, `type`, and `message`. Handle them by `type`. Full list in [Error Codes](https://docs.numeral.com/api-reference/v2026-11-01/error-codes.md).

| HTTP | `type` | When |
| - | - | - |
| 400 | `MISSING_FIELD` | A required field is missing. |
| 400 | `INCORRECT_TYPE` | A field has the wrong type. |
| 400 | `UNRECOGNIZED_FIELD` | An unknown field was sent. |
| 400 | `NEGATIVE_NUMBER_REQUIRED` | A refund amount isn't negative. |
| 400 | `CALCULATION_EXPIRED` | The calculation is more than 24 hours old. Create a new one. |
| 400 | `TRANSACTION_ALREADY_EXISTS` | A transaction already exists for this `calculation_id`. |
| 400 | `REFERENCE_ORDER_ID_ALREADY_EXISTS` | A transaction already exists with this `reference_order_id`. |
| 404 | `CALCULATION_NOT_FOUND` | `calculation_id` doesn't exist in this environment (test or live). |
| 404 | `TRANSACTION_NOT_FOUND` | `transaction_id` doesn't exist. |

```json 404 theme={null}
{
  "code": 404,
  "type": "CALCULATION_NOT_FOUND",
  "message": "Unable to find calculation with ID: calc_does_not_exist in test environment."
}
```


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