> ## 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.

# Streaming

> Real-time event streaming from your crew runs

## Overview

Crewship provides real-time event streaming so you can:

* Monitor crew execution as it happens
* Build responsive UIs that update live
* Debug issues by watching the event flow
* Log events to external systems

## Streaming via CLI

The simplest way to stream events:

```bash theme={null}
crewship invoke --input '{"topic": "AI"}' --stream
```

Output updates in real-time:

```
▶ Run started: run_abc123
├─ [10:30:01] Starting crew execution
├─ [10:30:02] Researcher agent starting task
├─ [10:30:05] Tool: web_search("AI agents 2024")
├─ [10:30:12] Researcher agent completed task
├─ [10:30:13] Writer agent starting task
├─ [10:30:45] Writer agent completed task
├─ [10:30:46] Artifact: report.md
✅ Run completed in 45.2s
```

## Streaming via API

### Server-Sent Events (SSE)

Connect to the events endpoint with SSE:

```bash theme={null}
curl -N \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: text/event-stream" \
  "https://api.crewship.dev/v1/runs/run_abc123/events"
```

### JavaScript/TypeScript

```typescript theme={null}
const eventSource = new EventSource('https://api.crewship.dev/v1/runs/run_abc123/events', {
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
  },
})

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data)
  console.log(data.type, data.payload)
}

eventSource.onerror = (error) => {
  console.error('Stream error:', error)
  eventSource.close()
}
```

### Python

```python theme={null}
import requests

response = requests.get(
    "https://api.crewship.dev/v1/runs/run_abc123/events",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Accept": "text/event-stream"
    },
    stream=True
)

for line in response.iter_lines():
    if line:
        # Parse SSE format
        if line.startswith(b"data: "):
            data = json.loads(line[6:])
            print(data["type"], data["payload"])
```

## Event Types

### Run Lifecycle Events

| Event           | Description      | Payload                           |
| --------------- | ---------------- | --------------------------------- |
| `run.started`   | Execution began  | `{ run_id, started_at }`          |
| `run.completed` | Success          | `{ run_id, duration_ms, result }` |
| `run.failed`    | Error            | `{ run_id, error, stack_trace }`  |
| `run.canceled`  | Manually stopped | `{ run_id, canceled_at }`         |

### Agent Events

| Event             | Description      | Payload                   |
| ----------------- | ---------------- | ------------------------- |
| `agent.started`   | Agent began task | `{ agent, task }`         |
| `agent.completed` | Agent finished   | `{ agent, task, output }` |
| `agent.error`     | Agent failed     | `{ agent, error }`        |

### Tool Events

| Event         | Description   | Payload            |
| ------------- | ------------- | ------------------ |
| `tool.called` | Tool invoked  | `{ tool, input }`  |
| `tool.result` | Tool returned | `{ tool, output }` |
| `tool.error`  | Tool failed   | `{ tool, error }`  |

### Log Events

| Event | Description | Payload                         |
| ----- | ----------- | ------------------------------- |
| `log` | Log message | `{ level, message, timestamp }` |

### Artifact Events

| Event      | Description   | Payload                        |
| ---------- | ------------- | ------------------------------ |
| `artifact` | File produced | `{ name, size, content_type }` |

## Event Format

Each SSE event follows this format:

```
event: <event_type>
data: <json_payload>
id: <event_id>

```

Example:

```
event: agent.started
data: {"agent":"Researcher","task":"Research AI trends","timestamp":"2024-01-15T10:30:02Z"}
id: evt_001

event: tool.called
data: {"tool":"web_search","input":"AI agents 2024","timestamp":"2024-01-15T10:30:05Z"}
id: evt_002

event: log
data: {"level":"info","message":"Found 15 relevant results","timestamp":"2024-01-15T10:30:06Z"}
id: evt_003
```

## Reconnection

SSE supports automatic reconnection. Use the `Last-Event-ID` header:

```javascript theme={null}
let lastEventId = localStorage.getItem('lastEventId')

const eventSource = new EventSource(`https://api.crewship.dev/v1/runs/${runId}/events`, {
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Last-Event-ID': lastEventId || '',
  },
})

eventSource.onmessage = (event) => {
  localStorage.setItem('lastEventId', event.lastEventId)
  // Process event...
}
```

## Building a Live UI

Example React component:

```tsx theme={null}
function RunProgress({ runId }: { runId: string }) {
  const [events, setEvents] = useState<Event[]>([])
  const [status, setStatus] = useState<'running' | 'completed' | 'failed'>('running')

  useEffect(() => {
    const eventSource = new EventSource(`https://api.crewship.dev/v1/runs/${runId}/events`)

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data)
      setEvents((prev) => [...prev, data])

      if (data.type === 'run.completed') {
        setStatus('completed')
        eventSource.close()
      } else if (data.type === 'run.failed') {
        setStatus('failed')
        eventSource.close()
      }
    }

    return () => eventSource.close()
  }, [runId])

  return (
    <div>
      <StatusBadge status={status} />
      <EventList events={events} />
    </div>
  )
}
```

## Filtering Events

Request specific event types:

```bash theme={null}
curl -N \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.crewship.dev/v1/runs/run_abc123/events?types=agent.started,agent.completed,artifact"
```

## Related

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Trigger runs and receive notifications
  </Card>

  <Card title="Invoke Command" icon="terminal" href="/cli/invoke">
    CLI streaming options
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/runs/events">
    Events API docs
  </Card>
</CardGroup>
