Create or update a contacts segment

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 404 error 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

The 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 (no value needed)

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_not
  • value: 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 the last_* prefix
  • value: a number for the count operations, a date or a number of days/hours for the others
  • window (optional, count operations only): { "operation": "...", "value": ... } to restrict the count
    to a time window

segment — Membership in another contacts segment:

  • operation: is, is_not
  • value: 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_replied
  • value (optional, clicked/not_clicked only): 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
Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Body Params
integer

Segment ID for update (optional). If not provided, a new segment will be created.

string
required

Segment name (1-255 characters)

filters
object
required

Predicate filter defining who belongs to this segment. See endpoint description for full schema documentation.

Responses

401

Authentication credentials are missing or invalid

404

Segment not found (when segment_id is provided)

422

Validation error: check name and filters format

Language
Credentials
Bearer
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json