Complete reference for all REST API endpoints. The API server runs on http://{host}:{port} (default: http://127.0.0.1:7420). All endpoints are prefixed with /api.
All domain errors return structured JSON responses:
| Exception | HTTP Status | Example |
|---|---|---|
NotFoundError |
404 | Organization or agent not found |
ConflictError |
409 | Duplicate name, invalid state transition |
ValidationError |
422 | Invalid snake_case name, non-absolute path |
PreconditionError |
412 | No root agent in organization |
Error response format:
{
"message": "Organization 'payments' not found."
}Get current system status.
Response:
{
"server": "running",
"dispatcher": "running",
"tasks": {
"open": 3,
"in_progress": 1,
"failed": 0,
"done": 12,
"canceled": 1
},
"active_workers": 1,
"max_concurrency": 4,
"consumed_input_tokens": 245000,
"consumed_output_tokens": 89000,
"total_cost": 1.23
}Trigger graceful API server shutdown. The dispatcher continues running.
Response:
{
"message": "API server shutting down. Dispatcher continues running."
}Create a new organization.
Request:
{
"name": "payments",
"workspace_path": "/home/user/payments-service",
"description": "Payments service team"
}name: Required. Must be snake_case (lowercase letters, digits, underscores; starts with a letter). Cannot beuserorsystem.workspace_path: Required. Must be an absolute path.description: Optional.
Response (201):
{
"name": "payments",
"description": "Payments service team",
"workspace_path": "/home/user/payments-service",
"agents": [],
"consumed_input_tokens": 0,
"consumed_output_tokens": 0,
"total_cost": 0.0
}List all organizations.
Response:
{
"organizations": [
{
"name": "payments",
"description": "Payments service team",
"workspace_path": "/home/user/payments-service",
"agent_count": 3,
"consumed_input_tokens": 245000,
"consumed_output_tokens": 89000,
"total_cost": 1.23
}
]
}Get organization details including the agent hierarchy tree.
Response:
{
"name": "payments",
"description": "Payments service team",
"workspace_path": "/home/user/payments-service",
"agents": [
{
"name": "lead_dev",
"description": "Lead developer",
"instructions_path": "/path/to/lead_dev.md",
"max_iterations": 50,
"model": null,
"is_removed": false,
"subordinates": [
{
"name": "backend_dev",
"description": "Backend specialist",
"subordinates": []
}
]
}
],
"consumed_input_tokens": 245000,
"consumed_output_tokens": 89000,
"total_cost": 1.23
}Update organization details.
Request:
{
"workspace_path": "/new/path",
"description": "Updated description"
}All fields are optional. At least one must be provided.
Response: Updated organization detail (same format as GET).
Delete an organization and all associated data.
Response: 204 No Content
Fails with 409 if the organization has any in_progress tasks.
Create a new agent.
Request:
{
"name": "backend_dev",
"instructions_path": "/path/to/backend_dev.md",
"boss": "lead_dev",
"max_iterations": 50,
"model": "anthropic/claude-3-5-sonnet-20241022"
}name: Required. Snake_case, unique within the organization.instructions_path: Required. Path to the.mdinstructions file.boss: Optional. Name of the supervising agent.max_iterations: Optional. Defaults todispatcher.default_max_iterations.model: Optional. LLM model override.
Response (201): Full agent detail.
List agents in an organization.
Query Parameters:
include_removed(boolean, default: false)
Response:
{
"agents": [
{
"name": "backend_dev",
"organization": "payments",
"description": "Backend specialist",
"boss": "lead_dev",
"instructions_path": "/path/to/backend_dev.md",
"max_iterations": 50,
"model": null,
"is_removed": false,
"consumed_input_tokens": 120000,
"consumed_output_tokens": 45000,
"total_cost": 0.65
}
]
}Get agent details including instructions content and subordinates.
Response:
{
"name": "backend_dev",
"organization": "payments",
"description": "Backend specialist",
"boss": "lead_dev",
"instructions_path": "/path/to/backend_dev.md",
"instructions_content": "You are a backend developer...",
"max_iterations": 50,
"model": null,
"is_removed": false,
"subordinates": [],
"consumed_input_tokens": 120000,
"consumed_output_tokens": 45000,
"total_cost": 0.65
}Update agent configuration.
Request:
{
"boss": "new_boss",
"instructions_path": "/new/path.md",
"max_iterations": 100,
"model": "openai/gpt-4o"
}All fields optional. Set boss to null to promote to root. The agent must not be assigned to any in_progress tasks.
Response: Updated agent detail.
Soft-delete an agent. Subordinates are promoted to root.
Response:
{
"removed": "backend_dev",
"warnings": ["Subordinate 'junior_dev' has been promoted to root (no boss)."]
}Create a new task.
Request:
{
"title": "Add idempotency keys",
"organization": "payments",
"description": "Wrap the /charges POST handler in idempotency logic..."
}title: Required.organization: Required.description: Optional. Defaults to the title if not provided.
The task is automatically assigned to the organization's first root agent.
Response (201): Task summary (same format as items in the list endpoint).
List tasks with optional filtering.
Query Parameters:
organization(string, optional)status(string, optional):open,in_progress,failed,done,canceledassignee(string, optional)
Response:
{
"tasks": [
{
"id": "PAYM-0001",
"title": "Add idempotency keys",
"status": "in_progress",
"organization": "payments",
"assignee": "backend_dev",
"created_at": "2026-03-30T10:00:00.000000Z",
"current_run_elapsed_seconds": 45.2,
"total_duration_seconds": null,
"consumed_input_tokens": 50000,
"consumed_output_tokens": 20000,
"total_cost": 0.30
}
]
}current_run_elapsed_seconds: Present whenin_progress, showing real-time elapsed time.total_duration_seconds: Present whendone/failed/canceled, showing sum of all run durations.
Get full task details including description and timeline.
Response:
{
"id": "PAYM-0001",
"title": "Add idempotency keys",
"organization": "payments",
"description": "Wrap the /charges POST handler...",
"status": "open",
"assignee": "user",
"created_at": "2026-03-30T10:00:00.000000Z",
"timeline": [
{
"type": "run_summary",
"run_id": "a1b2c3d4e5f6",
"agent": "backend_dev",
"status": "success",
"duration_seconds": 120.5,
"cost": 0.30,
"started_at": "2026-03-30T10:00:01.000000Z",
"ended_at": "2026-03-30T10:02:01.500000Z"
},
{
"type": "comment",
"author": "backend_dev",
"body": "Added the idempotency table and handler logic. @test_writer",
"created_at": "2026-03-30T10:02:01.000000Z"
}
],
"consumed_input_tokens": 50000,
"consumed_output_tokens": 20000,
"total_cost": 0.30
}Add a comment to a task.
Request:
{
"body": "Please also handle the edge case where the key expires mid-transaction. @backend_dev"
}Response (201):
{
"comment": {
"type": "comment",
"author": "user",
"body": "Please also handle the edge case...",
"created_at": "2026-03-30T11:00:00.000000Z"
},
"task": {
"id": "PAYM-0001",
"status": "open",
"assignee": "backend_dev",
"preempted_run": null
}
}Include @agent_name to route the task to that agent. Include @user to keep it with yourself. The task must not be in_progress, done, or canceled.
Preempt a running task.
Response:
{
"id": "PAYM-0001",
"status": "open",
"assignee": "user",
"preempted_run": "a1b2c3d4e5f6"
}Mark a task as completed. Must be open or failed and assigned to user.
Response:
{
"id": "PAYM-0001",
"status": "done",
"assignee": "user"
}Reopen a done or failed task.
Response:
{
"id": "PAYM-0001",
"status": "open",
"assignee": "user"
}Retry a done or failed task.
Query Parameters:
assignee(string, optional): Agent to assign. Defaults to the agent from the most recent run.
Response:
{
"id": "PAYM-0001",
"status": "open",
"assignee": "backend_dev"
}Cancel a task. Irreversible.
Response:
{
"id": "PAYM-0001",
"status": "canceled",
"assignee": "user",
"preempted_run": "a1b2c3d4e5f6"
}List all runs for a task.
Response:
{
"runs": [
{
"id": "a1b2c3d4e5f6",
"task_id": "PAYM-0001",
"agent": "backend_dev",
"organization": "payments",
"status": "success",
"duration_seconds": 120.5,
"total_cost": 0.30,
"model_used": "minimax/minimax-m2.7",
"started_at": "2026-03-30T10:00:01.000000Z",
"ended_at": "2026-03-30T10:02:01.500000Z"
}
]
}Get full run details including execution steps.
Response:
{
"id": "a1b2c3d4e5f6",
"task_id": "PAYM-0001",
"agent": "backend_dev",
"organization": "payments",
"status": "success",
"duration_seconds": 120.5,
"total_cost": 0.30,
"model_used": "minimax/minimax-m2.7",
"consumed_input_tokens": 50000,
"consumed_output_tokens": 20000,
"started_at": "2026-03-30T10:00:01.000000Z",
"ended_at": "2026-03-30T10:02:01.500000Z",
"execution_steps": [
{
"step": 1,
"type": "llm_reasoning",
"content": "I need to add an idempotency table first..."
},
{
"step": 2,
"type": "tool_call",
"tool": "file_read",
"arguments": {"path": "/path/to/models.py", "mode": "view"}
},
{
"step": 3,
"type": "tool_call",
"tool": "editor",
"arguments": {"path": "/path/to/models.py", "command": "str_replace", "old_str": "...", "new_str": "..."}
},
]
}Step types:
llm_reasoning: Agent's internal reasoning texttool_call: Tool invocation with name and argumentsfatal_error: Error message when the run failed
The API server also serves the web UI:
/assets/*-> Static assets (JS, CSS, images)/{path:path}-> SPA fallback toindex.html
These are served from the bundled sabbatical/web/dist/ directory.