This endpoint performs an upsert operation: it creates a new contacts segment or updates an existing one
based on the segment_id you provide.
If segment_id is provided:
- The segment with that ID will be updated
- If the segment doesn't exist or is being deleted, a
404error will be returned
If segment_id is not provided:
- A new segment will be created
What is a Segment?
A segment is a dynamic or static list of contacts that match a set of conditions.
When a segment is created or its filters change, Customerly automatically computes
which contacts belong to it.
The filters field — Predicate Structure
filters field — Predicate StructureThe filters field defines who belongs to this segment. It is a predicate tree with:
Root object:
{
"audience": "<audience_value>",
"operation": { ... }
}audience (required) — restricts the contact type:
"is_any_contact"(or"is_any") — all contacts, users and leads"is_user"— only registered users"is_lead"— only leads"is_not_user"— equivalent to"is_lead", and"is_not_lead"to"is_user": a stored contact is
always either a user or a lead"is_visitor"— always matches nothing: visitors are not stored contacts, so no segment can contain them
operation (optional) — a predicate node, either an operation or a condition:
Operation node (combines multiple predicates):
{
"type": "operation",
"operator": "and",
"predicates": [ ... ]
}operator:"and"or"or"(lowercase)predicates: array of condition or operation nodes
Condition node (single filter rule):
{
"type": "condition",
"target": "<target>",
"operation": "<operation>",
"value": "<value>"
}Condition Targets and Operations
state — Contact attribute. Requires name (the attribute key, e.g. "plan", or a default contact
field such as "email", "name", "created_at"). The operation set depends on the value type:
- string:
is,is_not,starts_with,ends_with,contains,does_not_contain - number:
greater_than,less_than,equal_to,not_equal - boolean:
is_true,is_false - date:
date_on,date_before,date_after,date_exactly,date_more_than,date_less_than,
date_more_than_hours,date_less_than_hours,date_more_than_ahead,date_less_than_ahead,
date_more_than_hours_ahead,date_less_than_hours_ahead - any type:
has_any_value,is_unknown(novalueneeded)
For date_on, date_before and date_after, value is a date (timestamp or parsable date string). For
the other date operations, value is a number of days (or hours, for the _hours variants).
company_state — Attribute of a company the contact belongs to. Same name/operation/value
semantics as state.
tag — Contact tag:
operation:is,is_notvalue: tag name (e.g.,"vip")
event — Custom event tracking. Requires name (the event name, e.g. "purchase"):
- count:
count_greater_than,count_less_than,count_is,count_is_not,count_has_any_value,count_is_unknown - first occurrence:
first_on,first_before,first_after,first_exactly,first_more_than,
first_less_than,first_more_than_hours,first_less_than_hours - last occurrence: same as
first_*but with thelast_*prefix value: a number for the count operations, a date or a number of days/hours for the otherswindow(optional, count operations only):{ "operation": "...", "value": ... }to restrict the count
to a time window
segment — Membership in another contacts segment:
operation:is,is_notvalue:segment_id(integer)
campaign — Campaign engagement:
name: the campaign ID (integer)operation:sent,not_sent,seen,not_seen,not_sent_or_not_seen,clicked,not_clicked,
replied,not_repliedvalue(optional,clicked/not_clickedonly): the clicked URL to match
campaigns_multiple — Same engagement operations as campaign, but across several campaigns at once:
names: array of campaign IDs (integers)value(optional): the clicked URL to match
Targets that segments cannot use
The predicate language also has real-time targets evaluated by the messenger (page, stats, platform,
office_hours, incoming_message). Segment membership is computed against stored data, so those targets
are accepted but never match anything — do not use them in a segment definition.
Examples
Example 1 — All registered contacts with the "vip" tag:
{
"audience": "is_user",
"operation": {
"type": "condition",
"target": "tag",
"operation": "is",
"value": "vip"
}
}Example 2 — Contacts on "premium" plan AND registered more than 30 days ago:
{
"audience": "is_any_contact",
"operation": {
"type": "operation",
"operator": "and",
"predicates": [
{
"type": "condition",
"target": "state",
"name": "plan",
"operation": "is",
"value": "premium"
},
{
"type": "condition",
"target": "state",
"name": "created_at",
"operation": "date_more_than",
"value": 30
}
]
}
}Example 3 — Contacts who have done "purchase" event OR have "enterprise" tag:
{
"audience": "is_any_contact",
"operation": {
"type": "operation",
"operator": "OR",
"predicates": [
{
"type": "condition",
"target": "event",
"name": "purchase",
"operation": "count_greater_than",
"value": 0
},
{
"type": "condition",
"target": "tag",
"operation": "is",
"value": "enterprise"
}
]
}
}Example 4 — Contacts who are in segment 10 but NOT in segment 20:
{
"audience": "is_any_contact",
"operation": {
"type": "operation",
"operator": "and",
"predicates": [
{
"type": "condition",
"target": "segment",
"operation": "is",
"value": 10
},
{
"type": "condition",
"target": "segment",
"operation": "is_not",
"value": 20
}
]
}
}Errors
422 segment_invalid_filters— malformed predicate (unknown target, invalid operation, missing required fields)422 segment_circular_dependency— the filters reference this or other segments in a circular way
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
401Authentication credentials are missing or invalid
404Segment not found (when segment_id is provided)
422Validation error: check name and filters format