Customers
Full CRM — customer profiles, segments, activity history, metrics, enrichment, and data protection.
Overview
The Customers API gives you a complete CRM for your store. Create and manage customer profiles with contact details, addresses, tags, and custom fields. Track every interaction through a unified activity timeline. Compute real-time metrics like lifetime value and churn risk. Build dynamic segments for targeted marketing, and handle GDPR/CCPA data removal requests with a single API call.
profiles
Full customer records with contact info, addresses, tags, and custom fields.
segments
Dynamic and static groups based on behavior, spend, location, or custom rules.
activity
Unified timeline of orders, page views, emails, support chats, and custom events.
metrics
RFM scores, average order value, lifetime value, churn risk, and purchase frequency.
List & Search Customers
Retrieve a paginated list of customers with full-text search across name, email, and phone. Filter by tags, segment membership, creation date, or custom fields. Results include cursor-based pagination for efficient traversal of large customer bases.
const whale = new WhaleClient("wk_live_...");
const customers = await whale.customers.list({
search: "john@",
tags: ["vip", "wholesale"],
created_after: "2026-01-01",
sort: "last_order_at",
order: "desc",
limit: 25
});
// Response
{
"object": "list",
"data": [
{
"id": "cust_a1b2c3d4",
"email": "john@acmecorp.com",
"first_name": "John",
"last_name": "Rivera",
"phone": "+1-555-0142",
"tags": ["vip", "wholesale"],
"total_orders": 47,
"total_spent": 12840.00,
"last_order_at": "2026-03-08T14:30:00.000Z",
"created_at": "2025-06-15T09:00:00.000Z"
}
],
"has_more": true,
"next_cursor": "eyJpZCI6ImN1c3RfYTFiMmMzZDQifQ=="
}Create a Customer
Create a new customer profile with contact information, tags, and optional address. The email field is unique per store — attempting to create a duplicate returns the existing customer. Tags are useful for segmentation and targeted campaigns.
const customer = await whale.customers.create({
email: "sarah.chen@example.com",
first_name: "Sarah",
last_name: "Chen",
phone: "+1-555-0198",
tags: ["retail", "newsletter"],
address: {
line1: "742 Evergreen Terrace",
city: "Springfield",
state: "IL",
postal_code: "62704",
country: "US"
},
metadata: {
source: "trade_show",
rep: "mike_d"
}
});
// Response
{
"id": "cust_e5f6a7b8",
"object": "customer",
"email": "sarah.chen@example.com",
"first_name": "Sarah",
"last_name": "Chen",
"phone": "+1-555-0198",
"tags": ["retail", "newsletter"],
"total_orders": 0,
"total_spent": 0,
"created_at": "2026-03-10T10:00:00.000Z"
}Customer Metrics
Retrieve computed metrics for a customer including RFM (Recency, Frequency, Monetary) scores, average order value, lifetime value, churn risk probability, and purchase frequency. Metrics are recalculated after every order and available in real time.
const metrics = await whale.customers.metrics("cust_a1b2c3d4");
// Response
{
"object": "customer_metrics",
"customer_id": "cust_a1b2c3d4",
"rfm": {
"recency_score": 5,
"frequency_score": 4,
"monetary_score": 5,
"segment": "champion"
},
"lifetime_value": 12840.00,
"average_order_value": 273.19,
"total_orders": 47,
"total_spent": 12840.00,
"purchase_frequency_days": 6.8,
"churn_risk": 0.04,
"first_order_at": "2025-06-20T11:00:00.000Z",
"last_order_at": "2026-03-08T14:30:00.000Z",
"computed_at": "2026-03-10T10:05:00.000Z"
}Customer Activity
Get a unified timeline of all customer interactions — orders placed, emails opened, pages viewed, support conversations, and custom events. Filter by event type or date range to focus on specific activity.
const activity = await whale.customers.activity("cust_a1b2c3d4", {
types: ["order", "email", "page_view"],
after: "2026-03-01",
limit: 10
});
// Response
{
"object": "list",
"data": [
{
"type": "order",
"title": "Order #1047 placed",
"amount": 289.00,
"occurred_at": "2026-03-08T14:30:00.000Z"
},
{
"type": "email",
"title": "Opened: Spring Collection Launch",
"campaign_id": "camp_x1y2z3",
"occurred_at": "2026-03-06T09:15:00.000Z"
},
{
"type": "page_view",
"title": "Viewed: /products/premium-leather-bag",
"referrer": "https://google.com",
"occurred_at": "2026-03-05T16:42:00.000Z"
},
{
"type": "support",
"title": "Chat: Sizing question",
"agent": "Whale Agent",
"occurred_at": "2026-03-03T11:20:00.000Z"
}
],
"has_more": true,
"next_cursor": "eyJ0IjoiMjAyNi0wMy0wM1QxMToyMDowMC4wMDBaIn0="
}Customer Segments
Create dynamic segments that automatically update as customer data changes, or static segments with a fixed member list. Dynamic segments use rule-based filters — combine conditions on spend, order count, tags, location, last activity, and more. Segments power targeted email campaigns, discount rules, and analytics breakdowns.
// Create a dynamic segment
const segment = await whale.segments.create({
name: "High-Value Churning",
type: "dynamic",
rules: [
{ field: "total_spent", operator: "gte", value: 500 },
{ field: "last_order_at", operator: "before", value: "90_days_ago" },
{ field: "churn_risk", operator: "gte", value: 0.6 }
]
});
// Response
{
"id": "seg_c9d0e1f2",
"object": "customer_segment",
"name": "High-Value Churning",
"type": "dynamic",
"rules": [
{ "field": "total_spent", "operator": "gte", "value": 500 },
{ "field": "last_order_at", "operator": "before", "value": "90_days_ago" },
{ "field": "churn_risk", "operator": "gte", "value": 0.6 }
],
"member_count": 34,
"created_at": "2026-03-10T10:00:00.000Z"
}
// Create a static segment with explicit members
const vipList = await whale.segments.create({
name: "VIP Invite List",
type: "static",
customer_ids: ["cust_a1b2c3d4", "cust_e5f6a7b8", "cust_c9d0e1f2"]
});Data Protection (GDPR/CCPA)
Handle data subject requests programmatically. Submit erasure requests to permanently delete customer data, or export requests to generate a downloadable archive of all data associated with a customer. Requests are processed asynchronously and you receive a webhook when complete. Erasure removes PII from all systems including backups within 30 days.
// Submit a data erasure request (GDPR Article 17)
const request = await whale.customers.removalRequest("cust_a1b2c3d4", {
type: "erasure",
reason: "Customer requested account deletion",
notify_customer: true
});
// Response
{
"id": "drr_f6a7b8c9",
"object": "data_removal_request",
"customer_id": "cust_a1b2c3d4",
"type": "erasure",
"status": "pending",
"reason": "Customer requested account deletion",
"estimated_completion": "2026-03-12T10:00:00.000Z",
"created_at": "2026-03-10T10:00:00.000Z"
}
// Submit a data export request (GDPR Article 20)
const exportReq = await whale.customers.removalRequest("cust_a1b2c3d4", {
type: "export",
format: "json"
});
// When complete, a webhook fires:
// { "event": "data_request.completed", "download_url": "..." }API Reference
| Method | Path | Description |
|---|---|---|
| GET | /v1/stores/{store_id}/customers | List all customers with search, filters, and pagination. |
| POST | /v1/stores/{store_id}/customers | Create a new customer profile. |
| GET | /v1/stores/{store_id}/customers/{id} | Get a single customer by ID. |
| PATCH | /v1/stores/{store_id}/customers/{id} | Update customer fields. |
| DELETE | /v1/stores/{store_id}/customers/{id} | Delete a customer record. |
| GET | /v1/stores/{store_id}/customers/{id}/metrics | Get RFM scores, AOV, LTV, and churn risk. |
| GET | /v1/stores/{store_id}/customers/{id}/activity | Get the customer activity timeline. |
| GET | /v1/stores/{store_id}/customers/{id}/notes | List notes for a customer. |
| POST | /v1/stores/{store_id}/customers/{id}/notes | Add a note to a customer. |
| GET | /v1/stores/{store_id}/customer-segments | List all customer segments. |
| POST | /v1/stores/{store_id}/customer-segments | Create a dynamic or static segment. |
| GET | /v1/stores/{store_id}/customer-segments/{id} | Get segment details and member count. |
| PATCH | /v1/stores/{store_id}/customer-segments/{id} | Update segment rules or metadata. |
| DELETE | /v1/stores/{store_id}/customer-segments/{id} | Delete a segment. |
| POST | /v1/stores/{store_id}/customers/{id}/removal-request | Submit a GDPR/CCPA data removal request. |