Events
A WebSocket that streams every bot's reply progress and changes to the bot list.
Connect a WebSocket to /api/events with the same bearer token:
wss://bots.example.com/api/events
Authorization: Bearer <access token>
The server sends one JSON text message per event, and pings every 20 seconds. Browsers' built-in WebSocket can't send an Authorization header, so connect from a client that can (Node, Python, .NET and most other WebSocket libraries). You never need to send anything; close the socket when you're done. Up to 2,000 events are buffered for a slow client, after which the oldest are dropped.
The event
{ "turn": { "botId": "scout", "turnId": "6c1e…", "kind": "Text", "text": "Here are three papers" } }
| Field | |
|---|---|
turn |
A turn event: something happened in a reply |
botsChanged |
true when bots were added, changed or removed (by any client). Fetch GET /bots again. |
relay |
A request for the desktop app (passing hand-offs between machines, browser commands). Only the most recently connected client gets these; other clients can ignore them. |
Turn events
Every turn event has botId, turnId and kind. The other fields depend on the kind:
kind |
Fields | |
|---|---|---|
Started |
request, authorId, authorName, authorColor |
A reply began. request is set when another bot sent the message. In a group chat, author* is the member replying. |
Thinking |
text |
The next chunk of the model's reasoning |
Text |
text |
The next chunk of the answer |
ToolStarted |
stepId, title, detail |
A tool step began (reading a file, running a command…) |
ToolFinished |
stepId, succeeded, summary |
It ended |
ApprovalRequested |
approval |
An approval card: answer with POST /approvals/{id} |
ApprovalResolved |
approval, choice |
It was answered (or timed out) |
QuestionAsked |
question |
A question card: answer with POST /questions/{id} |
QuestionAnswered |
question, answer |
It was answered, skipped or timed out |
Finished |
outcome, error, reply, context, final |
The reply ended: Completed, Failed or Stopped. reply is the saved message with its work log and metrics. |
In a group chat a turn is several replies, each from Started to Finished. Only the last Finished has final: true; outside group chats it's always true.
Example: print replies as they stream
import WebSocket from "ws";
const ws = new WebSocket("wss://bots.example.com/api/events", {
headers: { Authorization: `Bearer ${process.env.TOKEN}` },
});
ws.on("message", (data) => {
const e = JSON.parse(data);
if (!e.turn) return;
if (e.turn.kind === "Text") process.stdout.write(e.turn.text);
if (e.turn.kind === "Finished" && e.turn.final) console.log(`\n[${e.turn.outcome}]`);
});