List customers
The customers.list operation: GET /api/v1/customers in the REST API and the customers_list tool in the MCP server.
GET
/api/v1/customersLists the brand's customers in the mode of the request, newest first: only this organization's customers,
never another organization's. Deleted customers are left out unless includeDeleted=true.
email: the customer with exactly this address (addresses are compared in lower case);emailPrefix: customers whose address starts with this text (search);type:individual,businessorunknown.
Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).
At a glance
- REST:
GET /api/v1/customers - MCP tool:
customers_list - Operation ID:
customers.list - Scope: Brand
- Permission:
customers:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Pagination:
limit(at most 100) andstarting_after - Authentication: API key with the
customers:readscope - Since: M4
Request
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
limit | integer (1 to 100) | No | |
starting_after | cus_… ID | No | The customer's ID (cus_…). |
email | string | No | Only the customer with exactly this email address. |
emailPrefix | string | No | Customers whose email starts with this text (search). |
type | one of individual, business, unknown | No | |
includeDeleted | boolean or string | No | Include deleted customers (default false). true/false, also as a query string. |
Response
200 OK with a JSON object, a page of the list (newest first):
| Field | Type | Description |
|---|---|---|
object | "list" | |
data | array of object | |
data[].id | cus_… ID | |
data[].object | "customer" | |
data[].livemode | boolean | |
data[].entityId | ent_… ID | |
data[].brandId | brd_… ID | |
data[].email | string | |
data[].name | string or null | |
data[].businessName | string or null | |
data[].locale | string or null | |
data[].type | one of individual, business, unknown | Inferred (spec §13.1): business with a tax ID that isn't rejected, or with a business name when declared a business. Tax is decided per sale: only a valid tax ID makes a sale business-to-business. |
data[].declaredType | one of individual, business, unknown | What you declared. |
data[].billingAddress | object or null | |
data[].taxIds | array of object | |
data[].taxIds[].id | string | Identifies the tax ID on the customer: its canonical number, e.g. ATU12345678. |
data[].taxIds[].type | string | eu_vat, gb_vat, ch_uid/ch_vat, no_org/no_vat, us_ein, or another type (unverified). |
data[].taxIds[].value | string | The number as given. |
data[].taxIds[].country | string | |
data[].taxIds[].number | string or null | The canonical number (null for types Ownrecord can't check). |
data[].taxIds[].verification | object | The latest check (spec §9.4). |
data[].taxIds[].verification.status | one of valid, invalid, unavailable, format_only, unverified | valid, invalid, unavailable (the register couldn't answer), format_only (no register: format and checksum) or unverified (a type Ownrecord can't check). |
data[].taxIds[].verification.source | string | Who decided: VIES, HMRC, CH_UID, FORMAT (format and checksum only) or NONE. |
data[].taxIds[].verification.reason | string or null | Why, e.g. not_registered or service_unavailable. |
data[].taxIds[].verification.checkedAt | date-time | |
data[].taxIds[].verification.consultationNumber | string or null | The register's proof of the check (VIES request identifier, HMRC consultation number). |
data[].taxIds[].verification.simulated | boolean | A fixture answer (development and test environments), not a register's. |
data[].taxIds[].history | array of object | Earlier checks, newest first (at most 10). |
data[].taxIds[].history[].status | one of valid, invalid, unavailable, format_only, unverified | valid, invalid, unavailable (the register couldn't answer), format_only (no register: format and checksum) or unverified (a type Ownrecord can't check). |
data[].taxIds[].history[].source | string | Who decided: VIES, HMRC, CH_UID, FORMAT (format and checksum only) or NONE. |
data[].taxIds[].history[].reason | string or null | Why, e.g. not_registered or service_unavailable. |
data[].taxIds[].history[].checkedAt | date-time | |
data[].taxIds[].history[].consultationNumber | string or null | The register's proof of the check (VIES request identifier, HMRC consultation number). |
data[].taxIds[].history[].simulated | boolean | A fixture answer (development and test environments), not a register's. |
data[].taxIds[].addedAt | date-time | |
data[].taxCountryLocked | object or null | Where the customer's purchases are taxed (spec §9.3): set at the first successful payment, moved only when a top-up's evidence resolves to another country. |
data[].taxExempt | object or null | Tax exemption (spec §9.5). Not applied yet: exemption certificates come in a later release. |
data[].processorRefs | array of object | The customer at each payment processor used (set by checkout). |
data[].processorRefs[].processorConnectionId | pcon_… ID | |
data[].processorRefs[].customerRef | string | |
data[].risk | object | |
data[].risk.level | one of normal, elevated, blocked | |
data[].risk.reasons | array of string | |
data[].risk.firstPaymentAt | date-time or null | |
data[].risk.totalPaid | money | |
data[].portalLastLoginAt | date-time or null | |
data[].testClockId | clk_… ID or null | Test mode: the test clock the customer was created on (spec §16.13). |
data[].metadata | object | |
data[].createdAt | date-time | |
data[].updatedAt | date-time | |
data[].deletedAt | date-time or null | When the customer was deleted (soft delete); null while active. |
has_more | boolean | |
next_cursor | string or null |
Examples
Find a customer by email
HTTP
GET /api/v1/customers?email=ana%40example.com
Authorization: Bearer or_test_…
Response (200):
JSON
{
"object": "list",
"data": [
{
"id": "cus_01m4ty3c2b5qx7mhd9k8w6s0ab",
"object": "customer",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"email": "ana@example.com",
"name": "Ana Schmidt",
"businessName": null,
"locale": "de",
"type": "individual",
"declaredType": "individual",
"billingAddress": {
"line1": null,
"line2": null,
"city": null,
"postalCode": null,
"region": null,
"country": "DE"
},
"taxIds": [],
"taxCountryLocked": {
"country": "DE",
"subdivision": null,
"lockedAt": "2026-10-14T09:30:00.000Z",
"evidenceSetId": "evs_01m4ty3c2b5qx7mhd9k8w6s0ac"
},
"taxExempt": null,
"processorRefs": [
{
"processorConnectionId": "pcon_01m4ty3c2b5qx7mhd9k8w6s0af",
"customerRef": "cus_QxY12AbC"
}
],
"risk": {
"level": "normal",
"reasons": [],
"firstPaymentAt": "2026-10-14T09:30:00.000Z",
"totalPaid": {
"amount": "119000000",
"currency": "EUR"
}
},
"portalLastLoginAt": null,
"testClockId": null,
"metadata": {},
"createdAt": "2026-10-14T09:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z",
"deletedAt": null
}
],
"has_more": false,
"next_cursor": null
}
Business customers, two per page
HTTP
GET /api/v1/customers?type=business&limit=2
Authorization: Bearer or_test_…
Response (200):
JSON
{
"object": "list",
"data": [
{
"id": "cus_01m4ty3c2b5qx7mhd9k8w6s0aa",
"object": "customer",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"email": "billing@alpenapps.example",
"name": "Lena Huber",
"businessName": "Alpen Apps GmbH",
"locale": "de-AT",
"type": "business",
"declaredType": "business",
"billingAddress": {
"line1": "Mariahilfer Straße 1",
"line2": null,
"city": "Wien",
"postalCode": "1060",
"region": null,
"country": "AT"
},
"taxIds": [
{
"id": "ATU00000000",
"type": "eu_vat",
"value": "ATU 0000 0000",
"country": "AT",
"number": "ATU00000000",
"verification": {
"status": "valid",
"source": "VIES",
"reason": null,
"checkedAt": "2026-10-14T09:00:00.000Z",
"consultationNumber": "WAPIAAAAZ1x2y3",
"simulated": false
},
"history": [],
"addedAt": "2026-10-14T09:00:00.000Z"
}
],
"taxCountryLocked": null,
"taxExempt": null,
"processorRefs": [],
"risk": {
"level": "normal",
"reasons": [],
"firstPaymentAt": null,
"totalPaid": {
"amount": "0",
"currency": "EUR"
}
},
"portalLastLoginAt": null,
"testClockId": null,
"metadata": {
"userId": "u_4821"
},
"createdAt": "2026-10-14T09:00:00.000Z",
"updatedAt": "2026-10-14T09:00:00.000Z",
"deletedAt": null
},
{
"id": "cus_01m4ty3c2b5qx7mhd9k8w6s0a9",
"object": "customer",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"email": "billing@alpenapps.example",
"name": "Lena Huber",
"businessName": "Alpen Apps GmbH",
"locale": "de-AT",
"type": "business",
"declaredType": "business",
"billingAddress": {
"line1": "Mariahilfer Straße 1",
"line2": null,
"city": "Wien",
"postalCode": "1060",
"region": null,
"country": "AT"
},
"taxIds": [
{
"id": "ATU00000000",
"type": "eu_vat",
"value": "ATU 0000 0000",
"country": "AT",
"number": "ATU00000000",
"verification": {
"status": "valid",
"source": "VIES",
"reason": null,
"checkedAt": "2026-10-14T09:00:00.000Z",
"consultationNumber": "WAPIAAAAZ1x2y3",
"simulated": false
},
"history": [],
"addedAt": "2026-10-14T09:00:00.000Z"
}
],
"taxCountryLocked": null,
"taxExempt": null,
"processorRefs": [],
"risk": {
"level": "normal",
"reasons": [],
"firstPaymentAt": null,
"totalPaid": {
"amount": "0",
"currency": "EUR"
}
},
"portalLastLoginAt": null,
"testClockId": null,
"metadata": {
"userId": "u_4821"
},
"createdAt": "2026-10-14T09:00:00.000Z",
"updatedAt": "2026-10-14T09:00:00.000Z",
"deletedAt": null
}
],
"has_more": true,
"next_cursor": "cus_01m4ty3c2b5qx7mhd9k8w6s0a9"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A filter or pagination value is invalid. | Fix the fields listed in details.issues and send the request again. |
scope_required | 400 | The request names no brand (an org or entity key without Ownrecord-Brand). | Call the operation with credentials or a target at its level: an organization, a legal entity, a brand or the platform (details.required_scope). |
livemode_not_allowed | 403 | You have no live-mode access, so you can't act on live customers. | Use test mode, or credentials for the target's mode. Developers need live access granted by an organization owner or admin. |
permission_denied | 403 | You can't read this brand's customers (customers:read). | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, resource_not_found, dry_run_not_supported, rate_limited, internal_error.