Agent SSE Stream
https://agent.blackbox.ai/api/v1/agent/streamSubscribe to the raw SSE event stream for a specific agent run by runId. Replays buffered events and streams new ones in real-time.
This endpoint provides the raw SSE stream for a specific agent run. It replays all buffered events from the start of the run and then streams new events as they arrive. The stream closes automatically when the run finishes or the client disconnects.
Events are emitted with the same type contract for both agent runtimes (Claude and Codex). 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
Query Parameters
runIdstringrequiredThe unique run identifier returned when the task was created.
Example: runId=a1b2c3d4-e5f6-7890-abcd-ef1234567890
Response Format
Returns Content-Type: text/event-stream. Each event is a JSON object on a data: line:
data: {"type":"resume","runId":"..."}
data: {"type":"start","runId":"...","startedAt":"..."}
data: {"type":"text-delta","id":"...","delta":"Hello"}
data: {"type":"finish","runId":"...","status":"completed"}Event Types
resumeeventSent immediately on connection. Confirms the stream is live.
Fields: type, runId
starteventSent when the agent run begins executing.
Fields: type, runId, startedAt
text-starteventBeginning of a new text block.
Fields: type, id
text-deltaeventIncremental text chunk from the agent.
Fields: type, id, delta
tool-call-starteventAgent started a tool call.
Fields: type, toolCallId, toolName
tool-input-availableeventTool call input is ready.
Fields: type, toolCallId, toolName, input
tool-output-availableeventTool call result is available.
Fields: type, toolCallId, toolName, output
task-fileseventFiles produced by the task.
Fields: type, files
finisheventRun completed. Stream closes after this event.
Fields: type, runId, status
erroreventRun failed. Stream closes after this event.
Fields: type, errorText
curl -N 'https://agent.blackbox.ai/api/v1/agent/stream?runId=a1b2c3d4-e5f6-7890-abcd-ef1234567890' \
-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/agent/stream?runId=${RUN_ID}`,
{ headers: { Authorization: `Bearer ${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: ")) continue;
const event = JSON.parse(line.slice(6));
switch (event.type) {
case "resume":
console.log("Connected to stream");
break;
case "text-delta":
process.stdout.write(event.delta);
break;
case "tool-call-start":
console.log(`\nTool: ${event.toolName}`);
break;
case "finish":
console.log(`\nDone: ${event.status}`);
return;
case "error":
console.error(`Error: ${event.errorText}`);
return;
}
}
}import requests
import json
API_KEY = "YOUR_API_KEY"
RUN_ID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
response = requests.get(
"https://agent.blackbox.ai/api/v1/agent/stream",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"runId": RUN_ID},
stream=True,
)
for line in response.iter_lines():
if not line or not line.startswith(b"data: "):
continue
event = json.loads(line[6:])
if event["type"] == "text-delta":
print(event["delta"], end="", flush=True)
elif event["type"] == "tool-call-start":
print(f"\n[Tool: {event['toolName']}]")
elif event["type"] in ("finish", "error"):
print(f"\nStream ended: {event}")
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/agent/stream?runId=%s", 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: ") {
continue
}
var event map[string]interface{}
json.Unmarshal([]byte(line[6:]), &event)
switch event["type"] {
case "text-delta":
fmt.Print(event["delta"])
case "finish":
fmt.Printf("\nDone: %s\n", event["status"])
return
case "error":
fmt.Printf("\nError: %s\n", event["errorText"])
return
}
}
}data: {"type":"resume","runId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"}
data: {"type":"start","runId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","startedAt":"2026-05-19T10:00:02.000Z"}
data: {"type":"text-start","id":"msg_abc123"}
data: {"type":"text-delta","id":"msg_abc123","delta":"I'll start by examining the repository structure..."}
data: {"type":"tool-call-start","toolCallId":"tc_001","toolName":"bash"}
data: {"type":"tool-input-available","toolCallId":"tc_001","toolName":"bash","input":{"command":"ls /vercel/sandbox"}}
data: {"type":"tool-output-available","toolCallId":"tc_001","toolName":"bash","output":{"stdout":"src\npackage.json\nREADME.md","exitCode":0}}
data: {"type":"text-delta","id":"msg_abc123","delta":"The repository has a standard Node.js structure. Creating the French README now..."}
data: {"type":"finish","runId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","status":"completed"}{
"status": "not_found",
"error": null
}{
"error": "runId query parameter is required"
}Error Codes
| Status Code | Error | Description |
|---|---|---|
| 200 | Success | SSE stream established |
| 400 | Bad Request | Missing runId query parameter |
| 401 | Unauthorized | Invalid or missing API key |
| 409 | Conflict | Run is not in a streamable state (not found or no buffer) |