Segments
Saved filters over your contacts, usable as broadcast targets.
A segment is a saved filter over the team's contacts — it stores a filter expression, not a member list. Membership is evaluated live: a contact that starts matching the filter is in the segment immediately, and the contact count you see is computed at read time.
A segment created without a filter is a manual membership list: you
add and remove contacts explicitly (from the dashboard, or via
POST /contacts/{id}/segments/{segmentId} and the MCP's add_contact_to_segment). Both
kinds are equally valid broadcast targets.
Filters match on contact fields (email, name, subscribe state, creation date) and on custom properties, with operators such as equals, contains, is-set / is-not-set, and date comparisons. Conditions combine with and/or.
Dates
created_at and every property take four date operators:
| Operator | Matches a date that is | Value |
|---|---|---|
before | before the value | An ISO 8601 date or date-time |
after | after the value | An ISO 8601 date or date-time |
in_last_days | between N days ago and now | N, from 1 to 36500 |
not_in_last_days | more than N days ago | N, from 1 to 36500 |
{
"match": "all",
"conditions": [
{ "field": "property:last_login", "op": "not_in_last_days", "value": "90" }
]
}A property is read as a date the way a
date property takes one. A value that
isn't a date matches none of these operators, and a date still to come
matches neither in_last_days nor not_in_last_days. To find contacts
without the property, use is_not_set. Text operators work on every
property, whatever its type. In the dashboard, date operators show for
created_at and for date properties.
Using segments
- Broadcasts — target a segment instead of all contacts. The fan-out resolves membership at send time using the same filter translator as the contact count, so what you preview is what sends.
- Dashboard filtering — the Contacts view can be filtered by segment, and CSV export respects the active segment filter.
API
POST/GET/PATCH/DELETE /segments and GET /segments/{id} (which includes the
live contact_count) — see the API reference. Invalid
filter expressions are rejected with 422 and never stored. A PATCH with
neither name nor filter is a 422 too.