Skip to content

Segments API

Segments define audience groups using a filter DSL. Flows can target a segment so that only matching contacts enter the flow when a trigger event fires.

Note

For a user guide on building segments in the dashboard, see Segments.


Endpoints

CRUD

MethodPathDescription
GET/v1/segmentsList all segments
POST/v1/segmentsCreate a segment
GET/v1/segments/{id}Get a segment
PUT/v1/segments/{id}Full update
PATCH/v1/segments/{id}Partial update
DELETE/v1/segments/{id}Delete a segment

Actions

MethodPathDescription
POST/v1/segments/{id}/archiveArchive a segment
POST/v1/segments/{id}/unarchiveRestore an archived segment
POST/v1/segments/{id}/duplicateDuplicate a segment
POST/v1/segments/{id}/evaluateRe-evaluate membership
POST/v1/segments/estimateEstimate size without saving

Read-Only

MethodPathDescription
GET/v1/segments/{id}/contactsList matching contacts (paginated)
GET/v1/segments/{id}/historyMembership trend over time
GET/v1/segments/{id}/usageWhich flows use this segment

List Segments

bash
curl "https://synapse-api.pyrx.tech/v1/segments?search=premium&is_archived=false" \
-H "Authorization: Bearer <jwt>"

Query Parameters

ParameterTypeDefaultDescription
searchstring--Search by name or description (case-insensitive)
is_archivedbooleanfalseSet to true to list archived segments instead

Response

json
[
{
"id": "8f14e45f-ceea-467f-a83c-01a01ba3c5db",
"name": "Active Premium Users - Singapore",
"description": "Subscribed premium users located in Singapore",
"filters": {
"all": [
{"field": "subscription_status", "operator": "is", "value": "subscribed"},
{"field": "properties.plan", "operator": "is", "value": "premium"},
{"field": "properties.country", "operator": "is", "value": "SG"}
]
},
"exclusion_rules": [
{"field": "properties.test_account", "operator": "is", "value": true}
],
"is_dynamic": true,
"cached_count": 1247,
"last_evaluated": "2026-04-07T10:35:00Z",
"created_by": "mem_abc123",
"tags": ["premium", "singapore"],
"is_archived": false,
"created_at": "2026-04-07T10:30:00Z",
"updated_at": "2026-04-07T10:30:00Z"
}
]

Create a Segment

bash
curl -X POST https://synapse-api.pyrx.tech/v1/segments \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "Active Premium Users - Singapore",
"description": "Subscribed premium users located in Singapore",
"filters": {
"all": [
{"field": "subscription_status", "operator": "is", "value": "subscribed"},
{"field": "properties.plan", "operator": "is", "value": "premium"},
{"field": "properties.country", "operator": "is", "value": "SG"}
]
},
"exclusion_rules": [
{"field": "properties.test_account", "operator": "is", "value": true}
],
"tags": ["premium", "singapore"]
}'

Request Body

FieldTypeRequiredDescription
namestringYesSegment name (1--255 chars)
descriptionstringNoHuman-readable description
filtersobjectYesFilter DSL with all (AND) or any (OR) grouping. See Filter DSL.
exclusion_rulesarrayNoList of filter rules. Contacts matching any exclusion rule are removed. Default: []
is_dynamicbooleanNoWhether the segment recalculates automatically. Default: true
tagsstring[]NoFreeform tags for organizing segments. Default: []

Response (201 Created)

Returns the full segment object (same shape as List response).


Get a Segment

bash
curl https://synapse-api.pyrx.tech/v1/segments/8f14e45f-ceea-467f-a83c-01a01ba3c5db \
-H "Authorization: Bearer <jwt>"

Returns the full segment object.


Update a Segment

Both PUT (full update) and PATCH (partial update) are supported. Both accept the same request body -- PATCH only applies provided fields, while PUT replaces all fields.

bash
curl -X PATCH https://synapse-api.pyrx.tech/v1/segments/8f14e45f-ceea-467f-a83c-01a01ba3c5db \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "Active Premium - Singapore (Updated)",
"tags": ["premium", "singapore", "q2-campaign"]
}'

Updatable Fields

FieldTypeDescription
namestringSegment name
descriptionstringDescription
filtersobjectFilter DSL
exclusion_rulesarrayExclusion rules
is_dynamicbooleanDynamic recalculation
tagsstring[]Tags

Delete a Segment

bash
curl -X DELETE https://synapse-api.pyrx.tech/v1/segments/8f14e45f-ceea-467f-a83c-01a01ba3c5db \
-H "Authorization: Bearer <jwt>"

Response

json
{
"deleted": true,
"id": "8f14e45f-ceea-467f-a83c-01a01ba3c5db"
}
Warning

You cannot delete a segment that is referenced by an active flow. The API returns 409 Conflict in that case. Deactivate the flow first, or archive the segment instead. Non-active flows referencing the segment will have their segment_id cleared automatically.


Archive / Unarchive

Archive a segment you are not currently using. Archived segments are hidden from the default list view but can be restored at any time.

Archive

bash
curl -X POST https://synapse-api.pyrx.tech/v1/segments/8f14e45f.../archive \
-H "Authorization: Bearer <jwt>"

Unarchive

bash
curl -X POST https://synapse-api.pyrx.tech/v1/segments/8f14e45f.../unarchive \
-H "Authorization: Bearer <jwt>"

Both return the updated segment object. The is_archived field reflects the new state.


Duplicate a Segment

Create a copy of an existing segment with (copy) appended to the name. The duplicate inherits all filters, exclusion rules, tags, and settings.

bash
curl -X POST https://synapse-api.pyrx.tech/v1/segments/8f14e45f.../duplicate \
-H "Authorization: Bearer <jwt>"

Response (201 Created)

Returns the new segment object. The cached_count and last_evaluated fields are null until the duplicate is evaluated.


Evaluate a Segment

Re-run the segment filters against the contacts table and return the matching count and contact IDs. Also updates the segment's cached_count and last_evaluated fields, and records a history point for the trend graph.

bash
curl -X POST https://synapse-api.pyrx.tech/v1/segments/8f14e45f.../evaluate \
-H "Authorization: Bearer <jwt>"

Response

json
{
"segment_id": "8f14e45f-ceea-467f-a83c-01a01ba3c5db",
"count": 1247,
"contact_ids": [
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"b2c3d4e5-f6a7-8901-bcde-f12345678901"
]
}
Note

For large segments, the contact_ids array can be substantial. Use the List Contacts endpoint for paginated access.


Estimate Size

Preview how many contacts would match a set of filters without creating or saving a segment. Returns the total count plus per-rule match counts for the segment builder's real-time feedback.

bash
curl -X POST https://synapse-api.pyrx.tech/v1/segments/estimate \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"all": [
{"field": "subscription_status", "operator": "is", "value": "subscribed"},
{"field": "properties.country", "operator": "is", "value": "SG"}
]
},
"exclusion_rules": [
{"field": "product_type", "operator": "in", "value": ["Premium", "Unsub"]}
]
}'

Response

json
{
"count": 3842,
"per_rule_counts": [8500, 4100]
}
FieldTypeDescription
countintegerTotal contacts matching all filters minus exclusions
per_rule_countsinteger[]How many contacts each individual rule matches (in order). Useful for showing per-rule counts in the UI.

List Matching Contacts

Get a paginated list of contacts that match a segment's filters.

bash
curl "https://synapse-api.pyrx.tech/v1/segments/8f14e45f.../contacts?page=1&page_size=50" \
-H "Authorization: Bearer <jwt>"

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number (starts at 1)
page_sizeinteger20Items per page (1--100)

Response

json
{
"segment_id": "8f14e45f-ceea-467f-a83c-01a01ba3c5db",
"total": 1247,
"contacts": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Doe",
"product_type": "Standard",
"subscription_status": "subscribed"
}
],
"page": 1,
"page_size": 50
}
Note

Segment contacts are evaluated in real time against the current data. For large segments (10,000+ contacts), use the evaluate endpoint first to check the count.


Membership History

View how a segment's size has changed over time. Each data point is recorded whenever the segment is evaluated (manually or by the scheduler).

bash
curl "https://synapse-api.pyrx.tech/v1/segments/8f14e45f.../history?days=30" \
-H "Authorization: Bearer <jwt>"

Query Parameters

ParameterTypeDefaultDescription
daysinteger30Number of days of history (1--365)

Response

json
{
"segment_id": "8f14e45f-ceea-467f-a83c-01a01ba3c5db",
"history": [
{"evaluated_at": "2026-03-20T08:00:00Z", "contact_count": 980},
{"evaluated_at": "2026-03-27T08:00:00Z", "contact_count": 1100},
{"evaluated_at": "2026-04-03T08:00:00Z", "contact_count": 1200},
{"evaluated_at": "2026-04-07T10:35:00Z", "contact_count": 1247}
]
}

Segment Usage

See which flows reference a given segment.

bash
curl https://synapse-api.pyrx.tech/v1/segments/8f14e45f.../usage \
-H "Authorization: Bearer <jwt>"

Response

json
{
"segment_id": "8f14e45f-ceea-467f-a83c-01a01ba3c5db",
"flows": [
{"id": "f1a2b3c4-...", "name": "Welcome Flow - Premium SG", "status": "active"},
{"id": "d5e6f7a8-...", "name": "Re-engagement - Draft", "status": "draft"}
],
"total_flows": 2
}
Tip

Check segment usage before deleting or significantly changing a segment's filters. Active flows that depend on the segment will be affected.


Filter DSL

Segments use a JSON filter DSL with all (AND) and any (OR) grouping:

AND (all conditions must match)

json
{
"filters": {
"all": [
{"field": "subscription_status", "operator": "is", "value": "subscribed"},
{"field": "properties.country", "operator": "is", "value": "SG"}
]
}
}

OR (any condition can match)

json
{
"filters": {
"any": [
{"field": "properties.plan", "operator": "is", "value": "growth"},
{"field": "properties.plan", "operator": "is", "value": "enterprise"}
]
}
}

Filter Operators

OperatorSQL EquivalentApplicable TypesExample
is= valuestring, number{"field": "status", "operator": "is", "value": "active"}
is_not!= valuestring, number{"field": "status", "operator": "is_not", "value": "churned"}
inIN (values)string, number{"field": "plan", "operator": "in", "value": ["growth", "enterprise"]}
not_inNOT IN (values)string, number{"field": "plan", "operator": "not_in", "value": ["free"]}
containsLIKE '%value%'string{"field": "email", "operator": "contains", "value": "@acme.com"}
not_containsNOT LIKE '%value%'string{"field": "email", "operator": "not_contains", "value": "test"}
starts_withLIKE 'value%'string{"field": "name", "operator": "starts_with", "value": "John"}
ends_withLIKE '%value'string{"field": "email", "operator": "ends_with", "value": "@acme.com"}
greater_than> valuenumber{"field": "properties.order_count", "operator": "greater_than", "value": 5}
less_than< valuenumber{"field": "properties.balance", "operator": "less_than", "value": 0}
gte>= valuenumber{"field": "properties.age", "operator": "gte", "value": 18}
lte<= valuenumber{"field": "properties.age", "operator": "lte", "value": 65}
betweenBETWEEN a AND bnumber, date{"field": "properties.age", "operator": "between", "value": [18, 65]}
existsIS NOT NULLany{"field": "phone", "operator": "exists"}
not_existsIS NULLany{"field": "properties.opted_out", "operator": "not_exists"}
is_empty= ''string{"field": "phone", "operator": "is_empty"}
is_not_empty!= ''string{"field": "email", "operator": "is_not_empty"}
date_before< datedate{"field": "created_at", "operator": "date_before", "value": "2026-01-01"}
date_after> datedate{"field": "created_at", "operator": "date_after", "value": "2026-01-01"}
date_in_last> now - N daysdate{"field": "created_at", "operator": "date_in_last", "value": 30}
has_executedJoin on eventsevent name{"field": "event", "operator": "has_executed", "value": "purchase_completed"}
has_not_executedLeft join IS NULLevent name{"field": "event", "operator": "has_not_executed", "value": "onboarding_completed"}

Accessing Nested Properties

Use dot notation to filter on contact properties:

json
{"field": "properties.address.city", "operator": "is", "value": "Singapore"}

Exclusion Rules

Exclusion rules remove contacts from the segment regardless of whether they match the inclusion filters. Each exclusion rule uses the same {field, operator, value} format.

json
{
"exclusion_rules": [
{"field": "product_type", "operator": "in", "value": ["Premium", "Unsub"]},
{"field": "properties.test_account", "operator": "is", "value": true}
]
}

Permissions

EndpointRequired Permission
List, Get, Evaluate, Estimate, Contacts, History, Usagesegments:read
Create, Update (PUT/PATCH), Delete, Archive, Unarchive, Duplicatesegments:write