GoRunner

Subscribe to a run's live progress (Server-Sent Events)

Requires scope run:read
GET
/api/runs/{id}/stream

A long-lived text/event-stream (SSE), not a JSON document. The connection is opened while the run is executing and relays the worker's progress events as they happen. Send Accept: text/event-stream; the response sets Cache-Control: no-cache and X-Accel-Buffering: no.

What arrives on the wire, in order:

  1. One NAMED event connected whose data is {"runId":"<uuid>"} — sent immediately, and only confirming that the subscription is live.
  2. Zero or more UNNAMED events (SSE default type message), each a single JSON object of shape {"type":..., "runId":..., "nodeId":..., "status":..., "data":..., "error":...} — see the RunStreamEvent schema for the type vocabulary.
  3. Comment lines : ping every 25 seconds to keep the connection alive. These are SSE comments, not events; ignore them.

Things a client MUST know:

  • There is NO replay and NO Last-Event-ID support. You only receive events published after you connect; anything that happened before is only available from GET /api/runs/{id}. Open the stream before or immediately after starting the run, and reconcile with the run detail when you reconnect.
  • The server NEVER closes the stream by itself. After a terminal event (run_completed, run_failed, run_cancelled) nothing further will arrive — the client is responsible for disconnecting. A stream opened on an already-finished run yields connected and pings only, forever.
  • run_paused events carry the wait's resume details in data, including the raw resumeToken when the wait is webhook/approval based. That token can resume the run through the public resume endpoint — treat the stream as privileged.
  • Event data is progress metadata only; step OUTPUT is not streamed. Read it from GET /api/runs/{id} (steps[].outputData).

Authorization

bearerAuth
AuthorizationBearer <token>

An API token: Authorization: Bearer grt_…. Mint one in the app under Settings → Workspace → API tokens; the raw value is shown once. Scopes confine the token — see x-permission on each operation.

In: header

Path Parameters

id*string

The run id (UUID).

Formatuuid

Response Body

text/event-stream

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/runs/497f6eca-6276-4993-bfeb-53cbbbba6f08/stream"
"event: connected\ndata: {\"runId\":\"3c0ee072-37f7-4808-91ed-b713dc2fd0a7\"}\n\ndata: {\"type\":\"step_started\",\"runId\":\"3c0ee072-37f7-4808-91ed-b713dc2fd0a7\",\"nodeId\":\"parse_csv\",\"status\":\"running\",\"data\":{\"attempt\":0}}\n\ndata: {\"type\":\"step_completed\",\"runId\":\"3c0ee072-37f7-4808-91ed-b713dc2fd0a7\",\"nodeId\":\"parse_csv\",\"status\":\"completed\",\"data\":{\"attempt\":0,\"duration_ms\":3}}\n\ndata: {\"type\":\"run_completed\",\"runId\":\"3c0ee072-37f7-4808-91ed-b713dc2fd0a7\",\"status\":\"completed\"}\n\n: ping\n\n"