Base path: /agents/:agentId/conversations
Multi-turn conversations with agents. Supports both synchronous request/response and Server-Sent Events (SSE) streaming.
Types
// ============================================
// ENUMS
// ============================================
type ConversationStatus = 'pending' | 'active' | 'ended' | 'failed' | 'archived' ;
/**
* Why the conversation ended.
*
* - 'completed': Normal completion via [COMPLETE] phrase match
* - 'function_call_exit': Agent called the end_conversation tool (function_call exit mode)
* - 'exit_phrase': User said an exit phrase during a connect-agent voice call
* - 'max_turns': Maximum turn count reached during a connect-agent voice call
* - 'timeout': Conversation timeout exceeded during a connect-agent voice call
* - 'user_hangup': Caller hung up during a connect-agent voice call
* - 'error': An error occurred
*/
type ConversationExitReason =
| 'completed'
| 'function_call_exit'
| 'exit_phrase'
| 'max_turns'
| 'timeout'
| 'user_hangup'
| 'error' ;
type SortOrder = 'asc' | 'desc' ;
// ============================================
// MESSAGE TYPES
// ============================================
interface ConversationMessage {
/** Message UUID */
id : string ;
/** Who sent the message */
role : 'user' | 'assistant' ;
/** Message text content */
content : string ;
/** ISO 8601 timestamp */
createdAt : string ;
}
// ============================================
// REQUEST TYPES
// ============================================
interface StartConversationRequest {
/** User UUID (for API/web conversations) */
userId ?: string ;
/** Contact UUID (for contact-linked conversations) */
contactId ?: string ;
/** Conversation title */
title ?: string ;
}
interface SendMessageRequest {
/** Message text content */
message : string ;
}
// ============================================
// QUERY PARAMETERS
// ============================================
interface ConversationQueryParams {
/** Page number (default: 1) */
page ?: number ;
/** Items per page (default: 20, max: 100) */
limit ?: number ;
/** Sort field */
sortBy ?: 'createdAt' | 'updatedAt' | 'startedAt' | 'lastMessageAt' | 'messageCount' ;
/** Sort order (default: 'desc') */
sortOrder ?: SortOrder ;
/** Search by title (partial match, max 100 chars) */
search ?: string ;
/** Filter by status */
status ?: ConversationStatus ;
}
// ============================================
// RESPONSE TYPES
// ============================================
interface ConversationResponse {
/** Conversation UUID */
id : string ;
/** Organization UUID */
organizationId : string ;
/** Agent UUID */
agentId : string ;
/** Mastra thread UUID (internal) */
mastraThreadId : string ;
/** Mastra resource ID (internal) */
mastraResourceId : string ;
/** User UUID (set for API/web conversations) */
userId : string | null ;
/** Contact UUID (set for contact-linked conversations) */
contactId : string | null ;
/** Call UUID (set for connect-agent voice calls) */
callId : string | null ;
/** Flow node ID (set for connect-agent voice calls) */
nodeId : string | null ;
/** Conversation title */
title : string | null ;
/** Total messages exchanged */
messageCount : number ;
/** Cumulative input tokens */
totalInputTokens : number ;
/** Cumulative output tokens */
totalOutputTokens : number ;
/** Current conversation status */
status : ConversationStatus ;
/** Why the conversation ended (null if still active) */
exitReason : ConversationExitReason | null ;
/**
* Exit phrase details:
* - phrase_match mode: the matched exit phrase
* - function_call mode: the user's last transcript that triggered exit
*/
exitPhrase : string | null ;
/**
* LLM-generated conversation summary.
* Only populated when exitReason is 'function_call_exit'
* (from end_conversation tool's `summary` arg).
*/
summary : string | null ;
/** Variables extracted during the conversation (from flow extractVariables config) */
extractedVariables : Record < string , unknown >;
/** ISO 8601 timestamp: when conversation started */
startedAt : string ;
/** ISO 8601 timestamp: when the last message was sent (null if no messages yet) */
lastMessageAt : string | null ;
/** ISO 8601 timestamp: when conversation ended (null if still active) */
endedAt : string | null ;
/** ISO 8601 timestamp */
createdAt : string ;
/** ISO 8601 timestamp */
updatedAt : string ;
}
interface SendMessageResponse {
/** Agent's text response */
response : string ;
/** Token usage for this turn */
usage ?: {
inputTokens ?: number ;
outputTokens ?: number ;
};
}
interface ConversationListResponse {
data : ConversationResponse [];
meta : {
page : number ;
limit : number ;
total : number ;
totalPages : number ;
hasNextPage : boolean ;
hasPreviousPage : boolean ;
};
}
/**
* GET /conversations/:id/messages returns a flat array of ConversationMessage[].
* No pagination wrapper is used — all messages are returned.
*/
// ============================================
// SSE STREAM EVENT TYPES
// ============================================
/**
* Server-Sent Events for streaming message responses.
* Each event is a JSON object with a `type` field.
*
* Note: The implementation uses a single interface with optional fields
* rather than a discriminated union. The `usage` fields are optional.
*/
type StreamEvent =
| { type : 'text' ; text : string }
| { type : 'usage' ; usage : { inputTokens ?: number ; outputTokens ?: number } }
| { type : 'done' }
| { type : 'error' ; error : string };
// ============================================
// CONVERSATION TURN (Connect-Agent Analytics)
// ============================================
/**
* Per-turn metrics for connect-agent voice conversations.
* Available in analytics and conversation detail views.
* Not directly exposed via REST API but included in
* conversation persistence data.
*/
interface ConversationTurn {
/** Turn UUID */
id : string ;
/** Parent conversation UUID */
conversationId : string ;
/** 0-indexed turn number */
turnIndex : number ;
/** User's speech-to-text transcript */
userTranscript : string | null ;
/** Duration of user's speech in milliseconds */
userAudioDurationMs : number | null ;
/** Agent's text response */
agentResponse : string | null ;
/** Duration of agent's synthesized speech in milliseconds */
agentAudioDurationMs : number | null ;
/** Speech-to-text API latency in milliseconds */
sttLatencyMs : number | null ;
/** LLM API latency in milliseconds */
llmLatencyMs : number | null ;
/** Text-to-speech API latency in milliseconds */
ttsLatencyMs : number | null ;
// Note: ragLatencyMs is tracked in TurnResult internally but not persisted to the DB turn record
/** Input tokens for this turn */
inputTokens : number | null ;
/** Output tokens for this turn */
outputTokens : number | null ;
/** ISO 8601 timestamp: when this turn started */
startedAt : string ;
/** ISO 8601 timestamp: when this turn completed */
completedAt : string | null ;
}
Start a new conversation with an agent
Requirements:
Agent must exist and have status active
Status Codes:
Code Description 201Conversation started 404Agent not found 409Agent is not active
curl -X POST https://api.gomobile.ma/api/agents/550e8400-e29b-41d4-a716-446655440000/conversations \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '
{
"title": "Customer inquiry",
"userId": "user-uuid-123"
}
'
Response:
{
"id" : "770e8400-e29b-41d4-a716-446655440002" ,
"organizationId" : "660e8400-e29b-41d4-a716-446655440001" ,
"agentId" : "550e8400-e29b-41d4-a716-446655440000" ,
"mastraThreadId" : "880e8400-e29b-41d4-a716-446655440003" ,
"mastraResourceId" : "org-660e8400" ,
"userId" : "user-uuid-123" ,
"contactId" : null ,
"callId" : null ,
"nodeId" : null ,
"title" : "Customer inquiry" ,
"messageCount" : 0 ,
"totalInputTokens" : 0 ,
"totalOutputTokens" : 0 ,
"status" : "active" ,
"exitReason" : null ,
"exitPhrase" : null ,
"summary" : null ,
"extractedVariables" : {},
"startedAt" : "2025-01-15T10:30:00.000Z" ,
"lastMessageAt" : null ,
"endedAt" : null ,
"createdAt" : "2025-01-15T10:30:00.000Z" ,
"updatedAt" : "2025-01-15T10:30:00.000Z"
}
List conversations for an agent
Status Codes:
Code Description 200Paginated list of conversations 404Agent not found
Get a single conversation by ID
Status Codes:
Code Description 200Conversation found 404Conversation not found
Send a message in a conversation and receive the agent’s …
Status Codes:
Code Description 200Message sent, response returned 404Conversation not found 409Conversation is not active
curl -X POST https://api.gomobile.ma/api/conversations/770e8400/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '
{
"message": "I need help with my order"
}
'
Response:
{
"response" : "I'd be happy to help you with your order! Could you please provide your order number?" ,
"usage" : {
"inputTokens" : 245 ,
"outputTokens" : 28
}
}
Get all messages in a conversation
Status Codes:
Code Description 200Messages retrieved 404Conversation not found
Stream a message response using Server-Sent Events
Status Codes:
Code Description 200Stream started 404Conversation not found 409Conversation is not active
Event Types:
// Request
POST /conversations/770e8400/messages/stream
Authorization: Bearer <token>
Content-Type: application/json
{ "message": "What is your return policy?" }
// Response (SSE stream)
data: {"type":"text","text":"Our "}
data: {"type":"text","text":"return "}
data: {"type":"text","text":"policy "}
data: {"type":"text","text":"allows "}
data: {"type":"text","text":"returns within 30 days."}
data: {"type":"usage","usage":{"inputTokens":245,"outputTokens":12}}
data: [DONE]
Frontend Integration Notes:
Use the EventSource API or a library like eventsource-parser for SSE parsing
Each data: line contains a JSON object except the final terminator which is the raw string [DONE]
The stream ends when you receive data: [DONE]
If you receive an error event, display the error message and close the connection
Token usage is sent as a separate event after all text chunks
End an active conversation programmatically
Status Codes:
Code Description 200Conversation ended 404Conversation not found 409Conversation is not active