Customers

GET /customers

List the organization's customers, newest first by default. Supports search, filtering and cursor pagination.

Requires the customers:read permission.

Query Parameters

limitnumber

The number of records to return.

cursorstring

A pagination cursor. Fetch the next page by passing the nextCursor value from the previous response.

sortemail | -email | createdAt | -createdAt

The sort order. Prefix a field with - to sort descending. Defaults to -createdAt.

searchstring

A free-text search term, matched case-insensitively against the record's most identifying fields. Combined with filter using AND.

filterstring

A JSON-encoded filter document, for example {"createdAt":{"$gte":"2025-01-01T00:00:00Z"}}. Filterable fields: id, email, firstName, lastName, metadata, emailOptOut, emailOptOutSource, createdAt, tags.name. See Filtering for the syntax.

includestring

A comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: importJob, ordersCount, reviewsCount, wishlistsCount, loyaltyPointsBalance, tags.

Request
curl \
  "https://api.cascade.dev/customers" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "[email protected]",
      "phone": "string",
      "firstName": "string",
      "lastName": "string",
      "country": "string",
      "birthday": "string",
      "metadata": "...",
      "notes": "string",
      "emailOptOut": true,
      "emailOptOutAt": "2025-01-15T09:30:00Z",
      "emailOptOutSource": "customer",
      "createdAt": "2025-01-15T09:30:00Z",
      "updatedAt": "2025-01-15T09:30:00Z",
      "importJob": {
        "id": "...",
        "type": "...",
        "action": "...",
        "row": "...",
        "createdAt": "..."
      },
      "ordersCount": 0,
      "reviewsCount": 0,
      "wishlistsCount": 0,
      "loyaltyPointsBalance": 0,
      "tags": ["..."]
    }
  ],
  "nextCursor": "string"
}

PATCH /customers/bulk-update

Add or remove tags and metadata, or set the marketing email opt-out, across every customer matching a filter in one request. Sending no filter applies the changes to every customer in the organization. At least one change is required.

Requires the customers:write permission.

Costs 5 rate limit tokens instead of the usual one. See Rate limits.

Query Parameters

filterstring

A JSON-encoded filter document selecting the customers to update. Omit it and every customer in the organization is updated. See Filtering for the syntax.

searchstring

A free-text search term, matched case-insensitively against the record's most identifying fields. Combined with filter using AND.

Body Parameters

addTagsstring[]

Tag names to add. Tags that do not exist yet are created.

removeTagsstring[]

Tag names to remove.

addMetadataobject

Metadata keys to set, merged onto whatever each customer already has.

removeMetadataKeysstring[]

Metadata keys to delete.

emailOptOutboolean

Set to true to stop sending every matching customer marketing email, false to opt them all back in. Omit to leave it alone.

emailOptOutSourcecustomer | merchant | import | shopify

Where the opt-out came from. Defaults to merchant.

Request
curl \
  -X PATCH \
  "https://api.cascade.dev/customers/bulk-update" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "addTags": [
    "string"
  ],
  "removeTags": [
    "string"
  ],
  "addMetadata": "...",
  "removeMetadataKeys": [
    "string"
  ],
  "emailOptOut": true,
  "emailOptOutSource": "customer"
}'
Response
{
  "count": 0
}

POST /customers/import

Create or update customers in bulk, matching on email. Every column you send overwrites what is already stored, so send complete records rather than partial ones.

Requires the customers:write permission.

Costs 10 rate limit tokens instead of the usual one. See Rate limits.

Body Parameters

dataobject[]required

The customers to create or update.

Request
curl \
  -X POST \
  "https://api.cascade.dev/customers/import" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "data": [
    {
      "email": "[email protected]",
      "phone": "string",
      "firstName": "string",
      "lastName": "string",
      "birthday": "string",
      "metadata": "...",
      "tags": [
        "..."
      ],
      "emailOptOut": true,
      "emailOptOutSource": "customer"
    }
  ]
}'
Response
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "[email protected]",
      "phone": "string",
      "firstName": "string",
      "lastName": "string",
      "country": "string",
      "birthday": "string",
      "metadata": "...",
      "notes": "string",
      "emailOptOut": true,
      "emailOptOutAt": "2025-01-15T09:30:00Z",
      "emailOptOutSource": "customer",
      "createdAt": "2025-01-15T09:30:00Z",
      "updatedAt": "2025-01-15T09:30:00Z",
      "importJob": {
        "id": "...",
        "type": "...",
        "action": "...",
        "row": "...",
        "createdAt": "..."
      },
      "ordersCount": 0,
      "reviewsCount": 0,
      "wishlistsCount": 0,
      "loyaltyPointsBalance": 0,
      "tags": ["..."]
    }
  ],
  "skipped": [
    {
      "index": 0,
      "message": "string"
    }
  ]
}

GET /customers/{id}

Get a single customer by ID.

Requires the customers:read permission.

Path Parameters

idstring (uuid)required

The ID of the customer.

Query Parameters

includestring

A comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: importJob, ordersCount, reviewsCount, wishlistsCount, loyaltyPointsBalance, tags.

Request
curl \
  "https://api.cascade.dev/customers/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "[email protected]",
  "phone": "string",
  "firstName": "string",
  "lastName": "string",
  "country": "string",
  "birthday": "string",
  "metadata": "...",
  "notes": "string",
  "emailOptOut": true,
  "emailOptOutAt": "2025-01-15T09:30:00Z",
  "emailOptOutSource": "customer",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "importJob": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "customers",
    "action": "created",
    "row": 0,
    "createdAt": "2025-01-15T09:30:00Z"
  },
  "ordersCount": 0,
  "reviewsCount": 0,
  "wishlistsCount": 0,
  "loyaltyPointsBalance": 0,
  "tags": ["string"]
}

PATCH /customers/{id}

Update a customer's metadata, notes, tags, birthday or marketing email opt-out. Profile fields such as the email and name come from the store and cannot be edited here. Triggers the customer.updated webhook.

Requires the customers:write permission.

Path Parameters

idstring (uuid)required

The ID of the customer to update.

Body Parameters

metadataobject

Replaces the customer's metadata wholesale. Omit to leave it alone.

notesstring

Internal notes about the customer.

tagsstring[]

The customer's full set of tag names. Omit to leave the tags alone.

emailOptOutboolean

Set to true to stop sending the customer marketing email, false to opt them back in. Omit to leave it alone.

emailOptOutSourcecustomer | merchant | import | shopify

Where the opt-out came from. Defaults to merchant.

birthdaystring | null

The customer's birthday as MM-DD, such as 03-14. Send null to clear it, and omit it to leave it alone.

Request
curl \
  -X PATCH \
  "https://api.cascade.dev/customers/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "metadata": "...",
  "notes": "string",
  "tags": [
    "string"
  ],
  "emailOptOut": true,
  "emailOptOutSource": "customer",
  "birthday": "string"
}'
Response
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "[email protected]",
  "phone": "string",
  "firstName": "string",
  "lastName": "string",
  "country": "string",
  "birthday": "string",
  "metadata": "...",
  "notes": "string",
  "emailOptOut": true,
  "emailOptOutAt": "2025-01-15T09:30:00Z",
  "emailOptOutSource": "customer",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "importJob": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "customers",
    "action": "created",
    "row": 0,
    "createdAt": "2025-01-15T09:30:00Z"
  },
  "ordersCount": 0,
  "reviewsCount": 0,
  "wishlistsCount": 0,
  "loyaltyPointsBalance": 0,
  "tags": ["string"]
}

DELETE /customers/{id}

Delete a customer along with their orders, loyalty memberships, referrals and tags. Their reviews are kept but unlinked and unpublished, unless the organization has cascadeDeleteReviews turned on. Triggers the customer.deleted webhook.

Requires the customers:write permission.

Path Parameters

idstring (uuid)required

The ID of the customer to delete.

Request
curl \
  -X DELETE \
  "https://api.cascade.dev/customers/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "[email protected]",
  "phone": "string",
  "firstName": "string",
  "lastName": "string",
  "country": "string",
  "birthday": "string",
  "metadata": "...",
  "notes": "string",
  "emailOptOut": true,
  "emailOptOutAt": "2025-01-15T09:30:00Z",
  "emailOptOutSource": "customer",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "importJob": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "customers",
    "action": "created",
    "row": 0,
    "createdAt": "2025-01-15T09:30:00Z"
  },
  "ordersCount": 0,
  "reviewsCount": 0,
  "wishlistsCount": 0,
  "loyaltyPointsBalance": 0,
  "tags": ["string"]
}