Running Tasks
A task is one run of an agent against a goal. Use a runtime key (scoped to a single agent) to create and track tasks.
App API alternative
This guide uses the versioned Workspace SDK (POST /v1/chat/tasks), the recommended surface for integrations. The web app also exposes POST /api/chat/task/create (JWT auth, a broader/less stable contract) — see the Chat / Tasks API.
Create a Task
Send the agent id and the first user message. The server validates that the request's agent_id matches the agent bound to your runtime key, and that message.content is non-empty.
Request:
POST /v1/chat/tasks
{
"agent_id": 42,
"message": { "role": "user", "content": "Summarize the EV battery market." },
"metadata": { "request_id": "req_0c1d", "source": "sdk" },
"timezone": "Australia/Melbourne"
}timezone is optional — an IANA timezone name (up to 64 characters) for the caller's local clock, used to render the date the agent reasons from for this first turn. Omit it to keep UTC; a name the server cannot resolve degrades to UTC rather than failing the request.
Response (202 Accepted):
{
"task_id": 101,
"agent_id": 42,
"status": "running",
"created_at": "2026-06-23T12:00:00Z",
"run_id": "run_9f2c1a",
"state_version": 1,
"control_state": "running"
}The task is created and queued for background execution. task_id is an integer; poll the endpoints below to watch it move from running to completed or failed.
Track Progress
Fetch task details and the step-by-step plan as the agent works:
GET /v1/chat/tasks/{task_id} # task info & status
GET /v1/chat/tasks/{task_id}/steps # planned/executed stepsA task moves through its lifecycle from running to a terminal state (completed or failed). Steps reflect the Plan → Execute → Reflect loop.
Live Streaming (Server-Sent Events)
Instead of polling, subscribe to a task's own event stream to receive updates as they happen:
GET /v1/chat/tasks/{task_id}/events # text/event-streamThe stream carries these event types:
| Event | Payload | Meaning |
|---|---|---|
task.status | { status } | The task's lifecycle status changed. |
step.started | { step } | A new step began running. step has the same shape as an entry from GET /v1/chat/tasks/{task_id}/steps. |
step.completed | { step } | A step finished, with step.status of completed or failed. |
message.delta | { message_id, text } | An incremental chunk of the assistant's answer. |
message.completed | { message_id, content } | The assistant message is complete. content is the final text and may be truncated independently of the deltas that built up to it. |
task.completed | { status, output, error } | Terminal event — the task finished. |
task.input_required | { task_id, prompt } | The task is waiting on you. prompt carries the pending question when one is available. |
stream.error | { code, message } | Terminal — the stream itself failed; reconnect and fall back to polling if it recurs. |
Known limitations
The stream only carries events from the moment you connect forward — there is no replay of steps that ran before you opened the connection, so a client that connects late should also call GET /v1/chat/tasks/{task_id}/steps to backfill what it missed. A message-type step can appear twice: once via its own message.delta/message.completed pair, and again as a step.completed event from the underlying execution trace — this duplication is intentional, not a bug. Large field values are capped (64 KiB per field) and marked truncated: true when cut.
Retrieve Output & Files
When a task finishes, collect its output and any generated files. In the full app these are available via the chat task endpoints:
GET /api/chat/task/{task_id}
GET /api/chat/task/{task_id}/status
GET /api/chat/workspace/{task_id}/files
GET /api/chat/workspace/{task_id}/outputTip
Pass metadata on task creation to correlate runs with your own systems — request ids, user references, or campaign tags.