> ## 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.

# Customers

> Store your buyers and mark them tax exempt

A customer is one of your buyers. Create one to keep track of repeat purchases, or to mark a buyer as tax exempt. Exempt buyers are often wholesalers, religious groups, or educational institutions. Pass the customer on a [calculation](https://docs.numeral.com/v2025-05-12/objects/calculations.md) as `customer.id`.

```text Where customers fit theme={null}
Setup
└─ POST /tax/customers       send: email (+ is_tax_exempt)  → customer id
Checkout
└─ POST /tax/calculations    send: customer.id
```

Endpoints
[Create a customerPOST/tax/customers](#create-a-customer)
[Update a customerPOST/tax/customers/:id](#update-a-customer)
[Retrieve a customerGET/tax/customers/:id](#retrieve-a-customer)
[Delete a customerDELETE/tax/customers/:id](#delete-a-customer)

## The Customer object

### Attributes

**id** `string`

The ID of the customer, `cust_…`.

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

String representing the object's type.

**reference\_customer\_id** `string`

Your ID for the customer. Unique across your customers. You can use it instead of `id` to refer to the customer.

**name** `string`

The customer's name.

**email** `string`

The customer's email. Unique across your customers.

**is\_tax\_exempt** `boolean`

If `true`, every calculation for this customer returns 0 tax. Defaults to `false`.

```json The Customer object theme={null}
{
  "id": "cust_6126acaf-7379-411a-8ada-00005bac0715",
  "object": "tax.customer",
  "reference_customer_id": "20506",
  "name": "Customer Name",
  "email": "customer@example.com",
  "is_tax_exempt": true
}
```

## Use a customer in a calculation

Send the customer's `id` or your `reference_customer_id` as `customer.id` on a [calculation](https://docs.numeral.com/v2025-05-12/objects/calculations.md#create-a-calculation).

For a tax-exempt customer, the calculation returns 0 tax. The `tax_jurisdictions` row has `note: "no_collection_exempt_customer"`, which tells you the customer's exemption is the reason.

```bash POST /tax/calculations theme={null}
curl https://api.numeralhq.com/tax/calculations \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Version: 2025-05-12' \
  -d '{
    "customer": {
      "id": "20506",
      "address": {
        "address_line_1": "4 Privet Drive",
        "address_city": "Little Whinging",
        "address_province": "CA",
        "address_postal_code": "90210",
        "address_country": "US",
        "address_type": "shipping"
      }
    },
    "origin_address": {
      "address_line_1": "3990 N County Rd 300 E",
      "address_city": "Danville",
      "address_province": "IN",
      "address_postal_code": "46122",
      "address_country": "US"
    },
    "order_details": {
      "customer_currency_code": "USD",
      "tax_included_in_amount": false,
      "automatic_tax": "auto",
      "line_items": [
        {
          "reference_line_item_id": "line_123456789",
          "product_category": "GENERAL_MERCHANDISE",
          "amount": 200,
          "quantity": 2
        }
      ]
    }
  }'
```

```json Exempt customer response theme={null}
{
  "object": "tax.calculation",
  "line_items": [
    {
      "tax_jurisdictions": [
        {
          "tax_rate": 0,
          "rate_type": "Sales Tax",
          "jurisdiction_name": "State Tax",
          "fee_amount": 0,
          "note": "no_collection_exempt_customer"
        }
      ],
      "tax_amount": 0,
      "amount_excluding_tax": 200,
      "amount_including_tax": 200,
      "quantity": 2
    }
  ],
  "total_tax_amount": 0,
  "total_amount_excluding_tax": 200,
  "total_amount_including_tax": 200,
  "...": "see The Calculation object"
}
```

## Create a customer

Creates a customer. Only `email` is required. [Try it in the API reference](https://docs.numeral.com/api-reference/v2025-05-12/endpoint/customers).

The response has a Numeral `id`. If you sent a `reference_customer_id`, you can use either one to refer to the customer later.

### Parameters

**email** `string` *required*

The customer's email.

**name** `string`

The customer's name.

**reference\_customer\_id** `string`

Your ID for the customer.

**is\_tax\_exempt** `boolean` (default: false)

If `true`, every calculation for this customer returns 0 tax.

### Returns

A [Customer object](#the-customer-object).

```bash POST /tax/customers theme={null}
curl https://api.numeralhq.com/tax/customers \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Version: 2025-05-12' \
  -d '{
    "name": "Customer Name",
    "email": "customer@example.com",
    "is_tax_exempt": true,
    "reference_customer_id": "20506"
  }'
```

```json Response theme={null}
{
  "id": "cust_6126acaf-7379-411a-8ada-00005bac0715",
  "object": "tax.customer",
  "reference_customer_id": "20506",
  "name": "Customer Name",
  "email": "customer@example.com",
  "is_tax_exempt": true
}
```

## Update a customer

Updates a customer's `name`, `email`, `is_tax_exempt`, or `reference_customer_id`. Send at least one. Fields you leave out stay as they are. [Try it in the API reference](https://docs.numeral.com/api-reference/v2025-05-12/endpoint/update_customer).

* `email` and `reference_customer_id` must be unique across your customers. If another customer already uses the new value, the request fails with `duplicate_customer`, and `error_meta` has the conflicting customer's `id`, `reference_customer_id`, and `email`.
* `email` must be a valid email address, or the request fails with `invalid_email`.
* Setting `is_tax_exempt` to `true` makes every future calculation for this customer return 0 tax. Setting it to `false` removes the exemption.
* If every value you send matches what's stored, nothing changes and the current customer is returned with a `200`.
* Deleted customers can't be updated. The request fails with `customer_not_found`.
* If the customer's buyer record was deleted in Numeral's Exemption Certificate Manager, setting `is_tax_exempt` to `true` fails with `invalid_request`.

### Parameters

**customer\_id** `string` *required*

The customer's `id` or your `reference_customer_id`. No `id_type` needed.

**name** `string`

The customer's name.

**email** `string`

The customer's email.

**is\_tax\_exempt** `boolean`

`true` to exempt the customer from tax, `false` to remove the exemption.

**reference\_customer\_id** `string`

Your ID for the customer.

### Returns

The updated [Customer object](#the-customer-object).

```bash POST /tax/customers/:id theme={null}
curl https://api.numeralhq.com/tax/customers/20506 \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Version: 2025-05-12' \
  -d '{
    "name": "New Customer Name",
    "email": "new.email@example.com"
  }'
```

```json Response theme={null}
{
  "id": "cust_6126acaf-7379-411a-8ada-00005bac0715",
  "object": "tax.customer",
  "reference_customer_id": "20506",
  "name": "New Customer Name",
  "email": "new.email@example.com",
  "is_tax_exempt": true
}
```

## Retrieve a customer

Returns a customer by its `id` or your `reference_customer_id`. [Try it in the API reference](https://docs.numeral.com/api-reference/v2025-05-12/endpoint/get_customer).

**customer\_id** `string` *required*

The customer's `id`, or your `reference_customer_id` with `id_type=reference_customer_id`.

**id\_type** `enum` (default: id)

`id` to look up by the Numeral customer ID. `reference_customer_id` to look up by your own ID.

### Returns

A [Customer object](#the-customer-object).

```bash GET /tax/customers/:id theme={null}
curl 'https://api.numeralhq.com/tax/customers/20506?id_type=reference_customer_id' \
  -H 'Authorization: Bearer <token>' \
  -H 'X-API-Version: 2025-05-12'
```

## Delete a customer

Deletes a customer. Deleted customers can't be updated. [Try it in the API reference](https://docs.numeral.com/api-reference/v2025-05-12/endpoint/delete_customer).

**customer\_id** `string` *required*

The customer's `id`.

### Returns

The deleted object type and when it was deleted.

```bash DELETE /tax/customers/:id theme={null}
curl -X DELETE https://api.numeralhq.com/tax/customers/cust_6126acaf-7379-411a-8ada-00005bac0715 \
  -H 'Authorization: Bearer <token>' \
  -H 'X-API-Version: 2025-05-12'
```

```json Response theme={null}
{
  "object": "tax.customer",
  "deleted_at": 1721782604
}
```

## Errors

Errors return an `error` object with `error_code`, `error_message`, and sometimes `error_meta` with details. Handle them by `error_code`. The request ID is in the `X-Request-Id` response header.

| HTTP | `error_code` | When |
| - | - | - |
| 400 | `missing_field` | A required field is missing, e.g. `email` on create. |
| 400 | `incorrect_type` | A field has the wrong type. |
| 400 | `invalid_email` | On update, `email` isn't a valid email address. |
| 400 | `invalid_request` | An update sent no field to change, or set `is_tax_exempt` to `true` for a customer whose buyer record was deleted in Exemption Certificate Manager. |
| 400 | `duplicate_customer` | On update, another customer already uses this `email` or `reference_customer_id`. |
| 400 | `customer_not_found` | An update targeted a customer that doesn't exist or was deleted. |

```json duplicate_customer theme={null}
{
  "error": {
    "error_code": "duplicate_customer",
    "error_message": "Customer already exists.",
    "error_meta": {
      "id": "cust_1234567890abcdef",
      "reference_customer_id": "20507",
      "email": "new.email@example.com"
    }
  }
}
```

```json customer_not_found theme={null}
{
  "error": {
    "error_code": "customer_not_found",
    "error_message": "Customer with id cust_9876543210abcdef not found"
  }
}
```


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