> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crewship.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Stream Events

> Stream real-time events from a run using Server-Sent Events (SSE)

## Path Parameters

<ParamField path="id" type="string" required>
  Run ID (e.g., `run_xyz789abc`)
</ParamField>

## Event Format

Events are sent as SSE `data` messages with JSON payloads:

```
data: {"type":"run.started","data":{"entrypoint":"default"}}

data: {"type":"task.started","data":{"task":"Research AI trends","agent":"Researcher"}}

data: {"type":"log","data":{"message":"Found 15 relevant results"}}
```

## Event Types

When the runner machine is reachable, you receive detailed events from the crew execution:

| Type             | Description                  |
| ---------------- | ---------------------------- |
| `run.started`    | Run execution began          |
| `run.completed`  | Run finished successfully    |
| `run.failed`     | Run encountered an error     |
| `task.started`   | A task began execution       |
| `task.completed` | A task finished              |
| `agent.action`   | An agent performed an action |
| `tool_use`       | A tool was invoked           |
| `log`            | Log message from the crew    |
| `artifact`       | An artifact was produced     |

If the runner machine is not reachable, the API falls back to polling the database and sends simpler status events:

| Type        | Description                                                      |
| ----------- | ---------------------------------------------------------------- |
| `heartbeat` | Periodic status update while the run is in progress              |
| `complete`  | Run reached a terminal state (`succeeded`, `failed`, `canceled`) |
| `error`     | An error occurred (e.g., run not found)                          |
| `timeout`   | The SSE connection timed out                                     |

<RequestExample>
  ```bash cURL theme={null}
  curl -N \
    -H "Authorization: Bearer YOUR_API_KEY" \
    "https://api.crewship.dev/v1/runs/run_xyz789abc/events"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.crewship.dev/v1/runs/run_xyz789abc/events', {
    headers: {
      Authorization: 'Bearer YOUR_API_KEY',
    },
  })

  const reader = response.body.getReader()
  const decoder = new TextDecoder()
  let buffer = ''

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    buffer += decoder.decode(value, { stream: true })
    const lines = buffer.split('\n')
    buffer = lines.pop() || ''

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const event = JSON.parse(line.slice(6))
        console.log(event.type, event)

        if (['complete', 'run.completed', 'run.failed'].includes(event.type)) {
          console.log('Run finished')
          return
        }
      }
    }
  }
  ```
</RequestExample>

<ResponseExample>
  ```text SSE Stream (runner connected) theme={null}
  data: {"type":"run.started","data":{"entrypoint":"default"}}

  data: {"type":"task.started","data":{"task":"Research AI trends","agent":"Researcher"}}

  data: {"type":"log","data":{"message":"Found 15 relevant results"}}

  data: {"type":"task.completed","data":{"task":"Research AI trends","agent":"Researcher"}}

  data: {"type":"artifact","data":{"name":"report.md"}}

  data: {"type":"run.completed","data":{"status":"succeeded"}}

  ```

  ```text SSE Stream (fallback polling) theme={null}
  data: {"type":"heartbeat","status":"running"}

  data: {"type":"heartbeat","status":"running"}

  data: {"type":"complete","status":"succeeded","output":{"result":"Generated report..."},"error":null}

  ```
</ResponseExample>

## Notes

* If the run is already in a terminal state (`succeeded`, `failed`, `canceled`), a single `complete` event is returned immediately
* If the runner machine is reachable, events are proxied directly from the machine in real time
* If the machine is not reachable, the API falls back to polling the database every 2 seconds and sending `heartbeat` events
* The connection times out after 30 minutes
