API Contract Baseline

March 7, 2026 ยท View on GitHub

This document defines a contributor-facing API baseline for Claw-Empire. It is intentionally compact and focused on frequently used endpoints. Current baseline target: v1.2.4 (local snapshot, 2026-03-07).

Base

  • Base URL (local): http://127.0.0.1:8790
  • API prefix: /api
  • Health endpoints: /healthz, /api/health
  • Swagger UI: /api/docs
  • OpenAPI JSON: /api/openapi.json

Authentication

  • Loopback/local usage usually works without extra headers.
  • Remote/non-loopback deployments can require:
    • Authorization: Bearer <API_AUTH_TOKEN>
  • Inbox webhook endpoint requires:
    • x-inbox-secret: <INBOX_WEBHOOK_SECRET>
  • Browser session bootstrap (GET /api/auth/session) returns csrf_token.
    • For cookie-authenticated mutation requests (POST/PUT/PATCH/DELETE), send:
      • x-csrf-token: <csrf_token>
  • Interrupt injection endpoint (POST /api/tasks/:id/inject) additionally requires:
    • session_id
    • interrupt_token (or header x-task-interrupt-token)
    • Terminal API (GET /api/tasks/:id/terminal) exposes interrupt.session_id + interrupt.control_token
  • Swagger note:
    • /api/docs opens with an automatic /api/auth/session bootstrap attempt (loopback/local case).
    • If you still get 401 unauthorized, set Bearer <API_AUTH_TOKEN> via Swagger Authorize.

Common Error Shape

Error payloads can vary by route, but API clients should handle:

{
  "error": "error_code",
  "message": "human-readable detail"
}

The frontend client wraps non-2xx responses with ApiRequestError (status, code, details, url).

Messenger Session Contract (v1.2.3)

Messenger channel settings are stored in settings.key = "messengerChannels" and can include:

  • token: channel token (encrypted at rest with AES-256-GCM using OAUTH_ENCRYPTION_SECRET, fallback: SESSION_SECRET)
  • sessions[]:
    • id
    • name
    • targetId
    • enabled (default true)
    • agentId (optional, binds session to a specific agent for direct chat/task routing)

Supported channel ids (OpenClaw parity):

  • telegram
  • whatsapp
  • discord
  • googlechat
  • slack
  • signal
  • imessage

Runtime behavior highlights:

  • Task report relays are route-pinned to the task's originating messenger target ([messenger-route] audit marker in task logs).
  • Channel spread is prevented for route-pinned task reports.
  • Typing indicators are emitted during direct-chat generation for Telegram/Discord; other channels are no-op.
  • Native direct send runtime exists for all OpenClaw-parity channels (telegram, whatsapp, discord, googlechat, slack, signal, imessage).
  • Per-channel setup requirements differ (e.g., WhatsApp Cloud API token + phone number id, Google Chat webhook URL or key|token, Signal RPC base URL, macOS iMessage runtime).
  • New project creation path in direct-chat escalation is restricted by PROJECT_PATH_ALLOWED_ROOTS.

Core Endpoint Groups

Messenger (Built-in Channels)

MethodPathPurpose
GET/api/messenger/sessionsList runtime messenger sessions resolved from persisted settings
GET/api/messenger/receiver/telegramTelegram webhook/poll receiver status
GET/api/messenger/receiver/discordDiscord polling receiver status
POST/api/messenger/discord/channelsDiscover accessible Discord text channels by Bot token
POST/api/messenger/sendSend message by sessionKey or (channel + targetId)

POST /api/messenger/send request body:

{
  "sessionKey": "telegram:my-session",
  "text": "hello"
}

or

{
  "channel": "discord",
  "targetId": "123456789012345678",
  "text": "hello"
}

Workflow Pack Routing

MethodPathPurpose
GET/api/workflow-packsList workflow packs and effective enable state
PUT/api/workflow-packs/:keyUpdate workflow pack metadata/flags/json fields
POST/api/workflow/routeResolve workflow pack by explicit/session/project/text context

Runtime / Org

MethodPathPurpose
GET/api/departmentsList departments
GET/api/departments/:idGet department detail with member list
POST/api/departmentsCreate department
PATCH/api/departments/:idUpdate department
PATCH/api/departments/reorderReorder departments
GET/api/agentsList agents
GET/api/agents/:idGet agent detail
GET/api/meeting-presenceCurrent kickoff/review meeting seat occupancy
GET/api/agents/activeAgents currently marked working with live session metadata
GET/api/agents/cli-processesDetected CLI processes and task correlation
DELETE/api/agents/cli-processes/:pidKill a detected CLI process by pid
GET/api/cli-statusInstalled CLI provider detection + authentication readiness
POST/api/agentsCreate agent
POST/api/agents/:id/spawnSpawn assigned task execution directly from an agent card
PATCH/api/agents/:idUpdate agent
DELETE/api/agents/:idDelete agent
POST/api/sprites/processSlice/upload sprite sheet preview set and suggest sprite number
POST/api/sprites/registerPersist processed sprite variants under a sprite number
GET/api/statsDashboard/company stats
GET/api/settingsRead settings
PUT/api/settingsSave settings

Tasks / Execution

MethodPathPurpose
GET/api/tasksList tasks (supports filters)
GET/api/tasks/:idTask detail
POST/api/tasksCreate task
PATCH/api/tasks/:idUpdate task
DELETE/api/tasks/:idDelete task
POST/api/tasks/bulk-hideHide or unhide tasks by status group
POST/api/tasks/:id/assignAssign agent
POST/api/tasks/:id/runStart task
POST/api/tasks/:id/stopCancel or pause task
POST/api/tasks/:id/resumeResume paused task
POST/api/tasks/:id/injectQueue sanitized interrupt prompt (paused session)
GET/api/tasks/:id/terminalTask terminal logs
GET/api/tasks/:id/meeting-minutesMeeting minutes
GET/api/tasks/:id/diffGit diff/stat for task worktree branch
POST/api/tasks/:id/mergeManual merge of task worktree into project branch
POST/api/tasks/:id/discardDiscard task worktree and abandon branch changes
GET/api/worktreesActive task worktree registry
GET/api/subtasksList subtasks (active=1 limits to in-flight parent tasks)
POST/api/tasks/:id/subtasksCreate subtask
PATCH/api/subtasks/:idUpdate subtask

GET /api/tasks supports query filters: status, department_id, agent_id, project_id, workflow_pack_key.

Reports / Diagnostics

MethodPathPurpose
GET/api/task-reportsRoot completed-task report list
GET/api/task-reports/:taskIdConsolidated report detail (logs, subtasks, meeting minutes, documents)
POST/api/task-reports/:taskId/archiveRegenerate/archive planning consolidated markdown for a task tree
GET/api/docsSwagger UI for the current OpenAPI contract
GET/api/docs/swagger-bootstrap.jsSwagger bootstrap helper that primes /api/auth/session
GET/api/cli-usageCached CLI quota/usage windows by provider
POST/api/cli-usage/refreshRefresh CLI quota/usage cache and broadcast update

Messaging / Inbox / Decision

MethodPathPurpose
GET/api/messagesMessage history
POST/api/messagesSend message
POST/api/announcementsBroadcast announcement
POST/api/directivesSend directive
DELETE/api/messagesClear messages
POST/api/inboxExternal webhook ingestion
GET/api/decision-inboxDecision inbox items
POST/api/decision-inbox/:id/replyDecision reply

Skills / Providers / OAuth

MethodPathPurpose
GET/api/skillsSkill catalog
GET/api/skills/availableLearned skill inventory available for reuse
GET/api/skills/detailSkill detail
POST/api/skills/learnStart learn job
GET/api/skills/learn/:jobIdLearn job status
GET/api/skills/historyLearn history
POST/api/skills/unlearnUnlearn skill
POST/api/skills/customUpload custom skill
GET/api/skills/customList custom skills
DELETE/api/skills/custom/:skillNameDelete custom skill
GET/api/api-providersList API providers
POST/api/api-providersCreate API provider
PUT/api/api-providers/:idUpdate API provider
DELETE/api/api-providers/:idDelete API provider
POST/api/api-providers/:id/testProbe upstream provider and refresh model cache
GET/api/api-providers/:id/modelsRead cached or refreshed provider model list
GET/api/api-providers/presetsBuilt-in provider preset base URLs/auth conventions
GET/api/oauth/statusOAuth status
POST/api/oauth/disconnectOAuth disconnect
POST/api/oauth/refreshOAuth token refresh
POST/api/oauth/accounts/activateActivate, add, remove, or toggle a stored OAuth account
PUT/api/oauth/accounts/:idUpdate OAuth account metadata and model override
GET/api/oauth/modelsOAuth-backed model catalog (Copilot/OpenCode/Antigravity)
GET/api/cli-modelsLocal CLI model catalog (Claude/Codex/Gemini/OpenCode)

Project / GitHub / Update

MethodPathPurpose
GET/api/projectsList projects
POST/api/projectsCreate project
GET/api/projects/:idProject detail with assigned agents/tasks/reports/review events
PATCH/api/projects/:idUpdate project
DELETE/api/projects/:idDelete project
GET/api/projects/path-checkValidate project path
GET/api/projects/path-suggestionsSuggested paths
GET/api/projects/path-browseBrowse allowed project roots/subdirectories for manual selection
POST/api/projects/path-native-pickerNative path picker
GET/api/projects/:id/branchesLocal git branches for a project path
GET/api/github/statusGitHub integration status
GET/api/github/reposRepositories
GET/api/github/repos/:owner/:repo/branchesRemote GitHub branch list
POST/api/github/cloneClone repository
GET/api/github/clone/:cloneIdClone progress/status polling
GET/api/update-statusUpdate status
GET/api/update-auto-statusAuto-update daemon status and lock state
POST/api/update-auto-configToggle auto update
POST/api/update-applyTrigger update apply flow immediately

Coverage Notes

  • docs/openapi.json now includes the main contributor-facing detail/picker/report endpoints that were missing from the previous baseline.
  • CI E2E should treat the following as regression-sensitive:
    • /api/docs, /api/docs/swagger-bootstrap.js, /api/openapi.json
    • /api/projects/:id, /api/projects/:id/branches, /api/projects/path-browse
    • /api/tasks/bulk-hide, /api/tasks/:id/diff, /api/worktrees
    • /api/meeting-presence, /api/agents/active, /api/agents/cli-processes
    • /api/cli-usage, /api/api-providers/presets, /api/task-reports*

Known Follow-up

  • Promote this baseline to OpenAPI (/api/*.yaml) in incremental slices:
    1. auth/session + settings
    2. tasks/subtasks
    3. inbox/directives
    4. project/github/update routes