Skip to content

Event catalogue

Protocol version 2. Both transports carry byte-identical bodies — see Streaming a run for the guarantees and the resumption rules.

Adding a type is a protocol change and bumps the version. Adding a field to a type’s data is additive, which is why the types are a closed set and the payloads are mappings: read an unknown key rather than refusing the frame.

Every frame carries exactly these keys:

{
"protocol": "…",
"seq": "…",
"run_id": "…",
"ts": "…",
"type": "…",
"segment_id": "…",
"data": "…"
}

segment_id says whether the envelope’s segment_id may be null for that type: required on a content frame you could not otherwise attribute, optional on run-level, notice and error frames.

Typesegment_iddata keysNotes
run.startoptionalagent_id, agent_revision_id, session_id, lane, trigger_kind, attemptFirst event of an attempt.
run.statusoptionalstatus, previousEvery transition, including resumption.
run.endoptionalstatus, usage, cost, duration_ms, failure_class?, failure_detail?Terminal for the attempt. Not emitted for a failure with a retry scheduled (D-514): telling a subscriber to close on a run that is about to produce more frames is the worse of the two errors.
segment.startrequiredkind, name, parent_segment_id?, group_key?, model_ref?, tool_slug?, child_run_id?Emitted before any content of the segment, by construction (annex 15 §3.2). ‘kind’ is the step vocabulary, not a fifth translation of it (D-158, D-517).
segment.endrequiredstatus, duration_ms, usage?, cost?, finish_reason?, error?Usage rides here. There is no separate usage event (annex 15 §3.2).
text.deltarequiredtextIncremental output. THE ONLY CHANNEL FOR OUTPUT TEXT (annex 15 §3.1).
thinking.deltarequiredtextReasoning traces, distinct from output.
tool.callrequiredtool_call_id, tool_slug, arguments_delta?, arguments?
tool.resultrequiredtool_call_id, ok, output_preview, truncated, bytesPreview only; the full value is in the step payload.
suspendoptionalkind, resume_contract, prompt, deadline_at?
resumeoptionalkind, resolved_by
noticeoptionallevel, code, message, attributes?Compaction applied, model fallback used, cache skipped, guardrail warned.
erroroptionalcode, message, retryable‘code’ is from error_codes below; a client never string-matches ‘message’.

run.end is terminal for the attempt; nothing follows it and a client may close on it.

These types are coalesced before delivery, so a client sees fewer, larger frames than the executor produced: text.delta, thinking.delta.

An error frame carries one of these, and a client never string-matches the message. They are the stream’s own vocabulary and are spelled differently from the HTTP error catalogue.

AUTH_FAILED, MALFORMED_FRAME, PROTOCOL_UNSUPPORTED, RUN_NOT_FOUND, BUDGET_EXCEEDED, RATE_LIMITED, MODEL_ERROR, TOOL_ERROR, GUARDRAIL_BLOCKED, CONTEXT_OVERFLOW, TIMEOUT, CANCELLED, SANDBOX_ERROR, CHANNEL_ERROR, INTERNAL_ERROR.

CodeMeaning
1000Normal close after run.end
4401Authentication failed or timed out (5 s to send the first frame)
4404Run not found or out of scope - deliberately indistinguishable
4409Protocol version unsupported