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

# Customer Management overview

> List customers and retrieve customer activity scoped to a Chataigne location or organization.

The Customer Management API provides a read-only view of customers who interacted with a Chataigne location or business organization. It is designed for restaurant and middleware integrations that need customer identity, marketing consent, and scoped commercial activity without receiving provider credentials or unnecessary personal data.

## Endpoints

| Need                                      | Operation                                                         |
| ----------------------------------------- | ----------------------------------------------------------------- |
| List customers visible at one location    | `GET /v1/locations/{location_id}/customers`                       |
| Retrieve one customer at a location       | `GET /v1/locations/{location_id}/customers/{customer_id}`         |
| List customers across an organization     | `GET /v1/organizations/{organization_id}/customers`               |
| Retrieve one customer for an organization | `GET /v1/organizations/{organization_id}/customers/{customer_id}` |

Every operation requires `customers.read`. The `customer_id` is the stable, owner-scoped Chataigne Customer Profile identifier returned by the list endpoints.

## Scope determines every aggregate

The route—not the API key's maximum reach—determines the activity included in a customer detail:

* A location route counts only orders and interactions at that location.
* An organization route counts activity across that organization and its locations.
* A parent organization key calling a location route still receives location-only totals.
* A customer id that is not visible in the requested scope returns `404`.

For example, if a customer completed USD 100 of orders across an organization and USD 30 belongs to one location, the location detail returns USD 30. The organization detail returns USD 100.

<Warning>
  Never combine location-scoped totals with organization-scoped totals. The location amount is
  already included in the organization amount.
</Warning>

## List customers

Customer lists return the standard cursor-paginated list envelope. List items contain the fields needed to identify and contact a customer plus their marketing consent status:

```json theme={null}
{
  "id": "5ab32816-690d-4f09-874c-16c4cc72624d",
  "object": "customer",
  "created_at": "2026-07-01T10:00:00.000Z",
  "updated_at": "2026-07-12T15:30:00.000Z",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "email": "ada@example.com",
  "phone": "+33612345678",
  "language": "fr",
  "marketing_consent": {
    "status": "opted_in",
    "changed_at": "2026-07-10T14:30:00.000Z"
  },
  "completed_orders_count": 8
}
```

Use `limit`, `starting_after`, and `ending_before` as described in [Pagination](/concepts/pagination). Timestamp filters `created_after`, `created_before`, `updated_after`, and `updated_before` apply to Customer Profile timestamps.

## Filter customer lists

Customer lists support two server-side segmentation filters:

* **`marketing_consent_status`** accepts `opted_in`, `opted_out`, or `unknown`. It returns customers with that consent status; a missing consent record matches `unknown`.
* **`min_completed_orders`** accepts a non-negative integer. It returns customers with at least that many completed orders inside the requested route scope.

For example, this request returns customers who opted in to marketing and completed at least two orders at the selected location:

```http theme={null}
GET /v1/locations/{location_id}/customers?marketing_consent_status=opted_in&min_completed_orders=2
```

Filters combine with `AND` and are applied before cursor pagination. `completed_orders_count` on each list item uses the same scope as `min_completed_orders`: one location on location routes, or the organization and its locations on organization routes.

## Retrieve customer details

A detail response adds activity and completed-order aggregates for the route scope:

```json theme={null}
{
  "id": "5ab32816-690d-4f09-874c-16c4cc72624d",
  "object": "customer",
  "created_at": "2026-07-01T10:00:00.000Z",
  "updated_at": "2026-07-12T15:30:00.000Z",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "email": "ada@example.com",
  "phone": "+33612345678",
  "language": "fr",
  "marketing_consent": {
    "status": "opted_in",
    "changed_at": "2026-07-10T14:30:00.000Z"
  },
  "first_interaction_at": "2026-07-01T10:00:00.000Z",
  "last_interaction_at": "2026-07-12T15:30:00.000Z",
  "last_order_at": "2026-07-10T19:45:00.000Z",
  "completed_orders_count": 8,
  "total_spent": [
    {
      "amount": 184.5,
      "currency": "EUR"
    }
  ]
}
```

`total_spent` is an array because an organization can contain locations using different currencies. Values from unlike currencies are never added together. `last_order_at` includes the most recent order regardless of status, while `completed_orders_count` and `total_spent` include completed orders only.

## Marketing consent

`marketing_consent.status` has three possible values:

| Status      | Meaning                                             |
| ----------- | --------------------------------------------------- |
| `opted_in`  | The customer explicitly accepts marketing messages. |
| `opted_out` | The customer explicitly refuses marketing messages. |
| `unknown`   | Chataigne has no explicit consent decision.         |

`changed_at` is `null` while the status is `unknown` and no consent decision exists. Treat `unknown` as its own state; do not interpret it as opt-in.

## Deliberately excluded data

The first version does not return addresses, order identifiers, order URLs, payment data, Stripe identifiers, WhatsApp or Instagram provider identifiers, AI memory, legacy customer identifiers, or the global Person identifier. Erased Customer Profiles are excluded from lists and cannot be retrieved.
