Stream API (Socket)
Base transport endpoints
Streaming endpoints
| Transport | Endpoint / Destination | Purpose |
|---|---|---|
| SSE | GET /api/v1/conversation/stream/{conversationId} | Server-sent live audit events for one conversation |
| STOMP WS | WS handshake: /ws-convengine | WebSocket endpoint for STOMP clients |
| STOMP topic | /topic/convengine/audit/{conversationId} | Conversation-scoped audit stream destination |
Flow contract
Conversation turns are submitted through POST /api/v1/conversation/message.
Socket/SSE channels stream audit stages for that same conversationId.
SSE subscription
SSE client (browser)
JAVASCRIPT
const conversationId = "9bf7540a-b129-4685-a120-730e8a0cb94b";
const source = new EventSource(
"/api/v1/conversation/stream/" + conversationId
);
source.onmessage = (event) => {
// fallback event channel
console.log("SSE message:", event.data);
};
source.addEventListener("STEP_ENTER", (event) => {
console.log("STEP_ENTER:", JSON.parse(event.data));
});
source.addEventListener("ASSISTANT_OUTPUT", (event) => {
console.log("ASSISTANT_OUTPUT:", JSON.parse(event.data));
});
source.addEventListener("VERBOSE", (event) => {
console.log("VERBOSE:", JSON.parse(event.data));
});
STOMP subscription
STOMP client (JS)
JAVASCRIPT
// npm i @stomp/stompjs sockjs-client
import { Client } from "@stomp/stompjs";
import SockJS from "sockjs-client";
const conversationId = "9bf7540a-b129-4685-a120-730e8a0cb94b";
const client = new Client({
webSocketFactory: () => new SockJS("/ws-convengine"),
reconnectDelay: 5000,
onConnect: () => {
client.subscribe(
"/topic/convengine/audit/" + conversationId,
(message) => console.log("STOMP audit:", JSON.parse(message.body))
);
},
});
client.activate();
Socket payload contract (v2.0.8)
2.0.8 introduces envelope type separation in the stream payload.
eventType: "AUDIT"for audit stage eventseventType: "VERBOSE"for verbose runtime progress/error events
AUDIT envelope example
JSON
{
"eventType": "AUDIT",
"auditId": 12031,
"stage": "STEP_ENTER",
"createdAt": "2026-02-14T10:22:01.102Z",
"payload": {
"_meta": {
"stage": "STEP_ENTER",
"conversationId": "9bf7540a-b129-4685-a120-730e8a0cb94b",
"intent": "FAQ",
"state": "IDLE"
}
},
"verbose": null
}
VERBOSE envelope example
JSON
{
"eventType": "VERBOSE",
"auditId": null,
"stage": "VERBOSE",
"createdAt": "2026-02-27T13:40:24.250Z",
"payload": {
"verbose": {
"verboseId": 4,
"eventType": "VERBOSE_PROGRESS",
"stepName": "McpToolStep",
"determinant": "MCP_TOOL_CALL",
"intent": "LOAN_APPLICATION",
"state": "COLLECTING_DETAILS",
"ruleId": null,
"toolCode": "loan.credit.rating.check",
"level": "INFO",
"text": "Checking credit rating from credit union."
}
},
"verbose": {
"verboseId": 4,
"eventType": "VERBOSE_PROGRESS",
"stepName": "McpToolStep",
"determinant": "MCP_TOOL_CALL",
"level": "INFO",
"text": "Checking credit rating from credit union."
}
}
Socket + Audit API usage
- Call POST /api/v1/conversation/message with
conversationId. - Subscribe to SSE/STOMP for live stages.
- Query GET /api/v1/conversation/audit/{conversationId} for raw events.
- Query GET /api/v1/conversation/audit/{conversationId}/trace for normalized step timeline.
Operational recommendation
Use REST endpoints for deterministic request/response behavior, and use streaming endpoints for observability UX.