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}")
break
package 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"
}
Logs & Streaming
Agent SSE Stream
Subscribe to the raw SSE event stream for a specific agent run by runId. Replays buffered events and streams new ones in real-time.
GET
/
api
/
v1
/
agent
/
stream
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}")
break
package 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"
}
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
sk-xxxxxxxxxxxxxxxxxxxxxx
Headers
string
required
API Key of the form
Bearer <api_key>.Example: Bearer sk_b41b647ffbfed27f616560Query Parameters
string
required
The unique run identifier returned when the task was created.Example:
runId=a1b2c3d4-e5f6-7890-abcd-ef1234567890Response Format
ReturnsContent-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
event
Sent immediately on connection. Confirms the stream is live.Fields:
type, runIdevent
Sent when the agent run begins executing.Fields:
type, runId, startedAtevent
Beginning of a new text block.Fields:
type, idevent
Incremental text chunk from the agent.Fields:
type, id, deltaevent
Agent started a tool call.Fields:
type, toolCallId, toolNameevent
Tool call input is ready.Fields:
type, toolCallId, toolName, inputevent
Tool call result is available.Fields:
type, toolCallId, toolName, outputevent
Files produced by the task.Fields:
type, filesevent
Run completed. Stream closes after this event.Fields:
type, runId, statusevent
Run failed. Stream closes after this event.Fields:
type, errorTextcurl -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}")
break
package 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) |