Customer Insights
GET /cdp/customers/{identifier}/insights — the lifetime value & spend summary
for a single customer, resolved from the same identifier as
Get Customer. Returns lifetime spend (ltv), order
count, average order value, and the first / last order timestamps at the top of
insights, plus the customer’s RFM tier (insights.rfm), top products
(insights.top_products), and churn signal (insights.churn) inline.
Requires the beta:cdp-commerce permission on your brand.
What counts
Section titled “What counts”Totals are computed over the customer’s completed orders only
(state = "complete"). Orders in any other state — pending, cancelled, refunded —
are excluded. Amounts are denominated in the store’s currency as
dollar-value decimal strings (e.g. "300.00", not cents).
Metrics are computed on read from your synced orders, so they always reflect your current data. The response contract is stable: if computation is later cached or materialized, the shape below does not change (a cache would carry at most a few minutes of staleness).
Request
Section titled “Request”GET /cdp/customers/{identifier}/insightsAuthorization: Bearer vyg_…Path parameters
Section titled “Path parameters”| Param | Type | Description |
|---|---|---|
identifier | string | A profile id, email, phone, Shopify customer id, or contact id — classified by shape (see Get Customer). |
Response 200
Section titled “Response 200”{ "identifier": "alice@example.com", "matched_by": "email", "scope": "your-shop.myshopify.com", "insights": { "ltv": "300.00", "order_count": 3, "aov": "100.00", "first_order_at": "2026-01-10T00:00:00.000Z", "last_order_at": "2026-03-20T00:00:00.000Z", "currency_code": "USD", "rfm": { "recency_score": 5, "frequency_score": 4, "monetary_score": 4, "tier": "champion", "last_order_at": "2026-03-20T00:00:00.000Z", "order_count": 3, "ltv": "300.00" }, "top_products": [ { "product_id": "101", "title": "Serum", "quantity": 3, "order_count": 2, "customer_count": 1, "revenue": "180.00", "repeat_purchase_rate": 1 } ], "churn": { "days_since_last_order": 36, "median_inter_order_days": 34, "brand_median_inter_order_days": 30, "at_risk": false, "at_risk_score": 1.06 } }}| Field | Type | Description |
|---|---|---|
matched_by | string | Which identity key resolved the customer: email, shopify_customer_id, phone, contact_id, or none. |
scope | string | null | Your connected shop domain. |
insights.ltv | string | Lifetime spend — sum of completed-order totals, as a decimal string. |
insights.order_count | integer | Number of completed orders. |
insights.aov | string | Average order value = ltv / order_count, as a decimal string. |
insights.first_order_at | string | null | Timestamp of the earliest completed order, or null when there are none. |
insights.last_order_at | string | null | Timestamp of the latest completed order, or null when there are none. |
insights.currency_code | string | null | Currency of the completed orders, or null when there are none. |
insights.rfm | object | null | The customer’s brand-relative RFM: recency_score, frequency_score, monetary_score (each 1–5), the derived tier, plus last_order_at, order_count, and ltv. null when the customer has no completed orders. See RFM. |
insights.top_products | array | The customer’s top products by completed-order revenue (up to five), each with product_id, title, quantity, order_count, customer_count, revenue, and repeat_purchase_rate. Empty when the customer has no completed orders. See Product Insights. |
insights.churn | object | null | The customer’s churn signal: days_since_last_order, median_inter_order_days, brand_median_inter_order_days, at_risk_score, and the at_risk boolean (true past roughly twice the cadence). null when the customer has no completed orders. See At-Risk Customers. |
A customer that resolves but has no completed orders yet returns the all-zero
summary (ltv: "0.00", order_count: 0, aov: "0.00", timestamps and
currency_code null), with rfm and churn null and top_products an empty
array — a clean “found the customer, no purchases yet”, never a 404. matched_by
still reports the identity key that resolved the customer
(email, phone, shopify_customer_id, or contact_id); it is none only when
the identifier resolved a profile but no local commerce contact.
Example
Section titled “Example”curl -s "https://cdp.vyg.app/cdp/customers/alice@example.com/insights" \ -H "Authorization: Bearer vyg_your_key_here"Errors
Section titled “Errors”| Status | When |
|---|---|
400 | Missing identifier. |
401 | Missing or invalid credential. |
403 | Brand not enrolled in the commerce beta (beta_not_enabled), or no connected Shopify integration (integration_not_connected). |
404 | The customer is absent from both the profile and commerce stores — an unknown identifier or one belonging to another brand, indistinguishable by design. |
405 | Non-GET method. |
See Brand LTV for the brand-wide aggregate, and
Tenant Isolation & Scope for why cross-brand
identifiers return 404 and never leak another brand’s customers.