Segment rules
The rule format used to create a segment, change its rule, or estimate its size.
A segment groups customers who match your chosen rules. Send those rules as a definition
to create a segment, update it or check how many customers would match:
| Method & path | What it does |
|---|---|
POST /v1/segments | Create a segment from a rule. |
PATCH /v1/segments/{id} | Save a new version of the segment's rule. |
POST /v1/segments/{id}/archive | Archive the segment. |
POST /v1/segments/estimate | Count the customers a draft rule matches. |
Creating, changing and archiving need the segments:write scope and a sign-in (OAuth) token; API keys are
refused with 403. Estimating needs segments:read. Every route and its fields are in the
Segments reference.
Every rule is checked before it is saved. An invalid rule answers 400, and the error message
starts with the path of the condition that failed, for example
definition.rule.all.1: segment rule: unknown field "rfm".
The rule format
A definition is an object with a source and a rule:
{
"source": "commerce_orders",
"rule": {
"all": [
{ "op": "count-over-window", "window": { "days": 30 }, "times": { "op": ">=", "n": 1 } },
{
"op": "count-over-window",
"source": "product_events",
"where": [{ "field": "event_kind", "op": "=", "value": "product_viewed" }],
"window": { "days": 7 },
"times": { "op": ">=", "n": 1 }
}
]
}
}- Groups:
all,any(arrays of conditions) andnot(one condition). - Comparison:
{ "field", "op", "value" }, for example{ "field": "total_spend", "op": "greaterThan", "value": 500 }oncustomer_profile. - Count over a window:
{ "op": "count-over-window", "window": { "days": N }, "times": { "op", "n" }, "where": [...] }. - Aggregate:
{ "agg": "sum", "field": "total", "op": ">", "value": 100 }. - Member of another segment:
{ "op": "member-of-segment", "segmentId": "…" }. The segment must be an active segment; membership reflects its latest update. - A condition may name its own
sourceto combine sources in one rule.
The definition is stored and returned as you send it. Its keys and operators (such as segmentId and
greaterThan) are part of the rule format and are not renamed: the snake_case rule for API fields does not
apply inside a definition.
Supported sources: customer_profile (total_spend, orders_count, first_order_at,
last_order_at, last_event_at), commerce_orders, carts, product_events, utm_attribution,
subscription_contracts, engagement_events and customer_attributes (tags). RFM scores, geography, email engagement and consent are not supported in segment rules. Event sources keep 1,095 days of
history; a condition on them without a window means "in the last 1,095 days".
POST /v1/segments
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | 1 to 200 characters, unique among your active segments. |
description | string | no | Up to 2,000 characters. |
definition | object | yes | The rule, as above. |
Returns the segment as GET /v1/segments/{id} does, at version 1.
PATCH /v1/segments/{id}
Body: { "definition": { … } }. The new rule is saved as the next version; earlier versions are kept
unchanged. The segment's name and description do not change.
POST /v1/segments/{id}/archive
Body: {}. The segment stops being evaluated and leaves the active list. Its versions and history are
kept, and its name can be reused. Archiving cannot be undone through the API.
Example
curl -s -X POST "https://api.vyg.app/v1/segments" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Big spenders","definition":{"source":"customer_profile","rule":{"field":"total_spend","op":"greaterThan","value":500}}}'Errors
| Status | When |
|---|---|
400 | Invalid rule (the message starts with the failing path), or an unknown body field. |
401 | Missing or invalid credential. |
403 | Missing segments:write, an API key, or the brand does not have CDP access. |
404 | No segment was found for this ID. |
409 | The name is taken by an active segment, or the segment is archived. |