Skip to main content
Subscribe to a real-time stream of task execution events. The frontend uses this to show live tool calls, phase changes, and completion — zero polling required.

Endpoint

GET /tasks/events
This is an SSE (Server-Sent Events) endpoint. Connect with EventSource:
const es = new EventSource("http://localhost:3001/tasks/events");

es.addEventListener("task:start", (e) => {
  const data = JSON.parse(e.data);
  console.log(`Run #${data.runNumber} started for task ${data.taskId}`);
});

es.addEventListener("task:tool", (e) => {
  const data = JSON.parse(e.data);
  console.log(`Tool: ${data.tool}`, data.output);
});

es.addEventListener("task:complete", (e) => {
  const data = JSON.parse(e.data);
  console.log(`Run completed: ${data.status} (${data.durationMs}ms)`);
});

Event types

task:start

Emitted when a task run begins.
{
  "type": "task:start",
  "taskId": "abc123",
  "runId": "run-456",
  "runNumber": 3,
  "startedAt": 1709556000000,
  "phases": [
    { "id": "research", "description": "Research phase", "status": "pending" },
    { "id": "write", "description": "Write output", "status": "pending" }
  ]
}

task:tool

Emitted when a tool call finishes during execution.
{
  "type": "task:tool",
  "taskId": "abc123",
  "runId": "run-456",
  "tool": "webSearch",
  "input": { "query": "latest AI news March 2026" },
  "output": { "results": [...] },
  "status": "complete"
}

task:phase

Emitted when a phase changes status.
{
  "type": "task:phase",
  "taskId": "abc123",
  "phase": "Research phase",
  "status": "completed"
}

task:complete

Emitted when a run finishes successfully.
{
  "type": "task:complete",
  "taskId": "abc123",
  "runId": "run-456",
  "runNumber": 3,
  "status": "completed",
  "output": "## AI News Summary\n\n...",
  "durationMs": 45200,
  "toolCount": 7,
  "qualityScore": 0.85
}

task:error

Emitted when a run fails.
{
  "type": "task:error",
  "taskId": "abc123",
  "runId": "run-456",
  "error": "Rate limit exceeded from search provider"
}

task:steer

Emitted when a steering comment is posted.
{
  "type": "task:steer",
  "taskId": "abc123",
  "comment": "Focus more on open-source models"
}

Connection handling

  • The SSE connection stays open indefinitely
  • If the connection drops, reconnect with a new EventSource — events are not replayed
  • Events stream for all tasks, not a specific one. Filter by taskId on the client side
For initial load, use GET /tasks and GET /tasks/:id/runs to fetch existing data. The SSE stream handles everything after that — no polling needed.