Segments
Create Segment
Create a saved subscriber segment
POST
Create Segment
Create a segment from either the legacy flat filter array or a nested
A
root filter group. You must provide exactly one of filters or root, and it must contain at least one filter.
Request
string
required
Segment name.
FilterLeaf[]
Legacy v1 filter array. Use with
filterJoinOperator.string
default:"and"
and requires every v1 filter to match. or matches any v1 filter.FilterGroup
Nested v2 filter group. Use this for nested AND/OR logic, event filters, or
segment filters. Groups need
kind: "group" and a children array. Filters
need field, operator and a string value; omit value only for
is_empty and is_not_empty. A child without kind is read as a filter.segment filter matches the members of another saved segment. Counting
follows up to 16 levels of segment-to-segment references and 1,000
references in total; past either limit, counting the segment returns
SEGMENT_REFERENCE_DEPTH_EXCEEDED or SEGMENT_REFERENCE_COUNT_EXCEEDED.
Stripe trial subfilters stay under field: "stripeTrialProduct":
prod_123:is_canceled, prod_123:end_at:2026-05-26, or
prod_123:start_at:7 days ago.
Every filter field validates its own operator set:
status,segment,smsStatus:is,is_notphone:is_empty,is_not_emptytag:contains,not_contains,is_empty,is_not_emptyemail:contains,not_contains(domain or substring),is,is_not(exact, case-insensitive address)emailProvider,list:is,is_not,is_empty,is_not_emptyfirstName,lastName:contains,not_contains,is_empty,is_not_emptyadded:less_than,more_thanattribute: equality, empty checks, numeric/date comparisons, and contains checksevent, email engagement fields:is,is_not,at_least,less_than_countemailBounced: also supportsis_temporary_bounce,is_permanent_bounce- Stripe product fields: product-specific purchase/current/trial/date operators
commerceProduct,commerceCollection:is,is_not,at_least,less_than_count
smsStatus, use subscribed, unsubscribed, pending, or not_subscribed.
Phone presence filters use an empty value string. Commerce values use
provider:productId or provider:collectionKey, for example shopify:42 or
shopify:summer. Count operators append an order threshold, for example
shopify:42:3; omitting the threshold means 1. A bare product ID or collection
key matches across providers. Prefer provider-qualified values to avoid
collisions between stores.
Email engagement values can target any email (24h, 30d, all; hour windows accept whole hours from 1h to 8760h), one campaign
(campaign:<campaign_id>), or a delivery policy. Use marketing:<timeRange>
for marketing-policy campaigns, automations, and Send API traffic, and
transactional:<timeRange> for transactional sends. For example,
{"field":"emailOpened","operator":"is","value":"marketing:all"} matches
contacts who have ever opened a marketing email. Policy scopes work with
presence and bounce-subtype operators, not count operators.
Attribute filter names are matched case-sensitively against synced subscriber
attributes. When a filter references a custom attribute no subscriber has a
synced value for, the segment is still created but the response includes a
warnings array explaining that the filter currently matches no subscribers
(or every subscriber for exclusion operators like is_empty), with a
casing suggestion when a close match exists.
For arrays of objects, use wildcard paths such as
history_events[].eventvenue_id:2103. Two or more positive attribute filters
on the same array path that are connected only by AND must be satisfied by
one shared array element. A venue match on one history entry cannot combine
with a date match on another entry. Negative filters (is_not,
not_contains, and is_empty) remain independent because each asserts that
no array element matches its condition.