Back to Developer

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

MethodPathDescription
GET/v1/stores/{store_id}/customersList all customers with search, filters, and pagination.
POST/v1/stores/{store_id}/customersCreate 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}/metricsGet RFM scores, AOV, LTV, and churn risk.
GET/v1/stores/{store_id}/customers/{id}/activityGet the customer activity timeline.
GET/v1/stores/{store_id}/customers/{id}/notesList notes for a customer.
POST/v1/stores/{store_id}/customers/{id}/notesAdd a note to a customer.
GET/v1/stores/{store_id}/customer-segmentsList all customer segments.
POST/v1/stores/{store_id}/customer-segmentsCreate 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-requestSubmit a GDPR/CCPA data removal request.