POST /v1/agents/{agent_id}/chat/stream takes exactly the same request as the synchronous chat endpoint: same body, same Authorization and Idempotency-Key headers, same full permission, same conversation rules, billing and error codes. Only the transport differs: the response is text/event-stream.
Events
Each event is named and carries one JSONdata line.
Reasoning text and tool activity are never part of the stream.
response.completed always carries the full final text, so a client that missed some deltas can reconcile from it rather than from the concatenated deltas.Errors on a stream
Failures before the stream is established (invalid key, validation,idempotency_conflict, conversation_busy, a disabled agent, a rate limit) are ordinary JSON error envelopes with their HTTP status; check response.ok before you start reading events.
Once headers are sent the status is already 200. A failure after that point (for example insufficient_balance or internal_error) arrives as the error event, with the same fields as the envelope, and closes the stream.
Disconnects and retries
A client that drops the connection does not stop the reply: it is still produced and stored, and the idempotency record is completed. A retry with the sameIdempotency-Key streams response.created followed directly by response.completed with the stored result; the deltas are not replayed. See Idempotency.