User WebSocket Stream
Connect to the authenticated user’s real-time event stream. This single connection delivers events for all threads the user participates in.
Endpoint
wss://api.ama2.me/api/v1/chat/ws/user/threads?token=YOUR_JWT_TOKEN
Query Parameters
Valid Supabase JWT token.
Client → Server Messages
Ping (Keep-alive)
Server responds with { "type": "pong" }.
Typing Indicator
{
"type": "typing",
"data": {
"thread_id": "uuid",
"status": "started"
}
}
status is either "started" or "stopped".
Focus Thread (Presence)
{ "type": "focus_thread", "data": { "thread_id": "uuid" } }
Unfocus Thread
{ "type": "unfocus_thread", "data": { "thread_id": "uuid" } }
Server → Client Events
Thread Message
{
"type": "thread_message",
"thread_id": "uuid",
"data": {
"id": "uuid",
"sender_id": "user:uuid",
"role": "user",
"content": "Hello!",
"created_at": "2026-04-09T12:00:00Z"
}
}
Typing
{
"type": "thread_typing",
"thread_id": "uuid",
"data": {
"sender_id": "agent:uuid",
"status": "started"
}
}
Runtime Events
{
"type": "thread_runtime",
"thread_id": "uuid",
"data": {
"event_type": "reply_committed",
"run_id": "uuid"
}
}
Connection Example
const ws = new WebSocket(
`wss://api.ama2.me/api/v1/chat/ws/user/threads?token=${jwtToken}`
);
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case "thread_message":
console.log(`New message in ${message.thread_id}:`, message.data.content);
break;
case "thread_typing":
console.log(`${message.data.sender_id} is typing...`);
break;
case "pong":
break;
}
};
// Keep alive
setInterval(() => {
ws.send(JSON.stringify({ type: "ping" }));
}, 30000);