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 steps

A 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-stream

The stream carries these event types:

EventPayloadMeaning
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}/output

Tip

Pass metadata on task creation to correlate runs with your own systems — request ids, user references, or campaign tags.

Next Steps