API call to create, refine, and delete audience segments through AI-powered multi-turn conversation. The endpoint supports streaming (SSE) for real-time progress updates during segment generation.
Within a conversation the assistant can create segments, update them, and delete them. Updates and deletions are restricted to segments that were created earlier in the same conversation via create_segment; requests to change any other segment are rejected. An update only changes the fields the assistant supplies, so a rename leaves the filters untouched.
The user must be authenticated and have both read and write permissions to the siteGroup, because the assistant creates and deletes segments on their behalf. The customer must have the AI feature enabled. Both endpoints enforce this.
Endpoints
|
Path |
Transport |
Description |
|---|---|---|
|
|
JSON (POST) |
Non-streaming request/response |
|
|
SSE (POST) |
Streaming with real-time progress events |
The streaming endpoint returns Server-Sent Events (SSE) with progress updates as the AI processes the request, while the non-streaming endpoint returns a single JSON response. The streaming endpoint only supports start and message operations, while the non-streaming endpoint supports all five operations.
Request
Non-streaming endpoint (/ai/segment/chat)
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
String |
Yes |
The chat operation to perform. One of: |
|
|
String |
Yes |
The site group identifier to scope the conversation to |
|
|
String |
Depends |
The conversation identifier. Required for |
|
|
String |
Depends |
The user's message text. Required for |
|
|
String |
No |
Optional user identifier to associate with the conversation. Only used on |
|
|
boolean |
No |
Whether to include conversation history in the response. Defaults to |
|
|
Integer |
No |
Limit the number of history messages returned. Returns most recent N messages. No limit by default |
Streaming endpoint (/ai/segment/chat/stream)
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
String |
Yes |
The chat operation to perform. Only |
|
|
String |
Yes |
The site group identifier to scope the conversation to |
|
|
String |
Depends |
The conversation identifier. Required for |
|
|
String |
Yes |
The user's message text. Must be non-empty |
|
|
String |
No |
Optional user identifier to associate with the conversation. Only used on |
The conversation is always scoped to the authenticated caller, so conversations started here are visible to the list and history operations of the non-streaming endpoint.
On a message operation the site group of the existing conversation is used, so a siteGroupId that differs from the one the conversation was started with is ignored rather than honoured.
Operations
start - Start a New Conversation Begins a new AI segment chat conversation with an initial message. The AI will analyze the request, fetch relevant data from the site group, and generate a segment definition. Supported by both endpoints.
message - Send a Follow-up Message Sends a follow-up message in an existing conversation. The AI maintains context from previous messages and can refine or modify previously generated segments. Supported by both endpoints.
list - List Conversations Lists all conversations for the authenticated user, filtered by site group. Returns a summary of each conversation including the first message and creation time. Non-streaming endpoint only.
history - Get Conversation History Retrieves the full message history for an existing conversation. Non-streaming endpoint only.
end - End a Conversation Ends and cleans up a conversation. The conversation data is given a short TTL (approximately 1 hour) after which it expires. Until then the conversation is still returned by list, flagged with ended: true, and can still be read with history. Non-streaming endpoint only.
Active conversations are retained for 90 days by default. Ended conversations expire about 1 hour after the end operation.
Response
Non-streaming response (/ai/segment/chat)
For start and message operations
|
Name |
Type |
Description |
|---|---|---|
|
|
String |
Unique identifier for the conversation |
|
|
Object |
The generated segment definition as a JSON object |
|
|
Array of object |
List of chat messages (empty if |
|
|
boolean |
Whether the operation succeeded |
|
|
String |
Error message if the operation failed |
For list operation
|
Name |
Type |
Description |
|---|---|---|
|
|
Array of object |
Array of conversation summary objects |
A conversation summary object has the following fields:
|
Name |
Type |
Description |
|---|---|---|
|
|
String |
Unique identifier for the conversation |
|
|
String |
The site group identifier |
|
|
Number |
Unix timestamp in milliseconds when the conversation started |
|
|
String |
Preview of the first message (truncated to 100 characters) |
|
|
boolean |
Whether the conversation has been ended; ended conversations stop being listed once they expire |
For history operation
|
Name |
Type |
Description |
|---|---|---|
|
|
Array of object |
Array of chat messages |
For end operation
|
Name |
Type |
Description |
|---|---|---|
|
|
boolean |
Whether the conversation was ended |
Chat message object
Messages in conversationHistory and messages arrays have the following fields:
|
Name |
Type |
Description |
|---|---|---|
|
|
String |
|
|
|
String |
The message text |
|
|
Number |
Unix timestamp in milliseconds |
|
|
Object/null |
Parsed segment definition JSON, if the message contains one |
Streaming response (/ai/segment/chat/stream)
The streaming endpoint returns Server-Sent Events. Each event is a JSON object with an eventType field:
|
eventType |
Description |
Key fields |
|---|---|---|
|
|
The AI is analyzing the request |
|
|
|
The AI is fetching data or performing a segment action (e.g. |
|
|
|
A tool invocation completed. |
|
|
|
The segment has been generated |
|
|
|
An error occurred |
|
Segment response object
The responseText field contains the generated segment definition:
|
Name |
Type |
Description |
|---|---|---|
|
|
String |
Name of the generated segment |
|
|
String |
Description of the generated segment |
|
|
String |
The inferred segment type: |
|
|
Array of object |
Segment filter definitions. See Traffic filters for syntax |
|
|
String |
A conversational summary of what was created or changed |
Examples
Start a conversation (non-streaming)
$ python cx.py /ai/segment/chat '{"operation": "start", "siteGroupId": "1135172335968227720", "message": "Create a segment for users from Chicago on Safari who read Robert Herguth articles"}'
{
"conversationId": "e70245d5-0c6e-4dd9-a455-3f02b8de9c19",
"responseText": {
"name": "Chicago Safari Users Reading Robert Herguth",
"description": "Users from Chicago using Safari browser who read articles by Robert Herguth",
"inferred": "traffic",
"filters": [
{
"type": "time",
"start": "-30d",
"filter": {
"type": "user",
"having": {
"min": 1,
"filter": {
"type": "and",
"filters": [
{
"type": "event",
"group": "city",
"items": ["chicago"]
},
{
"type": "event",
"group": "browser",
"items": ["Safari"]
},
{
"type": "keyword",
"group": "author",
"items": ["robert herguth"]
}
]
}
}
}
}
],
"chat_message": "Created your segment targeting Chicago users on Safari who read Robert Herguth articles. Would you like to adjust anything?"
},
"conversationHistory": [
{
"role": "user",
"content": "Create a segment for users from Chicago on Safari who read Robert Herguth articles",
"timestamp": 1709654400000,
"segmentJson": null
},
{
"role": "assistant",
"content": "Created your segment targeting Chicago users on Safari who read Robert Herguth articles. Would you like to adjust anything?",
"timestamp": 1709654415000,
"segmentJson": { "..." }
}
],
"success": true,
"error": null
}
Send a follow-up message
$ python cx.py /ai/segment/chat '{"operation": "message", "siteGroupId": "1135172335968227720", "conversationId": "e70245d5-0c6e-4dd9-a455-3f02b8de9c19", "message": "Exclude users from Norway"}'
{
"conversationId": "e70245d5-0c6e-4dd9-a455-3f02b8de9c19",
"responseText": {
"name": "Chicago Safari Users Reading Robert Herguth (Excluding Norway)",
"description": "Users from Chicago using Safari browser who read articles by Robert Herguth, excluding users from Norway",
"inferred": "traffic",
"filters": ["..."],
"chat_message": "Updated your segment to exclude Norwegian users. Any other adjustments needed?"
},
"conversationHistory": ["..."],
"success": true,
"error": null
}
List conversations
$ python cx.py /ai/segment/chat '{"operation": "list", "siteGroupId": "1135172335968227720"}'
{
"conversations": [
{
"conversationId": "e70245d5-0c6e-4dd9-a455-3f02b8de9c19",
"siteGroupId": "1135172335968227720",
"createdAt": 1709654400000,
"firstMessage": "Create a segment for users from Chicago on Safari who read Robert Herguth articles",
"ended": false
}
]
}
Get conversation history
$ python cx.py /ai/segment/chat '{"operation": "history", "siteGroupId": "1135172335968227720", "conversationId": "e70245d5-0c6e-4dd9-a455-3f02b8de9c19"}'
{
"messages": [
{
"role": "user",
"content": "Create a segment for users from Chicago on Safari who read Robert Herguth articles",
"timestamp": 1709654400000,
"segmentJson": null
},
{
"role": "assistant",
"content": "Created your segment targeting Chicago users on Safari who read Robert Herguth articles. Would you like to adjust anything?",
"timestamp": 1709654415000,
"segmentJson": { "..." }
}
]
}
End a conversation
$ python cx.py /ai/segment/chat '{"operation": "end", "siteGroupId": "1135172335968227720", "conversationId": "e70245d5-0c6e-4dd9-a455-3f02b8de9c19"}'
{
"success": true
}
Streaming example (SSE events)
$ python cx.py /ai/segment/chat/stream '{"operation": "start", "siteGroupId": "1135172335968227720", "message": "Create a segment for sports fans"}'
data: {
"conversationId": "abc-123",
"eventType": "thinking",
"message": "Analyzing request..."
}
data: {
"eventType": "tool_call",
"toolName": "list_keyword_groups",
"message": "Discovering keyword groups..."
}
data: {
"eventType": "tool_result",
"toolName": "list_keyword_groups",
"message": "Discovering keyword groups done"
}
data: {
"eventType": "tool_call",
"toolName": "get_keyword_items",
"message": "Fetching keyword data..."
}
data: {
"eventType": "tool_result",
"toolName": "get_keyword_items",
"message": "Fetching keyword data done"
}
data: {
"eventType": "tool_call",
"toolName": "create_segment",
"message": "Creating segment..."
}
data: {
"eventType": "tool_result",
"toolName": "create_segment",
"toolUseId": "toolu_01A09q90qw90lq917835lq9",
"segmentId": "1y2ir0osde3ep",
"message": "Creating segment done",
"success": true
}
data: {
"conversationId": "abc-123",
"eventType": "complete",
"responseText": {...},
"conversationHistory": [...],
"success": true
}
Error Responses
Non-streaming endpoint (/ai/segment/chat)
|
Condition |
HTTP Status |
Error message |
|---|---|---|
|
Missing |
400 |
|
|
Missing |
400 |
|
|
Missing |
400 |
|
|
Empty message |
400 |
|
|
Unknown operation |
400 |
|
|
No AI feature, or no read/write permission on the siteGroup |
403 |
Permission denied |
|
No access to the conversation, or the conversation has expired |
200 |
|
|
Service unavailable |
200 |
|
An unknown, expired or someone else's conversation are all answered with Permission denied, so that the response does not reveal whether a given conversation id exists.
Streaming endpoint (/ai/segment/chat/stream)
Validation errors are returned as SSE events with eventType: "error" rather than HTTP error codes:
|
Condition |
Error message |
|---|---|
|
Missing |
HTTP 400: |
|
Invalid JSON request |
HTTP 400: |
|
Missing |
SSE: |
|
Empty message |
SSE: |
|
Not authenticated, or no AI feature |
HTTP 403: |
|
No access to the conversation, or the conversation has expired |
SSE: |
|
Unsupported operation |
SSE: |
|
Internal error |
SSE: |
Matching results to calls
toolUseId identifies one tool call and is repeated on its tool_result, so a turn that makes several calls to the same tool can be followed without assuming the events arrive in order. A turn that acts on three segments makes three calls, each of which succeeds or fails on its own, so per-call results are the normal case rather than the exception.
segmentId on a tool_result is the segment the call acted on: the id a create produced, the id an update or a delete was given, or the id a restore ended up with — a new one when the original could not be brought back. It is absent for tools that do not act on a segment. Read the id from here rather than from the assistant's text: the wording of that text comes from a prompt and can change at any time.
restore_segment undoes a delete_segment made in the same conversation. It brings the original segment back with the id it had, through /segment/restore, for a user who may restore — admins and customer admins. For anyone else, and for a segment /segment/restore can no longer rebuild, the definition the segment had when it was deleted is created again as a new segment with a new id.
A failing tool call is not one of these: it does not end the stream, because the model is told what went wrong and carries on. It is reported on the tool_result event instead, and the operation it stands for (a segment create, update or delete) did not happen:
data: {
"eventType": "tool_result",
"toolName": "create_segment",
"message": "Creating segment failed",
"success": false,
"error": "'filters' must be a JSON array of filter objects, got string"
}