Skip to content

API Reference

Mission Control exposes a REST API at http://localhost:3000/api/. All endpoints return JSON. There is no authentication required for local access (the gateway token protects the OpenClaw gateway separately).

Base URL: http://localhost:3000 (or http://localhost:3333 if using the separate MC container)


Health

GET /api/health

Check if Mission Control is running.

Response:

{
"status": "ok",
"timestamp": "2026-03-26T10:00:00.000Z"
}

Tasks

GET /api/tasks

List all tasks, ordered by last updated.

Response:

[
{
"id": "task_abc123",
"title": "Implement OAuth flow",
"description": "Add Claude Max OAuth support",
"status": "in_progress",
"priority": "high",
"assignedTo": "freya",
"projectId": "clawhalla",
"storyId": "story_xyz",
"sprintId": "sprint_01",
"estimatedHours": 8,
"actualHours": null,
"tags": "auth,security",
"notes": null,
"createdAt": "2026-03-25T08:00:00.000Z",
"updatedAt": "2026-03-25T14:00:00.000Z",
"completedAt": null
}
]

POST /api/tasks

Create a new task.

Request body:

{
"title": "Fix login redirect",
"description": "Users are redirected to 404 after login",
"status": "backlog",
"priority": "high",
"assignedTo": "freya",
"projectId": "clawhalla",
"storyId": "story_xyz",
"sprintId": "sprint_01",
"estimatedHours": 4,
"tags": "bug,auth"
}

Response: 201 Created with the created task object.

GET /api/tasks/[id]

Get a single task by ID.

Response: Task object (same shape as list items).

PATCH /api/tasks/[id]

Update a task. Send only the fields you want to change.

Request body:

{
"status": "review",
"actualHours": 6,
"notes": "Completed. PR #42 ready for review."
}

Response: Updated task object.

DELETE /api/tasks/[id]

Delete a task permanently.

Response:

{ "ok": true }

Sprints

GET /api/sprints

List all sprints.

Response:

[
{
"id": "sprint_01",
"name": "Sprint 1 - Core Features",
"status": "active",
"startDate": "2026-03-20",
"endDate": "2026-03-27",
"storyIds": "[\"story_01\",\"story_02\"]",
"createdAt": "2026-03-20T08:00:00.000Z",
"updatedAt": "2026-03-25T10:00:00.000Z"
}
]

POST /api/sprints

Create a sprint.

Request body:

{
"name": "Sprint 2 - Polish",
"startDate": "2026-03-27",
"endDate": "2026-04-03",
"storyIds": ["story_03", "story_04"]
}

PATCH /api/sprints

Update a sprint by ID (include id in the body).

DELETE /api/sprints

Delete a sprint (pass id as query parameter).


Epics

GET /api/epics

List all epics.

Response:

[
{
"id": "epic_01",
"title": "Mission Control Dashboard",
"status": "active",
"priority": "high",
"createdBy": "odin",
"approvedBy": "daniel",
"notes": "Full dashboard with task management and agent monitoring",
"createdAt": "2026-03-20T08:00:00.000Z",
"updatedAt": "2026-03-25T10:00:00.000Z",
"completedAt": null
}
]

POST /api/epics

Create an epic.

PATCH /api/epics

Update an epic (include id in the body).

DELETE /api/epics

Delete an epic (pass id as query parameter).


Projects

GET /api/projects

List all projects.

Response:

[
{
"id": "clawhalla",
"name": "ClawHalla",
"description": "Docker-based launcher for OpenClaw",
"status": "active",
"squad": "dev_squad",
"startDate": "2026-03-01T00:00:00.000Z",
"endDate": null,
"createdAt": "2026-03-01T00:00:00.000Z",
"updatedAt": "2026-03-25T10:00:00.000Z"
}
]

POST /api/projects

Create a project.

PATCH /api/projects

Update a project.

DELETE /api/projects

Delete a project.


Activities

GET /api/activities

List recent activities (agent actions logged by the workspace watcher).

Response:

[
{
"id": "act_m1x2y3_a4b5",
"agentId": "freya",
"action": "task_updated",
"target": "tasks.yaml",
"details": "projects/clawhalla/board/doing/tasks.yaml",
"timestamp": "2026-03-25T14:30:00.000Z"
}
]

POST /api/activities

Log a custom activity.

Request body:

{
"agentId": "bragi",
"action": "content_published",
"target": "LinkedIn post",
"details": "Published post about AI agents"
}

Approvals

GET /api/approvals

List all approvals, separated into pending and history.

Response:

{
"pending": [
{
"id": "apr_m1x2y3",
"taskId": "LinkedIn post: AI agents",
"requestedBy": "bragi",
"approver": "daniel",
"status": "pending",
"command": "publish",
"reason": "Draft ready. 1200 words, 3 images.",
"createdAt": "2026-03-25T10:00:00.000Z",
"resolvedAt": null
}
],
"history": [
{
"id": "apr_k9j8h7",
"taskId": "Deploy v0.2.0",
"requestedBy": "odin",
"approver": "daniel",
"status": "approved",
"command": "deploy",
"reason": "All tests passing. Ready for production.",
"createdAt": "2026-03-24T16:00:00.000Z",
"resolvedAt": "2026-03-24T16:30:00.000Z"
}
]
}

POST /api/approvals

Create an approval request.

Request body:

{
"title": "Publish LinkedIn post",
"type": "publish",
"requestedBy": "bragi",
"context": "Draft reviewed by Frigg. 1200 words about AI agents in dev."
}

PATCH /api/approvals/[id]

Approve or reject an approval.

Request body:

{
"status": "approved",
"reason": "Looks good, publish it."
}

Valid statuses: approved, rejected.


Vault

The vault stores encrypted secrets (API keys, tokens). Values are encrypted with AES-256-GCM.

GET /api/vault

List all secrets. Values are never included in the response.

Response:

{
"ok": true,
"secrets": [
{
"id": "sec_m1x2y3",
"name": "LINKEDIN_ACCESS_TOKEN",
"description": "LinkedIn API access token",
"category": "api_key",
"createdBy": "daniel",
"createdAt": "2026-03-25T08:00:00.000Z",
"updatedAt": "2026-03-25T08:00:00.000Z",
"lastAccessedAt": null
}
]
}

POST /api/vault

Create or update a secret.

Request body:

{
"name": "LINKEDIN_ACCESS_TOKEN",
"value": "your-actual-secret-value",
"description": "LinkedIn API access token",
"category": "api_key"
}

DELETE /api/vault

Delete a secret.

Query parameters: ?name=LINKEDIN_ACCESS_TOKEN

POST /api/vault/reveal

Decrypt and return a secret value.

Request body:

{
"name": "LINKEDIN_ACCESS_TOKEN"
}

Response:

{
"ok": true,
"name": "LINKEDIN_ACCESS_TOKEN",
"value": "your-actual-secret-value"
}

POST /api/vault/inject

Inject a vault secret as an environment variable into the runtime.

Request body:

{
"name": "LINKEDIN_ACCESS_TOKEN",
"envVar": "LINKEDIN_TOKEN"
}

Chat

POST /api/chat

Send a message to an agent. Supports single agent and party mode (multi-agent).

Single agent mode:

{
"message": "What tasks are assigned to you?",
"agentId": "odin"
}

Party mode (multi-agent):

{
"message": "Discuss the architecture for the new feature",
"agentIds": ["odin", "thor", "freya"],
"mode": "party"
}

Response: Streamed or JSON response with agent output.


Crons

GET /api/crons

List all cron jobs.

Response:

{
"ok": true,
"jobs": [
{
"id": "cron_abc123",
"name": "daily-standup",
"cron": "0 9 * * *",
"agentId": "odin",
"message": "Generate standup report",
"enabled": true,
"lastRun": "2026-03-25T09:00:00.000Z",
"nextRun": "2026-03-26T09:00:00.000Z"
}
]
}

POST /api/crons

Create a new cron job.

Request body:

{
"name": "weekly-report",
"agentId": "loki",
"cron": "0 18 * * 5",
"message": "Generate weekly analytics report",
"model": "sonnet",
"timezone": "America/Sao_Paulo"
}

PATCH /api/crons

Update or control a cron job.

Enable/disable:

{ "id": "cron_abc123", "action": "enable" }
{ "id": "cron_abc123", "action": "disable" }

Trigger manually:

{ "id": "cron_abc123", "action": "run" }

Edit fields:

{
"id": "cron_abc123",
"name": "updated-name",
"cron": "0 10 * * *",
"message": "Updated prompt"
}

DELETE /api/crons

Delete a cron job.

Query parameters: ?id=cron_abc123


Terminal

POST /api/terminal

Execute a shell command inside the container.

Request body:

{
"command": "openclaw status"
}

Response:

{
"ok": true,
"output": "Gateway running on port 18789\n...",
"exitCode": 0
}

GET /api/search

Full-text search across workspace files.

Query parameters:

  • q — Search query (minimum 2 characters, required)
  • category — Filter by category (optional)
  • limit — Max results (default: 20)

Example: GET /api/search?q=deployment&limit=10

Response:

{
"ok": true,
"query": "deployment",
"count": 3,
"results": [
{
"path": "skills/engineering/ci-cd-patterns.md",
"score": 0.85,
"excerpt": "...deployment pipeline using GitHub Actions..."
}
],
"stats": {
"totalFiles": 150,
"indexedAt": "2026-03-25T12:00:00.000Z"
}
}

POST /api/search

Trigger a full reindex of workspace files.

Response:

{
"ok": true,
"filesIndexed": 150,
"duration": 1234
}

SSE (Server-Sent Events)

GET /api/sse

Subscribe to real-time workspace events. Uses the Server-Sent Events protocol.

Event types:

data: {"type":"connected","timestamp":1711360000000}
data: {"type":"file_change","event":{"type":"created","path":"memory/2026-03-26.md","timestamp":1711360000000}}
data: {"type":"file_change","event":{"type":"updated","path":"projects/clawhalla/board/doing/tasks.yaml","timestamp":1711360001000}}
data: {"type":"ping","timestamp":1711360030000}

Usage in JavaScript:

const sse = new EventSource('/api/sse');
sse.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'file_change') {
console.log(`File ${data.event.type}: ${data.event.path}`);
}
};

Sends a heartbeat ping every 30 seconds to keep the connection alive.


Agents

GET /api/agents/factory

List available persona templates for agent creation.

Response:

{
"ok": true,
"templates": [
{
"id": "senior-dev",
"name": "Senior Dev",
"tier": "execution",
"path": "execution/senior-dev.md"
}
]
}

POST /api/agents/factory

Create a new agent from a template.

Request body:

{
"templateId": "senior-dev",
"name": "Atlas",
"agentId": "atlas",
"emoji": "gear",
"model": "claude-sonnet-4-6",
"squad": "dev_squad",
"reportsTo": "thor"
}

GET /api/agents/health

Get health status of all registered agents.

Response:

{
"ok": true,
"agents": [
{
"id": "main",
"state": "active",
"lastActivityMs": 1711360000000,
"idleMinutes": 2,
"model": "claude-opus-4-6",
"sessionCount": 3
},
{
"id": "odin",
"state": "idle",
"lastActivityMs": 1711350000000,
"idleMinutes": 45,
"model": "claude-sonnet-4-6",
"sessionCount": 1
}
]
}

Health states: active (under 2 min idle), idle (2-5 min or over 30 min), stalled (5-15 min), stuck (15-30 min), offline (gateway down).

GET /api/agents/coverage

Find agents that can cover for a given agent.

Query parameters: ?agent=freya

Response:

{
"ok": true,
"target": "freya",
"candidates": [
{
"id": "volund",
"role": "dev_github",
"skillOverlap": 3,
"sameTier": true
}
]
}

Packs

GET /api/packs

List available squad packs.

Response:

{
"ok": true,
"packs": [
{
"name": "Social Media Squad",
"version": "1.0.0",
"description": "Content research, creation, and publishing",
"agents": 3
}
]
}

POST /api/packs

Install a squad pack. Creates all agents, workspace directories, and org structure entries.


Git

GET /api/git

Get repository status.

Response:

{
"ok": true,
"branch": "main",
"commits": [
{ "hash": "abc1234", "message": "feat: add vault endpoint" }
],
"dirty": false,
"changedFiles": [],
"ahead": 0,
"behind": 0,
"remote": "https://github.com/deegalabs/clawhalla.git",
"lastCommitDate": "2026-03-25 14:00:00 -0300"
}

POST /api/git

Execute a git operation (commit, push, pull).


Council

GET /api/council/session

List council sessions (multi-agent deliberation).

POST /api/council/session

Start a new council session where multiple agents discuss a topic.

Request body:

{
"topic": "Should we migrate to a monorepo?",
"agents": ["odin", "thor", "freya"],
"rounds": 3
}

Feedback

GET /api/feedback

List feedback entries. Filter by agent with ?agent=bragi.

Response:

{
"ok": true,
"entries": [
{
"id": "fb_001",
"agentId": "bragi",
"taskId": "CLA-T-055",
"type": "correction",
"content": "Posts should be shorter -- max 800 words",
"context": "Post was 1500 words, too dense",
"createdAt": "2026-03-25T10:00:00.000Z",
"appliedTo": ["squads/clop-cabinet/cma/AGENTS.md"]
}
]
}

POST /api/feedback

Submit feedback for an agent.

Request body:

{
"agentId": "bragi",
"taskId": "CLA-T-055",
"type": "correction",
"content": "LinkedIn posts should be max 800 words",
"context": "Previous post was too long"
}

Types: correction, praise, pattern, rule.


Usage

GET /api/usage

Get token usage and cost summary.

Response:

{
"ok": true,
"today": {
"totalInputTokens": 150000,
"totalOutputTokens": 45000,
"estimatedCostCents": 350,
"byAgent": {
"claw": { "input": 50000, "output": 15000, "cost": 150 },
"odin": { "input": 100000, "output": 30000, "cost": 200 }
}
},
"allTime": {
"totalEvents": 500,
"estimatedCostCents": 5000
}
}

POST /api/usage

Log a cost event.

Request body:

{
"agentId": "odin",
"model": "claude-sonnet-4-6",
"action": "session",
"inputTokens": 5000,
"outputTokens": 1500,
"taskId": "CLA-T-042"
}

Memory

GET /api/memory

List daily memory files from agent workspaces.

Response:

[
{
"name": "2026-03-25.md",
"path": "/home/clawdbot/.openclaw/workspace/memory/2026-03-25.md",
"date": "2026-03-25",
"size": 4096,
"wordCount": 650,
"content": "# 2026-03-25\n\n## Session Notes\n...",
"modifiedAt": "2026-03-25T23:00:00.000Z"
}
]

GET /api/memory/longterm

Get the curated long-term memory file (MEMORY.md).

Response:

{
"content": "# Long-Term Memory\n\n## Key Decisions\n...",
"wordCount": 1200,
"modifiedAt": "2026-03-25T20:00:00.000Z",
"size": 8192
}

Memory Configuration

GET /api/memory/config

Returns current memory/RAG configuration, per-agent status, and available embedding providers.

Response:

{
"ok": true,
"config": {
"provider": "ollama",
"enabled": true
},
"agents": [
{
"agentId": "main",
"provider": "ollama",
"indexed": 12,
"total": 15,
"chunks": 89,
"dirty": false,
"vectorReady": true,
"mode": "default"
}
],
"providers": [...]
}
POST /api/memory/config

Update memory/RAG provider configuration and per-agent modes.

Body:

{
"provider": "ollama",
"enabled": true,
"agentModes": {
"mimir": "rag",
"freya": "md",
"thor": "default"
}
}

Semantic Search (RAG)

GET /api/memory/rag?q=query&agent=main&limit=10

Semantic search across agent memory using the configured embedding provider.

ParameterTypeDefaultDescription
qstringrequiredSearch query (min 2 chars)
agentstringmainAgent ID to search
limitnumber10Max results to return
POST /api/memory/rag

Trigger memory reindexing.

Body:

{
"agent": "main",
"force": true
}

Docs

GET /api/docs

Scan and return all markdown and YAML files in the workspace.

Response:

[
{
"name": "AGENTS.md",
"path": "/home/clawdbot/.openclaw/workspace/AGENTS.md",
"category": "Other",
"size": 10227,
"wordCount": 1500,
"modifiedAt": "2026-03-23T22:11:00.000Z",
"content": "## Organizational Context..."
}
]

Categories: Journal, Insights, Transcription, ADR, Report, Other.


Org Structure

GET /api/org-structure

Get the full organizational hierarchy.

Response: Parsed org_structure.yaml with agent details, squads, tiers, and escalation chains.


Gateway

GET /api/gateway/sessions

List active gateway sessions (proxied through the gateway).

Response:

{
"ok": true,
"sessions": [
{
"key": "main-session-key",
"agentId": "main",
"lastActivity": 1711360000000,
"model": "claude-opus-4-6"
}
]
}

GET /api/gateway/crons

List cron jobs from the gateway directly.


LinkedIn

GET /api/linkedin

Check LinkedIn connection status.

Response:

{
"ok": true,
"connected": true,
"profile": {
"name": "Daniel Gorgonha",
"email": "daniel@example.com",
"sub": "abc123"
}
}

POST /api/linkedin

Publish a LinkedIn post.

Request body:

{
"text": "Your post content here...",
"imageUrl": "https://example.com/image.jpg"
}

Requires LINKEDIN_ACCESS_TOKEN in the vault.


Skills

GET /api/skills/import

List installed skills by category.

Response:

{
"ok": true,
"categories": [
{
"category": "engineering",
"skills": ["docker-best-practices", "ci-cd-patterns"]
},
{
"category": "content",
"skills": ["seo-checklist"]
}
]
}

POST /api/skills/import

Import a skill from URL or raw content.

Request body:

{
"name": "react-patterns",
"category": "engineering",
"content": "# React Patterns\n\n## Component design...",
"url": null
}

Board (Legacy)

These endpoints provide direct board access through workspace YAML files.

GET /api/board/sync

Sync board state from workspace files.

Query parameters: ?project=clawhalla

PATCH /api/board/update

Update a task status on the board.

Request body:

{
"project": "clawhalla",
"taskId": "CLA-T-042",
"status": "in_progress",
"agentId": "thor"
}

POST /api/board/import

Import board data from external YAML files.


Content Publishing

POST /api/content/publish

Publish content to configured platforms (LinkedIn, Twitter, etc.) with approval flow.

GET /api/content/platforms

List available platform adapters and their configuration status.


Telegram Webhook

POST /api/telegram/webhook

Telegram bot webhook endpoint. Handles inline approval buttons and media uploads.


Heartbeat

POST /api/heartbeat

Trigger a heartbeat check for an agent.

Request body:

{
"agentId": "frigg"
}