/api/v1/agent/status/streamAgent Status Stream (SSE)
Server-Sent Events stream of real-time agent state changes. Receives a full snapshot on connect and on every meaningful state transition.
Overview
Opens a Server-Sent Events (SSE) connection that pushes agent status snapshots in real time. The stream sends an initial snapshot on connect, then sends updates only when the agent state meaningfully changes (e.g. idle to active, tool switches, sessions starting or ending).
Events are debounced at 1 second to avoid flooding during rapid tool sequences. A keepalive comment is sent every 30 seconds when idle.
If POCKETPAW_STATUS_API_KEY is set, requests must include the key via the X-Status-Key header or ?key= query parameter.
Event Format
The stream uses the standard SSE protocol. Each event has the type status with a JSON data payload matching the GET /api/v1/agent/status response schema.
event: statusdata: {"global":{"state":"active","active_sessions":1,...},"sessions":[...]}
event: statusdata: {"global":{"state":"idle","active_sessions":0,...},"sessions":[]}
: keepaliveDeduplication
The stream only sends events when the agent state actually changes. Repeated snapshots with the same global state, session states, and tool names are suppressed. Timing fields like duration_seconds and uptime_seconds do not trigger new events on their own.
curl -N http://localhost:8000/api/v1/agent/status/stream \ -H "X-Status-Key: your-key"const evtSource = new EventSource( "http://localhost:8000/api/v1/agent/status/stream?key=your-key");
evtSource.addEventListener("status", (event) => { const status = JSON.parse(event.data); console.log(status.global.state);
for (const session of status.sessions) { console.log(`${session.channel}: ${session.state}`); if (session.tool_name) { console.log(` Running: ${session.tool_name}`); } }});import jsonimport httpx
with httpx.stream( "GET", "http://localhost:8000/api/v1/agent/status/stream", headers={"X-Status-Key": "your-key"},) as response: for line in response.iter_lines(): if line.startswith("data: "): status = json.loads(line[6:]) print(status["global"]["state"])event: statusdata: {"global":{"state":"idle","active_sessions":0,"max_concurrent":5,"uptime_seconds":120},"sessions":[]}
event: statusdata: {"global":{"state":"active","active_sessions":1,"max_concurrent":5,"uptime_seconds":125},"sessions":[{"session_key":"websocket:abc123","session_id":"abc123","channel":"websocket","title":null,"state":"thinking","tool_name":null,"duration_seconds":0.5,"token_usage":null,"error_message":null}]}
event: statusdata: {"global":{"state":"active","active_sessions":1,"max_concurrent":5,"uptime_seconds":128},"sessions":[{"session_key":"websocket:abc123","session_id":"abc123","channel":"websocket","title":null,"state":"tool_running","tool_name":"bash","duration_seconds":1.2,"token_usage":{"input":500,"output":100},"error_message":null}]}
: keepalive
event: statusdata: {"global":{"state":"idle","active_sessions":0,"max_concurrent":5,"uptime_seconds":140},"sessions":[]}curl -X GET "http://localhost:8000/api/v1/agent/status/stream" \
-H "Content-Type: application/json"const response = await fetch("http://localhost:8000/api/v1/agent/status/stream", {
method: "GET",
headers: {
"Content-Type": "application/json"
},
});
const data = await response.json();
console.log(data);import requests
response = requests.get(
"http://localhost:8000/api/v1/agent/status/stream",
headers={'Content-Type':'application/json'},
)
print(response.json())package main
import (
"fmt"
"net/http"
"io"
)
func main() {
req, _ := http.NewRequest("GET", "http://localhost:8000/api/v1/agent/status/stream", nil)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}