Streaming protocol
The session SSE route, its credential, event formats, and resume cursor.
Use GET /sessions/{id}/stream with a token issued by POST /v1/sessions/streamToken.
An API key is not accepted on the stream route. Token issuance requires data scope;
the issued credential grants read of one session. The default token lifetime is 300
seconds and the maximum is 3600 seconds.
Request
curl -N "https://app.trycereal.ai/sessions/$SESSION_ID/stream?format=cereal" \
-H "Authorization: Bearer $STREAM_TOKEN"A fetch reader should use the authorization header. Native EventSource can use ?token=
when it cannot set a header. A token pinned to a format rejects a different requested
format. An unpinned token permits the request to choose a supported format.
Formats and disclosure
| Format | Frames |
|---|---|
cereal | Client-safe session events |
ai-sdk | AI SDK UI message chunks |
ag-ui | AG-UI events |
The stream is a projection, not the raw event log. Signed include groups control
additional disclosure such as cost. Do not assume fields from sessions.events are
available in a browser stream. The TypeScript subscribe helper requires an explicit format.
Resume
Durable frames carry id: <seq> or id: <seq>.<frame>. Reconnect with Last-Event-ID;
after supports starting at a sequence cursor. Ephemeral typing frames carry no durable
cursor. Replayed durable messages reconstruct text that transient deltas cannot preserve.
A resume cursor records where to continue, not the conversation itself. If the page lost its transcript state, replay the history instead of resuming beyond messages it no longer holds.
Writes and decisions
The stream is read-only. Send messages through sessions.send and approval decisions
through sessions.decide, using your application's server credential after authorizing
the customer. The complete browser integration is in the chat tutorial.
See stream operation reference for request fields and browser SDK for reconnection behavior.