Base URL: http://127.0.0.1:3000 (configurable via env vars)
Dual-user design: Every API endpoint can be called by both human users (via the GUI) and AI agents (via HTTP). The GUI makes the same API calls that agents make — there is no separate "admin" API.
All write endpoints require one of:
- Header:
Authorization: Bearer <token> - Body field:
"write_token": "<token>"
Default token: change-me-local (set CLAWTASKER_API_TOKEN env var to override)
Returns server health and version information.
Response:
{
"ok": true,
"time": "2026-03-21T09:30:00+00:00",
"version": "1.5.0",
"booted_at": "2026-03-21T08:00:00+00:00",
"role": "visualization-companion",
"visualization_only": true,
"state_source": "local",
"restart_safe": true,
"agents": 13,
"tasks": 15,
"uptime_seconds": 3600
}Returns the full current state: agents, tasks, projects, events, missions, conversations.
Response:
{
"agents": [...],
"tasks": [...],
"projects": [...],
"events": [...],
"missions": [...],
"conversations": [...],
"ui_settings": {...},
"version": "1.5.0",
"timestamp": "2026-03-21T09:30:00+00:00"
}Server-Sent Events stream. Subscribe to receive real-time state updates.
Headers: Accept: text/event-stream
Event format:
id: 42
event: clawtasker
data: {"id":42,"timestamp":"...","kind":"task_updated","title":"Codex updated T-203","details":"status→validation","meta":{}}
Event kinds: state_saved, agent_registered, agent_heartbeat, task_updated, mission_planned, message_posted, directive_queued, agent_decommission
Returns the agent integration contract — system prompt fragments and endpoint reference for AI agents to understand how to integrate.
Returns the JSON Schema for POST /api/tasks/update.
Returns the JSON Schema for POST /api/agents/register.
Returns the JSON Schema for POST /api/missions/plan.
Returns the JSON Schema for POST /api/agents/heartbeat.
Returns the JSON Schema for POST /api/conversations/message.
Returns the last recovery log entry and backup chain status. Useful for diagnosing startup issues.
Register a new AI agent. Call once on startup.
Body:
{
"agent_id": "codex",
"name": "Codex",
"role": "Engineering Manager",
"home_specialist": "code",
"skills": ["backend", "testing", "integration"],
"manager": "orion",
"project_id": "ceo-console",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"agent": {"id": "codex", "name": "Codex", "status": "idle", ...},
"org_card": {...},
"org_structure": {...},
"registration": {"operation": "registered", "registered_at": "2026-03-21T09:00:00+00:00"},
"contract": {...}
}Send a periodic heartbeat (every ~60 seconds recommended).
Body:
{
"agent_id": "codex",
"status": "working",
"current_task_id": "T-203",
"doing_summary": "Implementing board filter system",
"done_summary": "Completed state adapter refactor",
"next_summary": "Hand off to Ralph for validation",
"blockers": [],
"speaking": false,
"write_token": "change-me-local"
}Status values: working · idle · blocked · validation · offline
Response:
{
"ok": true,
"agent": {"id": "codex", "status": "working", "last_heartbeat": "2026-03-21T09:01:00+00:00", ...}
}Update a task's status, progress, notes, and artifacts.
Body:
{
"agent_id": "codex",
"task_id": "T-203",
"status": "validation",
"progress": 95,
"note": "Filters working across all views. Handing to Ralph.",
"blockers": [],
"artifacts": [
"company/projects/ceo-console/web/app.js"
],
"write_token": "change-me-local"
}Allowed status transitions:
backlog → ready
ready → backlog | in_progress
in_progress → ready | validation
validation → in_progress | done
done → validation
Response:
{
"ok": true,
"task": {"id": "T-203", "status": "validation", "progress": 95, ...}
}Create a new task directly. Available to both human operators (GUI) and AI agents.
Body:
{
"title": "Implement OAuth login",
"description": "Add Google OAuth support to the login page",
"project_id": "atlas-core",
"owner": "codex",
"specialist": "code",
"priority": "P1",
"status": "backlog",
"story_points": 5,
"type": "story",
"reporter": "alice",
"acceptance_criteria": ["User can log in with Google", "Session persists across page reloads"],
"definition_of_done": ["Implementation complete", "Tests passing", "Reviewed"],
"write_token": "change-me-local"
}All fields except title are optional. New fields: type (one of bug, story, task, spike, epic; default task), reporter (defaults to author or "ceo"), acceptance_criteria (list of strings), assignees (additional agent IDs beyond owner). The response task object also includes: links: [], activity: [].
Response:
{
"ok": true,
"task": {"id": "T-216", "title": "Implement OAuth login", "status": "backlog", ...}
}Permanently delete a task. Removes it from missions and dependency chains.
Body:
{
"task_id": "T-216",
"write_token": "change-me-local"
}Response:
{ "ok": true, "task_id": "T-216" }Create a named, bidirectional link between two tasks. The reverse/symmetric link is automatically added to the target task.
Supported link_type values: relates-to, duplicates, blocks, is-blocked-by, child-of, parent-of
Body:
{
"source_id": "T-101",
"target_id": "T-202",
"link_type": "blocks",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"source_id": "T-101",
"target_id": "T-202",
"link_type": "blocks",
"symmetric_type": "is-blocked-by"
}Errors: source_id is required, target_id is required, invalid link_type: <x>, cannot link a task to itself, unknown source task: <id>, unknown target task: <id>, link already exists: <source> <type> <target>
Append a comment to a task. Comments are stored in the task's comments[] array.
Body:
{
"task_id": "T-203",
"text": "Verified on staging — all filter combinations work correctly.",
"author": "ralph",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"task_id": "T-203",
"comment": {
"id": "CM-1711234567890-0",
"author": "ralph",
"text": "Verified on staging — all filter combinations work correctly.",
"timestamp": "2026-03-21T10:00:00+00:00"
}
}Chief agent proposes a new mission. Creates child tasks automatically.
Body:
{
"agent_id": "orion",
"title": "Launch v1.2.0 release candidate",
"objective": "Package, validate, and publish the v1.2.0 release with full documentation.",
"project_id": "ceo-console",
"horizon": "This Week",
"severity": "high",
"tasks": [
{
"title": "Package release zip",
"specialist": "ops",
"priority": "P0",
"description": "Bundle all web assets and server.py into the release archive.",
"owner": "charlie"
},
{
"title": "Update README and CHANGELOG",
"specialist": "docs",
"priority": "P1",
"description": "Document all v1.2.0 features for GitHub.",
"owner": "quill"
}
],
"write_token": "change-me-local"
}Response:
{
"ok": true,
"mission": {"id": "M-001", "title": "Launch v1.2.0 release candidate", ...},
"mission_control": {...},
"operation": "created"
}Permanently delete a mission. Tasks linked to it are unlinked but not deleted.
Body:
{
"mission_id": "M-301",
"write_token": "change-me-local"
}Response:
{ "ok": true, "mission_id": "M-301" }Delete a sprint. Tasks assigned to it become unsprinted.
Body:
{
"sprint_id": "SPR-007",
"write_token": "change-me-local"
}Response:
{ "ok": true, "sprint_id": "SPR-007" }Delete a project. Tasks and agents referencing it keep their project_id for history. Cannot delete the built-in ceo-console project.
Body:
{
"project_id": "atlas-core",
"write_token": "change-me-local"
}Response:
{ "ok": true, "project_id": "atlas-core" }Post a message to a conversation thread.
Body:
{
"sender": "orion",
"thread_id": "TH-CEO-ORION",
"text": "CEO priority stack confirmed. Routing filters to Codex, office polish to Pixel.",
"category": "directive",
"project_id": "ceo-console",
"write_token": "change-me-local"
}Category values: directive · discussion · summary · status · ack
Response:
{
"ok": true,
"thread": {"id": "TH-CEO-ORION", ...},
"message": {"id": "M-042", "sender": "orion", "text": "...", ...}
}CEO posts a directive, optionally creating a backlog task.
Body:
{
"target": "pixel",
"project_id": "ceo-console",
"text": "Polish the office canvas: ensure all zones are clearly labelled and furniture is visible at all zoom levels.",
"create_task": true,
"specialist": "design",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"directive": {
"id": "D-015",
"target": "pixel",
"text": "...",
"status": "queued",
"timestamp": "2026-03-21T09:05:00+00:00"
}
}Remove an agent from the active roster. Unassigns their tasks and removes them from missions.
Body:
{
"agent_id": "echo",
"reason": "Project market-radar paused; agent standing down.",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"message": "Agent Echo (echo) marked offline",
"agent_id": "echo",
"reason": "Project market-radar paused; agent standing down.",
"tasks_unassigned": ["T-203", "T-204"]
}Constraints: Cannot decommission the CEO agent.
Gracefully retire an agent, optionally handing off all tasks to a successor.
Body:
{
"agent_id": "echo",
"reason": "Project market-radar complete; agent standing down.",
"successor_id": "nova",
"write_token": "change-me-local"
}successor_id is optional. If omitted, tasks are unassigned rather than transferred.
Response:
{
"ok": true,
"message": "Agent Echo (echo) retired",
"agent_id": "echo",
"reason": "Project market-radar complete; agent standing down.",
"successor_id": "nova",
"tasks_transferred": ["T-203", "T-204"]
}Transfer all task and mission assignments from one agent to another, then retire the old agent.
Body:
{
"old_agent_id": "echo",
"new_agent_id": "nova",
"reason": "Nova is taking over the market-radar workstream.",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"message": "Agent Echo (echo) replaced by Nova (nova)",
"old_agent_id": "echo",
"new_agent_id": "nova",
"reason": "Nova is taking over the market-radar workstream.",
"tasks_transferred": ["T-203", "T-204"]
}Merge a source agent into a target agent: transfers all tasks and missions, combines skills, then retires the source.
Body:
{
"source_agent_id": "echo-v1",
"target_agent_id": "echo",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"message": "Agent Echo-v1 (echo-v1) merged into Echo (echo)",
"source_agent_id": "echo-v1",
"target_agent_id": "echo",
"tasks_transferred": ["T-203"]
}Constraints: Source and target must be different agents. Cannot merge the CEO.
Update any mutable field on an existing agent without a full re-register.
Body:
{
"agent_id": "orion",
"name": "Orion",
"role": "Chief of Staff",
"emoji": "🚀",
"skills": ["planning", "triage", "routing"],
"specialists": ["planning"],
"note": "Running the morning sweep.",
"write_token": "change-me-local"
}All fields except agent_id and write_token are optional. Only fields present in the body are updated.
Mutable fields: name, role, manager, emoji, profile_hue, department, org_level, team_id, team_name, coordination_scope, manager_title, avatar_ref, project_id, note, done_summary, doing_summary, next_summary, status, skills, specialists, allowed_tools, blockers, collaborating_with
Response:
{
"ok": true,
"agent": { "id": "orion", "name": "Orion", "role": "Chief of Staff", ... }
}Permanently remove an agent from the roster. All tasks and missions previously owned by the agent are unassigned (not deleted).
Body:
{
"agent_id": "iris",
"write_token": "change-me-local"
}Response:
{
"ok": true,
"deleted": "iris"
}Constraints: Cannot delete the chief agent.
Update org-level settings: chief agent, CEO display name/role, company name.
Body:
{
"chief_agent_id": "orion",
"ceo_name": "Alex",
"ceo_role": "Chief Executive Officer",
"company_name": "Acme Corp",
"write_token": "change-me-local"
}All fields are optional. Only provided fields are updated.
Create or update a project.
Body:
{
"project_id": "atlas-core",
"name": "Atlas Core",
"status": "active",
"write_token": "change-me-local"
}Create a new sprint.
Body:
{
"name": "Sprint 7",
"project_id": "ceo-console",
"start_date": "2026-03-24",
"end_date": "2026-04-06",
"write_token": "change-me-local"
}Update an existing sprint (status, dates, name).
Body:
{
"sprint_id": "SP-007",
"status": "active",
"write_token": "change-me-local"
}Dismiss one or more notifications.
Body:
{
"notification_ids": ["N-001", "N-002"],
"write_token": "change-me-local"
}Publish an agent run result — updates the run log and broadcasts an event.
Body:
{
"agent_id": "codex",
"task_id": "T-203",
"title": "Filter system pass",
"outcome": "working",
"summary": "Added project and agent filters across board, backlog, and calendar views.",
"artifacts": ["company/projects/ceo-console/web/app.js"],
"write_token": "change-me-local"
}Outcome values: working · needs_attention · blocked · validation
Sync an external roster of agents into ClawTasker in bulk. Registers or updates multiple agents in one call.
Body:
{
"agents": [
{"agent_id": "codex", "name": "Codex", "role": "Engineering Manager", "manager": "orion"},
{"agent_id": "pixel", "name": "Pixel", "role": "Design Lead", "manager": "orion"}
],
"write_token": "change-me-local"
}Reset all state to demo defaults (13 agents, 15 tasks, 3 projects). Destructive.
Body:
{ "write_token": "change-me-local" }Reset to a blank state with no agents, tasks, missions, or conversations. Retains structural scaffolding (skill catalog, org templates, office layout). Use this to start a fresh org without demo noise. Destructive.
Body:
{ "write_token": "change-me-local" }Response:
{ "ok": true, "reset": true, "mode": "blank" }Bootstrap a blank state with your own company info, projects, and agents in one call. Internally calls POST /api/blank/reset then registers the provided manifest. Destructive.
Body:
{
"company_name": "Acme Corp",
"ceo_name": "Alex",
"projects": [
{"project_id": "atlas-core", "name": "Atlas Core", "status": "active"}
],
"agents": [
{
"agent_id": "orion",
"name": "Orion",
"role": "Chief of Staff",
"home_specialist": "planning",
"skills": ["coordination", "planning"],
"manager": "ceo",
"project_id": "atlas-core"
}
],
"write_token": "change-me-local"
}All fields except write_token are optional. Agents that fail validation are skipped and listed in warnings.
Response:
{
"ok": true,
"agents_registered": ["orion"],
"projects": ["ceo-console", "atlas-core"],
"warnings": []
}All errors follow this shape:
{ "error": "agent_id is required" }| HTTP Status | Meaning |
|---|---|
| 400 | Bad request — invalid or missing fields |
| 401 | Unauthorised — missing or invalid write token |
| 404 | Not found — unknown route |
| 405 | Method not allowed |
| 413 | Request body too large (max 160 KB) |
| 429 | Rate limit exceeded — back off and retry |
| 500 | Internal server error |
Write endpoints are rate-limited per IP. Default: 30 requests/minute.
Configure with: CLAWTASKER_WRITE_LIMIT=60 python3 server.py
On limit hit, the server responds with HTTP 429 and a Retry-After header.
const es = new EventSource('http://127.0.0.1:3000/api/events/stream');
es.addEventListener('clawtasker', e => {
const event = JSON.parse(e.data);
console.log(`[${event.kind}] ${event.title}`);
if (event.kind === 'task_updated') {
// Refresh task board in your UI
refreshTaskBoard();
}
});
es.onerror = () => {
console.warn('SSE disconnected, will reconnect automatically');
};Add this to your agent's system prompt to wire it into ClawTasker:
You are connected to ClawTasker CEO Console v1.2.0.
On startup:
1. POST /api/agents/register — send your agent_id, name, role, home_specialist, skills, and manager.
Every ~60 seconds:
2. POST /api/agents/heartbeat — send your status (working/idle/blocked/validation), current_task_id, doing_summary, done_summary, next_summary, and any blockers.
When task status changes:
3. POST /api/tasks/update — send task_id, new status, progress %, note, and artifacts list.
When you propose work:
4. POST /api/missions/plan — describe the mission objective and list proposed tasks with specialist labels.
Subscribe to live events:
5. GET /api/events/stream — EventSource for real-time state updates.
Full contract: GET /api/openclaw/contract
All schemas: GET /api/schema/task | /api/schema/agent-register | /api/schema/mission-plan | /api/schema/heartbeat | /api/schema/message
Returns the highest-priority eligible task for a given agent.
Auth: Bearer token required
Query parameters:
| Parameter | Required | Description |
|---|---|---|
owner |
Yes | Agent ID to fetch next task for |
project |
No | Filter by project_id |
Response:
{
"ok": true,
"task": { /* full enriched task object */ },
"message": "no eligible tasks" // only when task is null
}Eligibility rules:
status == "ready"ownermatches the given agent ID- No unresolved blockers (
has_unresolved_blockers == false) - Sorted: P0 > P1 > P2 > P3, then oldest update first
Example (agent):
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:3000/api/tasks/next?owner=codex"Shorthand task lifecycle event publisher. Updates task status, adds a comment, and records activity in one call.
Auth: Bearer token required
Body:
{
"type": "started",
"task_id": "T-042",
"agent_id": "codex",
"note": "Beginning implementation of auth module"
}| Field | Required | Values |
|---|---|---|
type |
Yes | started, blocked, done, needs-validation |
task_id |
Yes | Task ID string |
agent_id |
Yes | Agent ID string |
note |
No | Optional text for the auto-created comment |
Status transitions:
| Event type | Status result |
|---|---|
started |
in_progress |
blocked |
(unchanged, sets blocked: true) |
done |
done |
needs-validation |
validation |
Response:
{
"ok": true,
"task": { /* full enriched task */ },
"event_type": "started"
}Example (agent operating loop):
import requests
headers = {"Authorization": f"Bearer {TOKEN}"}
base = "http://localhost:3000"
# 1. Get next task
task = requests.get(f"{base}/api/tasks/next?owner=codex", headers=headers).json()["task"]
# 2. Claim it
requests.post(f"{base}/api/tasks/event", json={
"type": "started", "task_id": task["id"], "agent_id": "codex",
"note": "Starting work on this task"
}, headers=headers)
# 3. Do the work...
# 4. Send to validation
requests.post(f"{base}/api/tasks/event", json={
"type": "needs-validation", "task_id": task["id"], "agent_id": "codex",
"note": "Implementation complete. Output: workspace/myproject/src/auth.py"
}, headers=headers)Returns all predefined task templates. No authentication required.
Response:
{
"ok": true,
"templates": [
{
"id": "software-feature",
"name": "Software Feature",
"specialist": "code",
"type": "story",
"priority": "P1",
"description": "Implement a new software feature...",
"definition_of_done": ["Implementation complete", "Unit tests passing", "Docs updated", "PR merged"],
"acceptance_criteria": ["Feature works as described", "No regressions", "Reviewed and approved"],
"labels": ["feature", "engineering"]
}
]
}Available templates: compliance-memo, market-validation, gtm-plan, founder-decision, research-brief, software-feature
┌──────────────────┐ REST API ┌──────────────────┐
│ Human CEO │ ◄───────────────► │ ClawTasker │
│ (Browser GUI) │ │ Server │
└──────────────────┘ │ (server.py) │
│ │
┌──────────────────┐ REST API │ │
│ AI Agent │ ◄───────────────► │ │
│ (HTTP client) │ └──────────────────┘
└──────────────────┘
Both users share the same API:
- POST /api/agents/register — agent self-registration
- POST /api/agents/heartbeat — agent heartbeats
- POST /api/tasks/update — update task status and progress
- POST /api/missions/plan — propose a mission
- POST /api/conversations/message — post to a thread
- POST /api/ceo/directive — queue a CEO directive
- GET /api/events/stream — SSE real-time stream
- GET /api/snapshot — full state snapshot