Skip to main content
Session events are the log of user input, agent output, tool activity, and status changes for a session. Use the list endpoint for durable history and the stream endpoint for live updates. For every event shape, see the Events Reference.

List events

Returns persisted events for a session in sequence order.
Response:

Stream events

Opens a Server-Sent Events stream for new events. Use after with the last durable numeric sequence already loaded from event history to avoid replaying older events on the initial connection.
Each SSE message uses the event type as the SSE event name and the event envelope as JSON data.

Reconnect and resume

Treat the SSE id as an opaque transport cursor, not as the event’s numeric sequence. Browsers automatically send it back as Last-Event-ID when an EventSource reconnects to the same URL. Some replayed history frames may not include an SSE id. The live stream is therefore not the source of truth for complete history. On every new connection or reconnect:
  1. Open the SSE stream and buffer incoming frames.
  2. List durable events using GET /events?after={lastSequence}.
  3. Merge the history response and buffered frames by event id, then advance your numeric sequence cursor.
  4. Continue consuming the live stream.
  5. Let the SSE client preserve Last-Event-ID; do not parse or synthesize it.
Opening the stream first avoids losing events created between the history request and the live connection. The after query parameter and event sequence belong to durable history. The SSE id and Last-Event-ID belong to live transport resume.

Event envelope

List and stream responses wrap every payload in the same event envelope: For inbound user.message events, payload is the accepted event. If the event included metadata, it is returned as payload.metadata. Metadata is persisted turn context and is not part of the visible payload.content text. If the event included attachments, the attachment metadata and dataUrl source are included in that payload so the event is auditable.

Usage snapshots

When available, terminal turn events include a usage object with the usage for that completed turn. This is the right object to forward to observability systems such as Langfuse for per-generation token and cost reporting. Session responses also expose an aggregate usage object for lifetime session totals.
cost_usd is omitted when pricing is unavailable; cost_status explains whether the cost is estimated, included, or unknown. last_turn_latency_ms measures the wall-clock time for that completed turn. context_* fields describe the current context window at the end of the turn; they are not billable deltas.

Event categories

See the Events Reference for schemas and examples.

Required actions

When a session.status_idle event has payload.stop_reason.type set to requires_action, the turn is paused until your application sends the matching user event.

Clarify requests

When the agent uses the clarify tool, the stream emits an agent.clarify_request followed by a session.status_idle with stop_reason.type: "requires_action". The turn is paused until you answer.
payload.choices is a list of multiple-choice options, or null for an open-ended question. Answer by sending a user.clarify_result event with the request_id and the user’s answer (an empty answer skips the question, letting the agent proceed with its own default). The paused turn then resumes and continues streaming.

Custom tool requests

When the model calls one of your custom tools, the stream emits agent.custom_tool_use, then session.status_idle with requires_action. Your application should execute the tool and send user.custom_tool_result.
See Send Session Events for the response format. For asynchronous application-owned work, see Long-running custom tools. That flow defines when session.tool_updated is emitted and how clients reconcile the ephemeral patch with durable event history.

Automatic title updates

When you create a session without a title, the agent generates a short, descriptive one from the first exchange (see Sessions). When the title is ready, the stream emits session.title_updated; update your UI from payload.title:
The event is persisted in the session event log, so it is returned by GET /events and replayed on reconnect. It also updates the session’s title field. Manual titles are authoritative: if you create or update a session with an explicit title, the automatic title is not applied. To read the current title at any time, call Get a session.

Send events

Use POST /v1/sessions/{sessionId}/events to send user input and control events. See Send Session Events.

Errors

Last modified on July 23, 2026