Stream Task Logs
https://agent.blackbox.ai/api/v1/tasks/{runId}/logs/streamStream task execution logs in real-time using Server-Sent Events (SSE). Live runs stream from the in-memory buffer; completed runs replay from persisted message parts.
This endpoint provides a real-time SSE stream of task execution events. For live tasks it subscribes to the in-memory event buffer and pushes events as they arrive. For completed tasks it replays all persisted events in a single burst and closes the stream.
The event type values are the same regardless of agent runtime — Claude and Codex tasks emit an identical contract (session-init, text-delta, tool-call-start, tool-input-available, tool-output-available, result, …). See the full event table.
Authentication
To use this API, you need a BLACKBOX API Key. Follow these steps to get your API key:
- Go to app.blackbox.ai/agent-api and click Get an API Key (requires a Pro subscription)
- Once provisioning completes, you will be redirected to your Dashboard
- From the Dashboard, create an API key to use with all Agent API requests
Your API key will be in the format: sk-xxxxxxxxxxxxxxxxxxxxxx
Headers
AuthorizationstringrequiredAPI Key of the form Bearer <api_key>.
Example: Bearer sk_b41b647ffbfed27f616560
Path Parameters
runIdstringrequiredThe unique run identifier returned when the task was created.
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Query Parameters
includeDeltasbooleandefault: trueWhether to include text-delta events (individual text chunks). Set to false for a cleaner stream with only structural events.
Default: true
Response Format
The endpoint returns Content-Type: text/event-stream. Each event is a JSON object on a data: line:
data: {"type":"text-start","id":"msg_abc123"}
data: {"type":"text-delta","id":"msg_abc123","delta":"Hello, "}
data: {"type":"finish","runId":"...","status":"completed"}Event Types
text-starteventBeginning of a new text block from the agent.
Fields: id — message identifier
text-deltaeventIncremental text chunk from the agent.
Fields: id, delta — text chunk string
tool-call-starteventAgent started a tool call.
Fields: toolCallId, toolName
tool-input-availableeventTool call input is ready.
Fields: toolCallId, toolName, input — tool input object
tool-output-availableeventTool call result is available.
Fields: toolCallId, toolName, output — tool output object
task-fileseventFiles produced by the task.
Fields: files — array of file objects
finisheventTask completed (stream closes after this).
Fields: runId, status
erroreventTask failed (stream closes after this).
Fields: errorText
curl -N 'https://agent.blackbox.ai/api/v1/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logs/stream' \
-H 'Authorization: Bearer YOUR_API_KEY'const API_KEY = "YOUR_API_KEY";
const RUN_ID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
const response = await fetch(
`https://agent.blackbox.ai/api/v1/tasks/${RUN_ID}/logs/stream`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
for (const line of chunk.split("\n")) {
if (line.startsWith("data: ")) {
const event = JSON.parse(line.slice(6));
console.log(event.type, event);
if (event.type === "finish" || event.type === "error") break;
}
}
}// Note: Browser EventSource doesn't support custom headers.
// Pass the API key as a query param or use a server-side proxy.
const RUN_ID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
const url = `https://agent.blackbox.ai/api/v1/tasks/${RUN_ID}/logs/stream`;
const es = new EventSource(url);
es.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === "text-delta") {
process.stdout.write(data.delta);
} else if (data.type === "finish") {
console.log("\nDone:", data.status);
es.close();
} else if (data.type === "error") {
console.error("Error:", data.errorText);
es.close();
}
};
es.onerror = () => es.close();import requests
import json
API_KEY = "YOUR_API_KEY"
RUN_ID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
response = requests.get(
f"https://agent.blackbox.ai/api/v1/tasks/{RUN_ID}/logs/stream",
headers={"Authorization": f"Bearer {API_KEY}"},
stream=True,
)
for line in response.iter_lines():
if line and line.startswith(b"data: "):
event = json.loads(line[6:])
print(event["type"], event)
if event["type"] in ("finish", "error"):
breakpackage main
import (
"bufio"
"encoding/json"
"fmt"
"net/http"
"strings"
)
func main() {
apiKey := "YOUR_API_KEY"
runId := "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
url := fmt.Sprintf("https://agent.blackbox.ai/api/v1/tasks/%s/logs/stream", runId)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "data: ") {
var event map[string]interface{}
json.Unmarshal([]byte(line[6:]), &event)
fmt.Println(event["type"], event)
if event["type"] == "finish" || event["type"] == "error" {
break
}
}
}
}data: {"type":"text-start","id":"msg_abc123"}
data: {"type":"text-delta","id":"msg_abc123","delta":"I'll start by cloning the repository..."}
data: {"type":"tool-call-start","toolCallId":"tc_001","toolName":"bash"}
data: {"type":"tool-input-available","toolCallId":"tc_001","toolName":"bash","input":{"command":"git clone https://github.com/org/repo.git /vercel/sandbox"}}
data: {"type":"tool-output-available","toolCallId":"tc_001","toolName":"bash","output":{"stdout":"Cloning into '/vercel/sandbox'...\ndone.","exitCode":0}}
data: {"type":"text-delta","id":"msg_abc123","delta":"Repository cloned successfully. Now adding the README..."}
data: {"type":"finish","runId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","status":"completed"}{
"status": "queued",
"error": null,
"message": "No logs available to stream. Task may not have started or logs were cleared."
}{
"error": "Unauthorized"
}Error Codes
| Status Code | Error | Description |
|---|---|---|
| 200 | Success | SSE stream established |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Task belongs to a different user |
| 404 | Not Found | Task not found |
| 409 | Conflict | No logs available to stream |
| 500 | Internal Server Error | Failed to start stream |