Skip to main content
Agent にタスクを委任する

SSE Event Stream

Qoder Cloud Agents streams public Session events over Server-Sent Events (SSE).

Connection URL

GET https://api.qoder.com/api/v1/cloud/sessions/{session_id}/events/stream
Request headers:
Authorization: Bearer $QODER_ACCESS_TOKEN
Accept: text/event-stream
By default, an Agent response is written to the Session event history and emitted on the stream as a complete public event, such as agent.message, after generation finishes. This guide calls that complete event a buffered event. The stream endpoint supports the Last-Event-ID header for reconnection. For ordinary buffered events, the stream resumes after that ID. In-progress event deltas have the additional behavior described below. Use event_deltas[] to receive an Agent response incrementally on this stream connection. Repeat the parameter to request both supported event types:
GET /api/v1/cloud/sessions/{session_id}/events/stream?event_deltas[]=agent.message
GET /api/v1/cloud/sessions/{session_id}/events/stream?event_deltas[]=agent.thinking
GET /api/v1/cloud/sessions/{session_id}/events/stream?event_deltas[]=agent.message&event_deltas[]=agent.thinking
The selection applies only to the current stream connection and does not affect other connections to the same Session. Without event_deltas[], the connection receives only the complete event after the response finishes. Thread event streams do not support this parameter.

SSE Format

Each event uses standard SSE fields:
id: evt_019e392c0d787cfaa21bda98e06cd913
event: agent.message
data: {"id":"evt_019e392c0d787cfaa21bda98e06cd913","type":"agent.message","content":[{"type":"text","text":"Hello"}],"processed_at":"2026-05-18T03:40:48.888851795Z"}
Heartbeat comments may be sent to keep the connection alive.

Event Deltas

Incremental agent.message output begins with event_start, followed by one or more event_delta frames:
id: evt_00jjujk9fbnr4wkj2gh8
event: event_start
data: {"event":{"id":"evt_00jjujk9fbnr4wkj2gh8","type":"agent.message"},"type":"event_start"}

id: evt_00jjujk9fbnr4wkj2gh8
event: event_delta
data: {"delta":{"content":{"text":"Hello","type":"text"},"index":0,"type":"content_delta"},"event_id":"evt_00jjujk9fbnr4wkj2gh8","type":"event_delta"}
Incremental agent.thinking output is start-only. No event_delta frames follow:
id: evt_00jjujk9fbnr55q5rtyp
event: event_start
data: {"event":{"id":"evt_00jjujk9fbnr55q5rtyp","type":"agent.thinking"},"type":"event_start"}
The SSE id:, event_start.event.id, every event_delta.event_id, and the later buffered event id are identical for the same message or thinking event. A typical response with both event types follows this order:
span.model_request_start
event_start (agent.thinking)
agent.thinking
event_start (agent.message)
event_delta (agent.message)
agent.message
span.model_request_end
Event delta frames do not contain top-level JSON id or processed_at fields. They do not appear in event list/history responses. The buffered agent.message is the authoritative result, and agent.thinking never exposes reasoning content.

Reconnecting During Event Deltas

Use the SSE Last-Event-ID header when reconnecting. Behavior depends on the cursor and whether the message is still being generated:
  1. The cursor is an event before the current event_start, and generation is still in progress. The stream replays that message's event_start and retained historical event_delta frames, then continues with new deltas.
  2. The cursor equals the current event_start.event.id, and generation is still in progress. Historical deltas for that message are not replayed. The stream emits only deltas generated after reconnection, followed by the buffered final event.
  3. Generation has completed. Historical deltas for that message are no longer replayed. Reconnecting from an earlier buffered event yields the final agent.message; reconnecting with that final message's ID resumes after it.
All frames for one incrementally streamed event use the same ID. If a client needs to rebuild the entire in-progress event after a disconnect, it should reconnect using the buffered event ID immediately before that event's event_start, discard or deduplicate its partial local state, and process the replayed event_start and event_delta frames again.

Common Event Flow

session.status_running
session.thread_status_running
user.message
span.model_request_start
agent.thinking
agent.tool_use
agent.tool_result
agent.message
span.model_request_end
session.thread_status_idle
session.status_idle
Not every turn contains every event. Managed-agent Sessions can also emit thread events such as session.thread_created, session.thread_status_running, agent.thread_message_sent, and agent.thread_message_received.

Model request spans

span.model_request_start contains id, processed_at, and type. The matching span.model_request_end contains id, is_error, model_request_start_id, processed_at, and type. Its model_request_start_id equals the corresponding start event's id. When credits are available for the model call, the end event also contains model_usage: {"credits": 1.25}. credits is floored to at most 2 decimal places.
Note: Public agent.thinking events only carry id, processed_at, and type. The reasoning content is intentionally not exposed; treat the event as a marker that the Agent paused to reason. Several other agent-generated events also omit processed_at — treat the field as optional when parsing.

Connection lifecycle

  • session.status_idle indicates the current turn finished. The connection should stay open and wait for the next turn.
  • session.status_terminated and session.deleted are terminal — the client should stop reconnecting; further events will not arrive.
  • session.status_rescheduled is a transient signal; the stream may briefly disconnect, then reconnect once the runtime is ready.
  • For network drops, reconnect with the Last-Event-ID header. See Reconnecting During Event Deltas for the special handling of an in-progress event.

Tool Responses

When the stream emits an agent.tool_use that requires confirmation, send user.tool_confirmation to POST /api/v1/cloud/sessions/{session_id}/events with the tool event ID:
{
  "events": [
    {
      "type": "user.tool_confirmation",
      "tool_use_id": "evt_01JZ6Q3FB6SG8F7J1M2N",
      "result": "allow"
    }
  ]
}
When the stream emits agent.custom_tool_use, execute the custom tool in your client and send user.custom_tool_result.

Event History

Use the list endpoint for historical events and pagination:
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events?limit=20&order=desc" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"
List responses use data and next_page. See List events and Session schemas.