Skip to main content
GET
Stream conversation events

Server-Sent Events

This endpoint is a long-lived Server-Sent Events (SSE) stream, not a one-shot JSON response. Open it with an SSE client and keep it open — it emits one event per agent or platform update until you disconnect.
A comment line (: ping / : idle) is sent periodically as a keepalive so proxies don’t drop the connection — ignore it.

Event shape

Each event has an event: name, a monotonic id: cursor, and a single-line JSON data: payload:

Common events

final/error end a turn, not the stream — the next message produces the next batch. New event: names may be added over time; ignore ones you don’t recognize (standard SSE behavior).

Reconnecting

id: is an opaque, incrementing sequence. On reconnect, send the last one you saw as the Last-Event-ID header and the server replays the events you missed from the conversation journal. (EventSource sets Last-Event-ID automatically on auto-reconnect; on a fresh attach where you can’t set the header, pass ?since_seq=<id> instead.) An optional ?scope= query parameter narrows which events you receive.
To send a message and watch the reply, POST to Post a message (returns immediately) and read the result off this stream.

Authorizations

Authorization
string
header
required

Personal Access Token. Send as Authorization: Bearer hq_pat_....

Path Parameters

id
string<uuid>
required

Conversation id

Query Parameters

scope
string | null

Self-downgrade only. user strips diagnostic + accounting fields; admin / integrator and absent default to the trusted full vocabulary. Unknown values do NOT elevate -- see [crate::stream_scope::Scope::from_query]. Auth-derived scope replaces this in #729.

since_seq
integer<int64> | null

Explicit "I've already seen up to seq N" cursor for fresh attaches. The standard EventSource API doesn't let JS set Last-Event-ID on the initial request -- only on automatic reconnects -- so Studio passes its journal high-water mark here to avoid a race where events emitted between the journal fetch and the SSE subscribe vanish into the gap.

view
string | null

?view=admin opts a tenant admin into attaching to a conv stream they don't participate in. Non-admins are silently downgraded. Audited per-attach so admin tail reads of someone else's conv are observable.

Response

Server-Sent Events for the conversation's turn. Each frame is a named event (the agent token/tool/final event kinds, plus stale when the client lagged and done when the turn closes) carrying a JSON data payload and an id: sequence. Resume after a drop with the standard Last-Event-ID header, or pass ?since_seq= on a fresh attach. Native EventSource (cookie auth) and fetch-stream (Bearer PAT) both work.