Skip to content

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.

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).

GET /cdp/customers/{identifier}/insights
Authorization: Bearer vyg_…
ParamTypeDescription
identifierstringA profile id, email, phone, Shopify customer id, or contact id — classified by shape (see Get Customer).
{
"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
}
}
}
FieldTypeDescription
matched_bystringWhich identity key resolved the customer: email, shopify_customer_id, phone, contact_id, or none.
scopestring | nullYour connected shop domain.
insights.ltvstringLifetime spend — sum of completed-order totals, as a decimal string.
insights.order_countintegerNumber of completed orders.
insights.aovstringAverage order value = ltv / order_count, as a decimal string.
insights.first_order_atstring | nullTimestamp of the earliest completed order, or null when there are none.
insights.last_order_atstring | nullTimestamp of the latest completed order, or null when there are none.
insights.currency_codestring | nullCurrency of the completed orders, or null when there are none.
insights.rfmobject | nullThe customer’s brand-relative RFM: recency_score, frequency_score, monetary_score (each 15), the derived tier, plus last_order_at, order_count, and ltv. null when the customer has no completed orders. See RFM.
insights.top_productsarrayThe 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.churnobject | nullThe 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.

Terminal window
curl -s "https://cdp.vyg.app/cdp/customers/alice@example.com/insights" \
-H "Authorization: Bearer vyg_your_key_here"
StatusWhen
400Missing identifier.
401Missing or invalid credential.
403Brand not enrolled in the commerce beta (beta_not_enabled), or no connected Shopify integration (integration_not_connected).
404The customer is absent from both the profile and commerce stores — an unknown identifier or one belonging to another brand, indistinguishable by design.
405Non-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.