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

# Stream Events

> Unified SSE stream for history replay and live task events

# Stream Task Events

Connect to the unified SSE stream to receive the complete conversation history followed by live execution events. This is the recommended way to build a real-time chat UI.

## Request

```bash theme={null}
GET /api/v1/tasks/{id}/stream
Authorization: Bearer {api_key}
```

### Path Parameters

| Parameter | Type   | Description                |
| --------- | ------ | -------------------------- |
| `id`      | string | The unique task identifier |

## Stream Behavior

The stream delivers events in three phases:

1. **History replay** - Emits `history_message` events for each saved conversation message
2. **History complete** - Emits `history_done` with `{ messageCount, isStreaming }`
3. **Live events** (if task is running) - Catch-up state followed by real-time `content`, `thought`, `tool_call`, `tool_result`, `subagent_start`, `subagent_thought`, `subagent_tool`, `subagent_end`, `error`, and `done` events

If the task is not currently running, the stream ends after `history_done`.

## Reconnection

You can disconnect and reconnect at any time. On reconnect, the stream replays the full history and catches up to the current state. **The task continues executing in the background regardless of stream connections** - disconnecting does not cancel the task.

## Heartbeat

The server sends `:heartbeat` comments every 15 seconds to keep the connection alive. These can be safely ignored by your SSE parser.

## Stream Output Example

```
event: history_message
data: {"id":"msg-1","role":"user","content":"Analyze this CSV file","createdAt":"2026-01-26T15:50:54.870Z","attachedFiles":[{"name":"data.csv","path":"uploads/data.csv"}]}

event: history_message
data: {"id":"msg-2","role":"assistant","content":"I analyzed the CSV file...","createdAt":"2026-01-26T15:50:59.998Z","thoughts":[{"subject":"Analyzing","description":"Reading CSV structure"}],"toolCalls":[{"callId":"tc-1","toolName":"read_file","status":"success"}]}

event: history_done
data: {"messageCount":2,"isStreaming":true}

event: content
data: {"text":"Now let me provide additional analysis...","isPartial":true}

event: tool_call
data: {"callId":"call_456","toolName":"write_file","status":"executing","args":{"path":"output.csv"}}

event: tool_result
data: {"callId":"call_456","status":"success","output":"File written successfully"}

event: subagent_start
data: {"agentName":"code-writer","displayName":"Code Writer","description":"Writes and edits code files","objective":"Create summary chart"}

event: subagent_thought
data: {"agentName":"code-writer","text":"I'll generate a chart from the analyzed data"}

event: subagent_tool
data: {"agentName":"code-writer","status":"end","toolName":"write_file","output":"Chart saved"}

event: subagent_end
data: {"agentName":"code-writer","terminateReason":"GOAL","result":"Created summary chart"}

event: content
data: {"text":"I've created the output file.","isPartial":false}

event: done
data: {"finalResponse":"I've created the output file with the analysis results."}
```

## Event Types

### `history_message`

A replayed conversation message from history.

```json theme={null}
{
  "id": "msg-1",
  "role": "user",
  "content": "Analyze this CSV file",
  "createdAt": "2026-01-26T15:50:54.870Z",
  "attachedFiles": [
    { "name": "data.csv", "path": "uploads/data.csv" }
  ]
}
```

| Field           | Type   | Description                               |
| --------------- | ------ | ----------------------------------------- |
| `id`            | string | Message identifier                        |
| `role`          | string | `user` or `assistant`                     |
| `content`       | string | Message text                              |
| `createdAt`     | string | ISO timestamp                             |
| `attachedFiles` | array  | Uploaded files (user messages only)       |
| `thoughts`      | array  | Agent reasoning (assistant messages only) |
| `toolCalls`     | array  | Tool executions (assistant messages only) |

### `history_done`

Signals that history replay is complete.

```json theme={null}
{
  "messageCount": 2,
  "isStreaming": true
}
```

| Field          | Type    | Description                                                          |
| -------------- | ------- | -------------------------------------------------------------------- |
| `messageCount` | number  | Number of history messages sent                                      |
| `isStreaming`  | boolean | Whether the task is currently running (live events follow if `true`) |

### Live Events

After `history_done`, if `isStreaming` is `true`, the stream delivers live events including `content`, `thought`, `tool_call`, `tool_result`, subagent events (`subagent_start`, `subagent_thought`, `subagent_tool`, `subagent_end`), `error`, and `done`. See [Streaming Events](/streaming) for the complete event format reference.

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  # Stream events (Ctrl+C to disconnect - task keeps running)
  curl -N https://api.sigmic.ai/api/v1/tasks/YOUR_TASK_ID/stream \
    -H "Authorization: Bearer sigmic_your_key_here"
  ```

  ```javascript JavaScript theme={null}
  const taskId = 'c37c1d78-4d23-4e53-949a-ddd775f25e01';

  const response = await fetch(
    `https://api.sigmic.ai/api/v1/tasks/${taskId}/stream`,
    { headers: { 'Authorization': 'Bearer sigmic_your_key_here' } }
  );

  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 events = buffer.split('\n\n');
    buffer = events.pop() || '';

    for (const event of events) {
      if (!event.trim() || event.startsWith(':')) continue;

      const lines = event.split('\n');
      const eventType = lines[0]?.replace('event: ', '');
      const dataLine = lines[1]?.replace('data: ', '');
      if (!dataLine) continue;

      const data = JSON.parse(dataLine);

      switch (eventType) {
        case 'history_message':
          console.log(`[${data.role}] ${data.content}`);
          break;
        case 'history_done':
          console.log(`History loaded: ${data.messageCount} messages`);
          if (!data.isStreaming) console.log('Task is not running');
          break;
        case 'content':
          process.stdout.write(data.text);
          break;
        case 'done':
          console.log('\nDone:', data.finalResponse);
          break;
      }
    }
  }
  ```

  ```python Python theme={null}
  import json
  import requests

  task_id = 'c37c1d78-4d23-4e53-949a-ddd775f25e01'

  response = requests.get(
      f'https://api.sigmic.ai/api/v1/tasks/{task_id}/stream',
      headers={'Authorization': 'Bearer sigmic_your_key_here'},
      stream=True
  )

  event_type = None
  for line in response.iter_lines():
      if not line:
          continue

      line = line.decode('utf-8')
      if line.startswith('event:'):
          event_type = line.replace('event: ', '')
      elif line.startswith('data:'):
          data = json.loads(line.replace('data: ', ''))

          if event_type == 'history_message':
              print(f"[{data['role']}] {data['content'][:80]}...")
          elif event_type == 'history_done':
              print(f"History: {data['messageCount']} messages, streaming: {data['isStreaming']}")
          elif event_type == 'content':
              print(data.get('text', ''), end='', flush=True)
          elif event_type == 'done':
              print(f"\nDone: {data.get('finalResponse', '')}")
  ```
</CodeGroup>

## Use Cases

### Building a Chat UI

Use the stream endpoint to hydrate your chat interface and receive live updates:

```javascript theme={null}
async function connectToTask(taskId) {
  const messages = [];

  const response = await fetch(`${API_BASE}/api/v1/tasks/${taskId}/stream`, {
    headers: { 'Authorization': `Bearer ${apiKey}` }
  });

  // Parse SSE events...
  // history_message events → populate chat history
  // history_done → render the chat UI
  // content events → update current assistant message in real-time
  // done event → finalize the message
}
```

### Reconnecting After Disconnect

```javascript theme={null}
// User switches tabs, connection drops
// When they come back, just reconnect:
async function reconnect(taskId) {
  // Same endpoint - replays full history + catches up
  return connectToTask(taskId);
}
```

<Note>
  The stream endpoint is the recommended way to consume task events. It replaces the previous pattern of reading SSE from POST endpoints. Use `GET /tasks/:id/history` as a REST alternative when SSE is not practical.
</Note>

## Errors

| Code              | Description                              |
| ----------------- | ---------------------------------------- |
| `AUTH_REQUIRED`   | No authentication provided               |
| `INVALID_API_KEY` | Invalid or expired API key               |
| `NOT_FOUND`       | Task with the specified ID was not found |
