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

# Get Stream Task Logs

> Stream task execution logs in real-time using Server-Sent Events (SSE). Perfect for live monitoring and building real-time dashboards.

This endpoint provides real-time streaming of task execution logs using Server-Sent Events (SSE). Instead of polling for updates, you receive logs as they're generated, making it ideal for live monitoring, debugging, and building real-time user interfaces.

## Authentication

**Required** - You need a BLACKBOX API Key to use this API.

Follow these steps to get your API key:

1. **Click on your Profile Image** in the top right corner at [cloud.blackbox.ai](https://cloud.blackbox.ai)
2. **Click on "BLACKBOX API Token"** from the dropdown menu
3. **Copy the existing token** or **click "Generate"** if you don't have one yet

Your API key will be in the format: `bb_xxxxxxxxxxxxxxxxxxxxxx`

## Headers

<ParamField header="Authorization" type="string" required>
  API Key of the form `Bearer <api_key>`.

  Example: `Bearer bb_b41b647ffbfed27f61656049d3eaeef3d903cc503345d9eb80080d98bc0`
</ParamField>

## Path Parameters

<ParamField path="taskId" type="string" required>
  The unique identifier of the task you want to stream logs for.

  Example: `9qQe2F8Z_nXx9-eJA0BD6`
</ParamField>

## Query Parameters

<ParamField query="fromIndex" type="integer" default="0">
  Start streaming from this log index. Useful for resuming after disconnection.

  Default: 0 (stream from beginning)

  Example: `fromIndex=50` (resume from log index 50)
</ParamField>

<ParamField query="includeStatus" type="boolean" default="true">
  Include periodic task status updates in the stream.

  Default: true

  Example: `includeStatus=false` (only stream logs, no status updates)
</ParamField>

## Event Types

The stream sends different event types to provide comprehensive real-time updates:

<ResponseField name="connected" type="event">
  Initial connection confirmation sent when stream starts.

  **Data Fields:**

  * `taskId` - Task identifier
  * `fromIndex` - Starting log index
  * `message` - Connection confirmation message
  * `timestamp` - ISO 8601 timestamp
</ResponseField>

<ResponseField name="log" type="event">
  Individual log entry from task execution.

  **Data Fields:**

  * `index` - Log position in array
  * `log` - Log entry object containing:
    * `type` - Log type (info, error, success, warning, system)
    * `contentType` - Content format (agentResponse, ansi, system, message, plain-text)
    * `message` - Log message content
    * `timestamp` - When log was created
    * `agent` - Agent that generated the log (claude, blackbox, codex, gemini)
    * `step` - Execution step identifier
  * `timestamp` - ISO 8601 timestamp when log was sent
</ResponseField>

<ResponseField name="status" type="event">
  Periodic task status update (sent every 2 seconds if `includeStatus=true`).

  **Data Fields:**

  * `status` - Current task status (pending, processing, saving, completed, error, stopped, timeout)
  * `error` - Error message if task failed (null otherwise)
</ResponseField>

<ResponseField name="complete" type="event">
  Stream completion notification sent when task finishes.

  **Data Fields:**

  * `status` - Final task status
  * `totalLogs` - Total number of logs sent
  * `message` - Completion message
  * `timestamp` - ISO 8601 timestamp
</ResponseField>

<ResponseField name="error" type="event">
  Error notification if something goes wrong during streaming.

  **Data Fields:**

  * `error` - Error message
  * `details` - Additional error details (optional)
</ResponseField>

## Response Format

The endpoint returns a Server-Sent Events (SSE) stream with `Content-Type: text/event-stream`. Each event follows this format:

```
event: <event_type>
data: <json_data>

```

## Security & Access Control

The streaming endpoint implements comprehensive security measures:

* ✅ **Authentication Required** - Valid API key or session required
* ✅ **Access Control** - Users can only stream logs for:
  * Their own tasks
  * Tasks from teams they're members of
  * Public tasks
* ✅ **No Sensitive Data** - Only logs and status are streamed (no API keys, tokens, user IDs, or credentials)
* ✅ **Automatic Cleanup** - Stream closes automatically when task completes or client disconnects

<RequestExample>
  ```bash cURL theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  curl -N 'https://cloud.blackbox.ai/api/tasks/9qQe2F8Z_nXx9-eJA0BD6/stream?fromIndex=0&includeStatus=true' \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Accept: text/event-stream'
  ```

  ```javascript Node.js (EventSource) theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  // Using eventsource package: npm install eventsource
  const EventSource = require('eventsource');

  const API_KEY = "YOUR_API_KEY";
  const TASK_ID = "9qQe2F8Z_nXx9-eJA0BD6";
  const API_URL = `https://cloud.blackbox.ai/api/tasks/${TASK_ID}/stream?fromIndex=0&includeStatus=true`;

  const eventSource = new EventSource(API_URL, {
    headers: {
      'Authorization': `Bearer ${API_KEY}`
    }
  });

  // Handle connection
  eventSource.addEventListener('connected', (event) => {
    const data = JSON.parse(event.data);
    console.log('Connected:', data.message);
  });

  // Handle log entries
  eventSource.addEventListener('log', (event) => {
    const data = JSON.parse(event.data);
    console.log(`[Log ${data.index}]:`, data.log.message);
  });

  // Handle status updates
  eventSource.addEventListener('status', (event) => {
    const data = JSON.parse(event.data);
    console.log('Status:', data.status);
    if (data.error) {
      console.error('Error:', data.error);
    }
  });

  // Handle completion
  eventSource.addEventListener('complete', (event) => {
    const data = JSON.parse(event.data);
    console.log(`Task ${data.status}! Total logs: ${data.totalLogs}`);
    eventSource.close();
  });

  // Handle errors
  eventSource.addEventListener('error', (event) => {
    if (event.data) {
      const data = JSON.parse(event.data);
      console.error('Stream error:', data.error);
    }
    eventSource.close();
  });

  // Handle connection errors
  eventSource.onerror = (error) => {
    console.error('Connection error:', error);
    eventSource.close();
  };
  ```

  ```javascript Browser (Native EventSource) theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  const API_KEY = "YOUR_API_KEY";
  const TASK_ID = "9qQe2F8Z_nXx9-eJA0BD6";
  const API_URL = `https://cloud.blackbox.ai/api/tasks/${TASK_ID}/stream?fromIndex=0&includeStatus=true`;

  // Note: Browser EventSource doesn't support custom headers
  // You'll need to use a polyfill or pass API key as query parameter
  const eventSource = new EventSource(API_URL);

  eventSource.addEventListener('connected', (event) => {
    const data = JSON.parse(event.data);
    console.log('Connected:', data.message);
  });

  eventSource.addEventListener('log', (event) => {
    const data = JSON.parse(event.data);
    const logElement = document.createElement('div');
    logElement.textContent = `[${data.index}] ${data.log.message}`;
    document.getElementById('logs').appendChild(logElement);
  });

  eventSource.addEventListener('status', (event) => {
    const data = JSON.parse(event.data);
    document.getElementById('status').textContent = data.status;
  });

  eventSource.addEventListener('complete', (event) => {
    const data = JSON.parse(event.data);
    console.log('Task completed!', data);
    eventSource.close();
  });

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

  ```python Python theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  import requests
  import json

  API_KEY = "YOUR_API_KEY"
  TASK_ID = "9qQe2F8Z_nXx9-eJA0BD6"
  API_URL = f"https://cloud.blackbox.ai/api/tasks/{TASK_ID}/stream"

  headers = {
      "Authorization": f"Bearer {API_KEY}",
      "Accept": "text/event-stream"
  }

  params = {
      "fromIndex": 0,
      "includeStatus": "true"
  }

  # Stream with requests
  response = requests.get(API_URL, headers=headers, params=params, stream=True)

  if response.status_code == 200:
      for line in response.iter_lines():
          if line:
              decoded_line = line.decode('utf-8')
              
              # Parse SSE format
              if decoded_line.startswith('event:'):
                  event_type = decoded_line.split(':', 1)[1].strip()
              elif decoded_line.startswith('data:'):
                  data = json.loads(decoded_line.split(':', 1)[1].strip())
                  
                  if event_type == 'connected':
                      print(f"Connected: {data['message']}")
                  elif event_type == 'log':
                      print(f"[Log {data['index']}]: {data['log']['message']}")
                  elif event_type == 'status':
                      print(f"Status: {data['status']}")
                  elif event_type == 'complete':
                      print(f"Task {data['status']}! Total logs: {data['totalLogs']}")
                      break
                  elif event_type == 'error':
                      print(f"Error: {data['error']}")
                      break
  else:
      print(f"Error: {response.status_code}")
      print(response.text)
  ```

  ```go Go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  package main

  import (
      "bufio"
      "encoding/json"
      "fmt"
      "net/http"
      "strings"
  )

  func main() {
      apiKey := "YOUR_API_KEY"
      taskId := "9qQe2F8Z_nXx9-eJA0BD6"
      url := fmt.Sprintf("https://cloud.blackbox.ai/api/tasks/%s/stream?fromIndex=0&includeStatus=true", taskId)

      req, _ := http.NewRequest("GET", url, nil)
      req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", apiKey))
      req.Header.Add("Accept", "text/event-stream")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      if resp.StatusCode != 200 {
          fmt.Printf("Error: %d\n", resp.StatusCode)
          return
      }

      scanner := bufio.NewScanner(resp.Body)
      var eventType string

      for scanner.Scan() {
          line := scanner.Text()

          if strings.HasPrefix(line, "event:") {
              eventType = strings.TrimSpace(strings.TrimPrefix(line, "event:"))
          } else if strings.HasPrefix(line, "data:") {
              dataStr := strings.TrimSpace(strings.TrimPrefix(line, "data:"))
              
              switch eventType {
              case "connected":
                  var data map[string]interface{}
                  json.Unmarshal([]byte(dataStr), &data)
                  fmt.Printf("Connected: %s\n", data["message"])
                  
              case "log":
                  var data map[string]interface{}
                  json.Unmarshal([]byte(dataStr), &data)
                  log := data["log"].(map[string]interface{})
                  fmt.Printf("[Log %.0f]: %s\n", data["index"], log["message"])
                  
              case "status":
                  var data map[string]interface{}
                  json.Unmarshal([]byte(dataStr), &data)
                  fmt.Printf("Status: %s\n", data["status"])
                  
              case "complete":
                  var data map[string]interface{}
                  json.Unmarshal([]byte(dataStr), &data)
                  fmt.Printf("Task %s! Total logs: %.0f\n", data["status"], data["totalLogs"])
                  return
                  
              case "error":
                  var data map[string]interface{}
                  json.Unmarshal([]byte(dataStr), &data)
                  fmt.Printf("Error: %s\n", data["error"])
                  return
              }
          }
      }
  }
  ```
</RequestExample>

<ResponseExample>
  ```text SSE Stream Example theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  event: connected
  data: {"taskId":"9qQe2F8Z_nXx9-eJA0BD6","fromIndex":0,"message":"Connected to log stream","timestamp":"2024-01-15T10:00:00.000Z"}

  event: log
  data: {"index":0,"log":{"type":"system","contentType":"system","message":"Cloning repository...","timestamp":"2024-01-15T10:00:01.000Z","agent":"claude","step":"git_cloning"},"timestamp":"2024-01-15T10:00:01.123Z"}

  event: log
  data: {"index":1,"log":{"type":"info","contentType":"ansi","message":"Repository cloned successfully","timestamp":"2024-01-15T10:00:05.000Z","agent":"claude","step":"git_cloned"},"timestamp":"2024-01-15T10:00:05.456Z"}

  event: status
  data: {"status":"processing","error":null}

  event: log
  data: {"index":2,"log":{"type":"info","contentType":"agentResponse","message":"**Analyzing codebase...**\n\nI'll examine the authentication module to understand the current implementation.","timestamp":"2024-01-15T10:00:10.000Z","agent":"claude","step":"agent_executing"},"timestamp":"2024-01-15T10:00:10.789Z"}

  event: log
  data: {"index":3,"log":{"type":"success","contentType":"system","message":"Analysis complete","timestamp":"2024-01-15T10:00:30.000Z","agent":"claude","step":"agent_executing"},"timestamp":"2024-01-15T10:00:30.123Z"}

  event: status
  data: {"status":"saving","error":null}

  event: log
  data: {"index":4,"log":{"type":"success","contentType":"system","message":"Changes committed successfully","timestamp":"2024-01-15T10:01:00.000Z","agent":"claude","step":"git_committed"},"timestamp":"2024-01-15T10:01:00.456Z"}

  event: complete
  data: {"status":"completed","totalLogs":5,"message":"Task completed","timestamp":"2024-01-15T10:01:05.000Z"}
  ```

  ```json Error Response - Unauthorized theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  HTTP/1.1 401 Unauthorized
  Content-Type: application/json

  {
    "error": "Unauthorized. Please provide valid credentials."
  }
  ```

  ```json Error Response - Task Not Found theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  HTTP/1.1 404 Not Found
  Content-Type: application/json

  {
    "error": "Task not found"
  }
  ```
</ResponseExample>

## Use Cases

### Real-Time Log Viewer

Build a live log viewer that displays logs as they arrive:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
function createLogViewer(taskId, apiKey) {
  const API_URL = `https://cloud.blackbox.ai/api/tasks/${taskId}/stream`;
  const eventSource = new EventSource(API_URL, {
    headers: { 'Authorization': `Bearer ${apiKey}` }
  });

  const logContainer = document.getElementById('logs');
  const statusElement = document.getElementById('status');

  eventSource.addEventListener('log', (event) => {
    const { index, log } = JSON.parse(event.data);
    
    const logElement = document.createElement('div');
    logElement.className = `log-entry log-${log.type}`;
    logElement.innerHTML = `
      <span class="log-index">[${index}]</span>
      <span class="log-timestamp">${new Date(log.timestamp).toLocaleTimeString()}</span>
      <span class="log-message">${log.message}</span>
    `;
    
    logContainer.appendChild(logElement);
    logContainer.scrollTop = logContainer.scrollHeight; // Auto-scroll
  });

  eventSource.addEventListener('status', (event) => {
    const { status } = JSON.parse(event.data);
    statusElement.textContent = status.toUpperCase();
    statusElement.className = `status status-${status}`;
  });

  eventSource.addEventListener('complete', (event) => {
    const { status, totalLogs } = JSON.parse(event.data);
    console.log(`Task ${status}! Received ${totalLogs} logs`);
    eventSource.close();
  });

  return eventSource;
}
```

### Resume After Disconnection

Handle reconnection and resume from last received log:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
class TaskLogStreamer {
  constructor(taskId, apiKey) {
    this.taskId = taskId;
    this.apiKey = apiKey;
    this.lastLogIndex = -1;
    this.eventSource = null;
  }

  connect() {
    const fromIndex = this.lastLogIndex + 1;
    const url = `https://cloud.blackbox.ai/api/tasks/${this.taskId}/stream?fromIndex=${fromIndex}`;
    
    this.eventSource = new EventSource(url, {
      headers: { 'Authorization': `Bearer ${this.apiKey}` }
    });

    this.eventSource.addEventListener('log', (event) => {
      const { index, log } = JSON.parse(event.data);
      this.lastLogIndex = index;
      this.onLog(log, index);
    });

    this.eventSource.addEventListener('complete', (event) => {
      this.onComplete(JSON.parse(event.data));
      this.disconnect();
    });

    this.eventSource.onerror = (error) => {
      console.error('Connection lost, reconnecting...');
      this.disconnect();
      setTimeout(() => this.connect(), 2000); // Reconnect after 2s
    };
  }

  disconnect() {
    if (this.eventSource) {
      this.eventSource.close();
      this.eventSource = null;
    }
  }

  onLog(log, index) {
    console.log(`[${index}]`, log.message);
  }

  onComplete(data) {
    console.log('Stream complete:', data);
  }
}

// Usage
const streamer = new TaskLogStreamer('9qQe2F8Z_nXx9-eJA0BD6', 'YOUR_API_KEY');
streamer.connect();
```

## Error Codes

| Status Code | Error                 | Description                                 |
| ----------- | --------------------- | ------------------------------------------- |
| 200         | Success               | Stream established successfully             |
| 401         | Unauthorized          | Invalid or missing API key                  |
| 404         | Not Found             | Task not found or user does not have access |
| 500         | Internal Server Error | Failed to start log stream                  |
