Skip to main content

Segments API

Segment management, dynamic rules, and sync to Messaging service.


List Segments

GET /segments

Query Parameters

ParameterTypeDescription
tenantIdstringRequired
typestringSTATIC, DYNAMIC, SMART
isActivebooleanFilter active

Response: 200 OK

{
"data": [{
"id": "segment_123",
"name": "High-Value Members",
"type": "DYNAMIC",
"isActive": true,
"memberCount": 342,
"lastRefreshedAt": "2025-12-14T02:00:00Z",
"messagingSegmentId": "msg_segment_456",
"lastSyncedAt": "2025-12-14T02:05:00Z",
"createdAt": "2025-06-01T00:00:00Z"
}]
}

Get Segment

GET /segments/:id

Response: 200 OK

{
"id": "segment_123",
"tenantId": "tenant_123",
"name": "High-Value Members",
"description": "Members with high engagement and Gold+ tier",
"type": "DYNAMIC",
"criteria": {
"combinator": "AND",
"rules": [
{ "field": "engagementScore", "operator": "gte", "value": 70 },
{ "field": "membershipTier", "operator": "in", "value": ["Gold", "Platinum"] },
{ "field": "emailOptIn", "operator": "eq", "value": true }
]
},
"isActive": true,
"memberCount": 342,
"lastRefreshedAt": "2025-12-14T02:00:00Z",
"messagingSegmentId": "msg_segment_456",
"lastSyncedAt": "2025-12-14T02:05:00Z",
"createdBy": "user_123",
"createdAt": "2025-06-01T00:00:00Z",
"updatedAt": "2025-12-14T02:00:00Z"
}

Get Segment Members

GET /segments/:id/members

Query Parameters

ParameterTypeDescription
skipnumberOffset
takenumberLimit

Response: 200 OK

{
"data": [{
"id": "customer_123",
"email": "john@example.com",
"firstName": "John",
"lastName": "Smith",
"engagementScore": 75,
"joinedSegmentAt": "2025-12-01T00:00:00Z"
}],
"meta": { "total": 342, "skip": 0, "take": 25 }
}

Create Segment

POST /segments

Request Body

{
"tenantId": "tenant_123",
"name": "High-Value Members",
"description": "Members with high engagement and Gold+ tier",
"type": "DYNAMIC",
"criteria": {
"combinator": "AND",
"rules": [
{ "field": "engagementScore", "operator": "gte", "value": 70 },
{ "field": "emailOptIn", "operator": "eq", "value": true }
]
}
}

Response: 201 Created


Update Segment

PATCH /segments/:id

Request Body

{
"name": "Premium Members",
"criteria": {
"combinator": "AND",
"rules": [
{ "field": "engagementScore", "operator": "gte", "value": 80 },
{ "field": "membershipTier", "operator": "eq", "value": "Platinum" }
]
}
}

Response: 200 OK


Delete Segment

DELETE /segments/:id

Response: 204 No Content

Note: Segments with active campaigns cannot be deleted.


Refresh Segment

Triggers recalculation of dynamic segment membership.

POST /segments/:id/refresh

Response: 200 OK

{
"segmentId": "segment_123",
"previousCount": 340,
"newCount": 342,
"added": 5,
"removed": 3,
"refreshedAt": "2025-12-14T10:00:00Z"
}

Sync to Messaging

Syncs segment membership to Messaging service for campaign execution.

POST /segments/:id/sync-to-messaging

Response: 200 OK

{
"messagingSegmentId": "msg_segment_123",
"syncedCount": 342,
"syncedAt": "2025-12-14T10:00:00Z"
}

Note: This creates or updates the corresponding segment in the Messaging service. The Messaging service uses this for actual message delivery.


Segment Criteria Reference

Available Fields

FieldTypeDescription
statusstringProfile status
lifecycleStagestringCustomer lifecycle stage
membershipTierstringMembership tier name
membershipStatusstringMembership status
engagementScorenumber0-100
churnRiskScorenumber0-100
lifetimeValuenumberCents
handicapnumberGolf handicap
emailOptInbooleanEmail consent
smsOptInbooleanSMS consent
lastActivityAtdateLast activity timestamp
createdAtdateProfile creation date

Operators

OperatorDescriptionExample
eqEquals{ "field": "status", "operator": "eq", "value": "ACTIVE" }
neNot equals{ "field": "status", "operator": "ne", "value": "MERGED" }
gtGreater than{ "field": "engagementScore", "operator": "gt", "value": 50 }
gteGreater than or equal{ "field": "engagementScore", "operator": "gte", "value": 70 }
ltLess than{ "field": "churnRiskScore", "operator": "lt", "value": 30 }
lteLess than or equal{ "field": "handicap", "operator": "lte", "value": 18 }
inIn array{ "field": "membershipTier", "operator": "in", "value": ["Gold", "Platinum"] }
ninNot in array{ "field": "status", "operator": "nin", "value": ["MERGED", "DELETED"] }
containsString contains{ "field": "email", "operator": "contains", "value": "@company.com" }
isNullIs null{ "field": "handicap", "operator": "isNull" }
isNotNullIs not null{ "field": "lastActivityAt", "operator": "isNotNull" }

Nested Groups

{
"combinator": "AND",
"rules": [
{ "field": "status", "operator": "eq", "value": "ACTIVE" },
{
"combinator": "OR",
"rules": [
{ "field": "membershipTier", "operator": "eq", "value": "Gold" },
{ "field": "membershipTier", "operator": "eq", "value": "Platinum" }
]
}
]
}

AI Segment Builder

The AI Segment Builder converts natural language to segment criteria.

Build from Natural Language

POST /v1/ai/segments/build

Request Body

{
"query": "Find platinum members who haven't booked in 60 days",
"tenantId": "tenant_123"
}

Response: 200 OK

{
"success": true,
"result": {
"criteria": {
"$and": [
{ "membershipTier": "PLATINUM" },
{ "lastBookingAt": { "$lt": "2025-10-17T00:00:00Z" } }
]
},
"explanation": "Platinum tier members who haven't booked in 60 days",
"fieldsMapped": ["membershipTier", "lastBookingAt"],
"confidence": 0.95,
"ambiguities": []
},
"previewCount": 45
}

Refine Existing Criteria

POST /v1/ai/segments/refine

Request Body

{
"instruction": "Also require email opt-in",
"currentCriteria": { "membershipTier": "PLATINUM" },
"tenantId": "tenant_123"
}

Preview Count

POST /v1/ai/segments/preview

Returns the count of customers matching criteria.

Get Available Fields

GET /v1/ai/segments/fields

Returns all segmentable fields with their types and operators.

See AI Segment Builder Spec for full documentation.