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

# List customers

> List customers in your tenant with optional search and pagination.

**Required scope:** `customers:read`
**Rate limit:** 300 requests/minute

## Pagination

Supports both [cursor pagination (recommended)](/developer-api/pagination#cursor-pagination-recommended)
and [page pagination (deprecated)](/developer-api/pagination#page-pagination-deprecated).
The cursor shape wins if both are supplied. Both shapes apply the same
in-process name match (capped at 1,000 candidate rows) and return identical
row sets for the same `search` term.

## Query parameters

### Cursor shape (recommended)

| Parameter | Type    | Default | Notes                                                  |
| --------- | ------- | ------- | ------------------------------------------------------ |
| `cursor`  | string  | –       | Opaque cursor from a previous response's `next_cursor` |
| `limit`   | integer | `50`    | 1–100                                                  |

### Page shape (deprecated)

<Warning>
  Use cursor pagination for new integrations – see [Pagination](/developer-api/pagination).
</Warning>

| Parameter  | Type    | Default | Notes     |
| ---------- | ------- | ------- | --------- |
| `page`     | integer | `1`     | 1-indexed |
| `per_page` | integer | `50`    | 1–100     |

### Filters (both shapes)

| Parameter | Type   | Default | Notes                                                                                                                                             |
| --------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `search`  | string | –       | Matches an email exactly (when shaped like an email) or matches the customer's name (case-insensitive). The name fallback applies in both shapes. |

<Note>
  Email and name fields are stored encrypted and matched via deterministic
  lookup hashes; substring matching on names happens in-process across at
  most 1,000 candidate rows. The same cap applies to cursor and page walks.
</Note>

## Response

Cursor shape:

```json theme={null}
{
  "customers": [
    {
      "id": "c0ffee00-0000-4000-8000-000000000001",
      "email": "buyer@example.com",
      "first_name": "Alex",
      "last_name": "Buyer",
      "total_ltv": "175.00",
      "created_at": "2026-04-26T01:23:45Z",
      "location_id": null
    }
  ],
  "next_cursor": "cur_v1_eyJ2IjoxLCJ0Ijoi…uH8.QwR2…"
}
```

Page shape (deprecated):

```json theme={null}
{
  "customers": [/* …items… */],
  "total": 102,
  "page": 1,
  "per_page": 50
}
```

`total_ltv` is the sum of all voucher purchases attributed to this customer.

## Examples

```bash theme={null}
curl \
  -H "X-API-Key: vg_live_EXAMPLEdoNotUseThis123456" \
  "https://api.vouchergrid.com/api/v1/developer/customers?search=buyer@example.com"
```

```ts theme={null}
const params = new URLSearchParams({ search: "buyer@example.com" });
const res = await fetch(
  `https://api.vouchergrid.com/api/v1/developer/customers?${params}`,
  { headers: { "X-API-Key": process.env.VOUCHERGRID_API_KEY! } },
);
const data = await res.json();
```
