# Stream a Run

> Consume committed Server-Sent Event or WebSocket frames and reconnect without treating transport loss as cancellation.

## Before you begin {#before-you-begin}

Start or identify the exact Run and retain its namespace, Agent, session, and Run id. Obtain `run:read`. Streaming is tied to committed workflow output; a network disconnect does not stop the Run.

## Steps {#steps}

1. Connect to `GET /v1/namespaces/:namespace/agents/:agent/sessions/:session/stream?runId=:runId` with Bearer authorization and `Accept: text/event-stream` for Server-Sent Events.
2. Record each frame’s sequence or event id after the application accepts it. On reconnect, send the latest accepted value as `Last-Event-ID` so the stream can replay committed frames after that cursor.
3. Supply `x-constal-stream-client` or `clientId` when one logical consumer needs stable acknowledgement tracking.
4. For WebSocket transport, send the standard upgrade headers to the same route. The platform applies the same Run authorization and cursor semantics.
5. Treat disconnect as transport loss. Reconnect, then read Run detail to determine whether execution is active, suspended, complete, failed, cancelled, or stopped.
6. Built-in OpenAI Chat Completions and Anthropic Messages adapters encode the same committed Agent stream. They do not create a different Agent, session, or Run identity.

## Verify {#verify}

Disconnect a test client after several frames, reconnect from the last accepted id, and confirm no accepted frame is processed twice. After a terminal frame, compare the assembled output with Run detail and the committed fact. Confirm an unauthorized caller cannot attach by guessing the Run id.

## Next steps {#next-steps}

Use [Resolve waits and control Runs](/docs/runs/waits-and-controls.md) for operator actions and [Operate Agents](/docs/agents/operate.md) for the deployment and bindings that produced the stream.
