Skip to main content
The WebSocket session is the richest transport for chat UIs: send message frames, receive the reply as a live token stream, and recover any missed events after a reconnect. It complements the REST and SSE transports — same conversation model, same threads.

Connect

Authenticate on the upgrade request with your Bearer token:
Invalid or expired credentials close the connection with code 1008 (policy violation). Internal errors close with 1011.

Query parameters

include_trace
boolean
default:"true"
When true, the final message envelope carries data.trace_info — the reasoning trace.
events
string
Omit for the minimal stream (token deltas + completion). all or verbose opts into the full workflow/lifecycle event set.
resume_after
integer
With task_id, replays buffered envelopes with seq greater than this value on connect — gap recovery after a reconnect.
task_id
string
Thread id to replay from on connect (pairs with resume_after).

Frames you send

message — submit a turn

type
string
required
Must be "message".
agent_id
string
required
The target agent — use the agent_id returned by the token exchange.
thread_id
string
Omit to auto-create a thread; its id is announced back as the first envelope. Pass it to continue an existing thread.
user_id
string
End-user reference for an auto-created thread.
text
string
required
The message content.

resume — replay after a reconnect

Replays buffered envelopes with seq > resume_after for the active thread.

Envelopes you receive

Every server frame is a sequenced envelope:
typeMeaningdata
threadThe resolved thread id, once per thread per connection{ "thread_id": "..." }
eventA streaming event while the agent worksToken deltas carry data.text under event name thread-message-text-content-updated
messageTurn complete — the full agent replyThe same message object as REST, plus trace_info when include_trace=true
errorA recoverable error; the socket stays open{ "error": "...", "code": 402 } for session errors, or the turn error’s message and status
Track the highest seq you’ve processed — that’s your resume cursor. Locally-generated errors use seq: -1 and are not resumable.

Code example

Node.js

Best practices

  • Reconnect with resume — on an abnormal close, reconnect with task_id + resume_after (or send a resume frame) instead of restarting the turn; you get exactly the envelopes you missed.
  • Track seq continuously — a gap in seq means you missed frames; resume from your last processed value.
  • Exponential backoff — back off between reconnection attempts.
  • Keep the thread id — persist thread_id across reconnects to stay in the same conversation.
The full machine-readable contract is published as an AsyncAPI document at /asyncapi.yaml.