Customer Journey
A customer's full consolidated journey — orders, messages (with full bodies), and browse activity — merged newest-first.
GET /cdp/customers/{identifier}/journey returns a customer's full consolidated journey for
your brand: a single newest-first timeline merging CDP interaction events (orders, messages,
subscriptions) with on-demand message bodies fetched live from the source and the
browse/pixel timeline from Unomi — composed across all three stores without duplicating
bodies into the CDP. It is the REST twin of the cdp_customer_journey MCP tool: both return
the same timeline, computed by one shared capability.
Every read is bound to your brand's scope. See Tenant Isolation & Scope.
Path & query parameters
The {identifier} is classified by shape:
| Shape | Interpreted as |
|---|---|
| UUID | CDP customerId |
contains @ | email |
starts with + | phone |
| all digits | shopify_customer_id |
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 200 | Max journey entries, 1–500. |
since | string | — | ISO-8601 lower bound — only include activity at/after this instant. |
Response 200
{
"customerId": "8f2b…",
"brandId": "b1a2…",
"identities": [
{ "type": "email", "value": "jane@example.com", "source": "shopify", "confidence": 1, "verified": true }
],
"journey": [
{
"kind": "message",
"occurredAt": "2026-06-30T09:20:00.000Z",
"source": "liverecover",
"eventType": "engagement.sms_sent",
"signals": { "channel": "sms", "direction": "outgoing", "senderType": "agent" },
"detail": { "body": "No problem — I've cancelled that for you.", "direction": "outgoing" }
},
{
"kind": "message",
"occurredAt": "2026-06-30T09:12:00.000Z",
"source": "liverecover",
"eventType": "engagement.sms_received",
"signals": { "channel": "sms" },
"detail": { "body": "Yes, please cancel my subscription.", "direction": "incoming" }
},
{
"kind": "order",
"occurredAt": "2026-06-20T14:30:00.000Z",
"source": "shopify",
"eventType": "order_created",
"signals": { "amount": 153.38, "currency": "USD" }
},
{
"kind": "browse",
"occurredAt": "2026-06-19T11:00:00.000Z",
"source": "unomi",
"eventType": "product_viewed",
"detail": { "url": "/products/widget" }
}
],
"degraded": { "detail": false, "browse": false },
"scope": "your-shop.myshopify.com"
}identities— the customer's resolved identity graph (type/value + provenance).journey— the merged, newest-first timeline. Each entry carries akind(message|order|browse|event),occurredAt,source,eventType,signals, and — for messages — the full messagebody(owner decision: brand-key holders already own this customer data). Browse entries come from the Unomi pixel timeline.degraded—detail: truewhen message bodies could not be fetched;browse: truewhen the browse timeline browned out. The rest of the journey still returns.scope— your brand's resolved shop domain.
How this differs from other reads
Unlike GET /cdp/customers/{identifier} (the merged
profile + commerce summary), the journey is the richest read: the full ordered event
timeline with message bodies and browse activity.
Example
curl -s "https://cdp.vyg.app/cdp/customers/jane@example.com/journey?limit=100" \
-H "Authorization: Bearer vyg_your_key_here"Errors
| Status | When |
|---|---|
400 | Missing identifier, or limit out of range (bad_request). |
401 | Missing or invalid credential. |
403 | No connected Shopify integration resolves a scope for the brand. |
404 | No CDP customer resolves for the identifier in this brand. |
405 | Non-GET method. |
503 | The CDP is temporarily unavailable — retry (upstream_unavailable). |
Customer Orders
List a single customer's order history, resolved by profile id, email, phone, Shopify customer id, or contact id, in the standard order-list contract.
Customer Insights
Lifetime value and spend totals for a single customer — resolved by profile id, email, phone, Shopify customer id, or contact id — over their completed orders.