Skip to content

Endpoints Overview

System

MethodPathAuthDescription
GET/healthNoneLiveness only — returns {"status":"ok"} (no agent list)
GET/statusAdmin key or dashboard session¹Per-agent stats, legacy/managed sessions, worker pools + heartbeat history
GET/processesAdmin key or dashboard session¹Host process tree for the dashboard
GET/knowledge/graphAdmin key or dashboard session¹Memory-wiki as { nodes, edges, demo, scope } for the dashboard Knowledge base tab. ?scope=shared (default) = the cross-agent Shared KB; ?scope=agent:<id> = that agent's Lane-2 memory (workspace/memory/*.md, id validated against the known-agents allowlist). Computed on-demand (independent of gateway.knowledge.shared.graph and the nightly reindex). Shared scope serves a labelled demo (demo:true) when empty; ?demo=off returns the real model; ?demo=<N> a synthetic N-node graph for scale testing
GET/knowledge/sourcesAdmin key or dashboard session¹Graph sources for the KB tab's selector: { sources: [{ id, label, count }] } — the Shared KB plus every agent with ≥1 Lane-2 memory note
GET/knowledge/noteAdmin key or dashboard session¹Full Markdown body of one note for the KB tab's detail section: { id, scope, path, updated, body } (frontmatter stripped, ≤20 KB; path = gateway-root-relative location, updated = ISO last-modified). ?scope=shared|agent:<id> selects the vault (same allowlist guard as /knowledge/graph); ?id=<relPath>.md must be a .md path that resolves inside that vault (no traversal)
GET/knowledge/dreamsAdmin key or dashboard session¹Nightly-dreaming audit trail for the Nightly dreaming tab: { runs, agents }, newest-first, parsed from each agent's .dreaming/DREAMS.md + promotions.jsonl (+ accepted.jsonl). Each proposal carries an index (accept target) and an accepted flag. Bounded (≤200 runs; proposal content truncated)
POST/knowledge/dreams/applyAdmin key or dashboard session¹Manually accept propose-mode proposals: applies the selected ops to the agent's MEMORY.md/USER.md via the same K4 safe applier as auto mode (backup + bounded-loss + net-negative + CAS + never-empty; memory-only ⇒ no restart), records them to .dreaming/accepted.jsonl (idempotent), and promotes applied adds to the shared vault when it is auto. Body: { agentId, ts, indexes?[] } (omit indexes ⇒ whole run). Returns { applied, skipped, alreadyAccepted, requested, backups }. 404 unknown agent / no matching run, 400 bad ts/indexes
GET/dashboardSession cookie¹Web UI dashboard (Sessions + Knowledge base + Nightly dreaming tabs; serves the login page when unauthenticated)
POST/dashboard/loginNone (validates an admin key)Exchange an admin API key for an HttpOnly; SameSite=Lax dash_session cookie (8h). Brute-force throttled per IP (429 after 10 failed attempts / 5 min)
POST/dashboard/logoutSession cookieRevoke the dashboard session and clear the cookie
GET/api/v1/commandsNoneList slash commands available in the chat UI
GET/api/v1/_meta/routesAPI keyRoute manifest (every defineRoute-registered endpoint, incl. its CLI noun/verb mapping) — source for the claude-gateway CLI's codegen and doctor cross-check

¹ Auth applies when gateway.api.keys is configured, and requires an admin key (admin: true). The dashboard/monitoring surface grants cross-agent, host-wide power (session list, process tree, and PTY keystroke injection into any session), so it intentionally requires more than a scoped or write key. "Admin key or dashboard session" accepts an admin API key (X-Api-Key / Authorization: Bearer) or the dash_session cookie issued by POST /dashboard/login (which is itself only issued to an admin key). A valid but non-admin key is rejected (401). With no keys configured the behavior depends on the bind: on a loopback bind (127.0.0.1) they stay open (a keyless local install has no credential to check); on a non-loopback bind (0.0.0.0 or a real IP) they fail closed/status, /processes, and /dashboard return 503 until gateway.api.keys is set, so the surface is never exposed unauthenticated to the network. If keys are configured but none is admin, the dashboard is inaccessible (login returns 401) and a startup warning is emitted. /health stays public in all cases.

Terminal viewer (/cli)

See Terminal viewer (/cli).

Agent API

MethodPathAuthDescription
GET/api/v1/agentsKeyList agents accessible by the provided key
POST/api/v1/agentsAdminCreate a new agent
PATCH/api/v1/agents/:agentIdWriteUpdate agent name, description, model, or allow_tools (connectors needs Admin)
DELETE/api/v1/agents/:agentIdAdminDelete an agent
POST/api/v1/agents/:agentId/messagesKeySend a message — sync JSON or SSE stream; supports slash commands
POST/api/v1/agents/:agentId/greetingWriteStream a proactive welcome from GREETING.md into an existing session (SSE); returns 204 if file absent
GET/api/v1/modelsKeyList available models — live catalog when configured, gateway.models otherwise
PUT/api/v1/agents/:agentId/modelAdminSet the active model for an agent

Orchestration and voice

See activity polling, scoped task dispatch, voice WebSocket protocol and dashboard fields.

Session Management API

Session management operations require chat_id (query param for GET/DELETE, body for POST/PATCH). The resumable stream and orchestration activity/task routes instead use their documented session and principal checks. Sessions are stored at sessions/api-{chat_id}/ — symmetric with telegram-{id} and discord-{id}.

MethodPathAuthDescription
GET/api/v1/agents/:agentId/sessionsKeyList API sessions for a chat_id
POST/api/v1/agents/:agentId/sessionsKeyCreate a new API session (auto-names from prompt)
GET/api/v1/agents/:agentId/sessions/:sessionId/infoKeyGet session info (name, message count, context %)
GET/api/v1/agents/:agentId/sessions/:sessionId/streamKeyRe-attach to the session's in-flight turn (SSE, resumable from a seq cursor)
PATCH/api/v1/agents/:agentId/sessions/:sessionIdKeyRename a session
DELETE/api/v1/agents/:agentId/sessions/:sessionIdKeyDelete a session
POST/api/v1/agents/:agentId/sessions/:sessionId/clearKeyClear session history
POST/api/v1/agents/:agentId/sessions/:sessionId/compactKeySummarise old history, keep only recent messages
POST/api/v1/agents/:agentId/sessions/:sessionId/stopKeyInterrupt the in-flight turn
POST/api/v1/agents/:agentId/sessions/:sessionId/restartKeyGraceful session restart
POST/api/v1/agents/:agentId/sessions/:sessionId/attachmentsKeyRegister file paths as attachments for the current turn (called internally by api_reply MCP tool)

Workspace File API

MethodPathAuthDescription
GET/api/v1/agents/:agentId/files/:filenameKeyRead a workspace file
PUT/api/v1/agents/:agentId/files/:filenameWriteWrite a workspace file

Telegram Channel API

MethodPathAuthDescription
GET/api/v1/agents/:agentId/telegram/pendingAdminList pending pairing requests (DM + group knocks)
POST/api/v1/agents/:agentId/telegram/approveAdminApprove a pending pairing by code (kind-aware)
POST/api/v1/agents/:agentId/telegram/denyAdminDeny a pending pairing by code
PATCH/api/v1/agents/:agentId/telegram/policyAdminUpdate DM policy, pairing toggle, group policy and/or mention gate
GET/api/v1/agents/:agentId/telegram/allowlistAdminList allowlisted users
DELETE/api/v1/agents/:agentId/telegram/allow/:userIdAdminRemove a user from the allowlist
GET/api/v1/agents/:agentId/telegram/group/allowlistAdminList allowlisted group ids
DELETE/api/v1/agents/:agentId/telegram/group/allow/:groupIdAdminRemove a group from the group allowlist

Discord Channel API

MethodPathAuthDescription
GET/api/v1/agents/:agentId/discord/pendingAdminList pending pairing requests (DM + guild knocks)
POST/api/v1/agents/:agentId/discord/approveAdminApprove a pending pairing by code (kind-aware)
POST/api/v1/agents/:agentId/discord/denyAdminDeny a pending pairing by code
PATCH/api/v1/agents/:agentId/discord/policyAdminUpdate DM policy, pairing toggle, guild policy and/or mention gate
GET/api/v1/agents/:agentId/discord/allowlistAdminList allowlisted users
DELETE/api/v1/agents/:agentId/discord/allow/:userIdAdminRemove a user from the allowlist
GET/api/v1/agents/:agentId/discord/guild/allowlistAdminList allowlisted guild ids
DELETE/api/v1/agents/:agentId/discord/guild/allow/:guildIdAdminRemove a guild from the guild allowlist

Public Webhook Ingress

MethodPathAuthDescription
GET/webhooks/:appNone (self-authenticating)Provider URL-verification probe
GET/webhooks/:app/:agentIdNone (self-authenticating)Provider URL-verification probe, agent-scoped
POST/webhooks/:appNone (self-authenticating)Inbound webhook delivery — first agent with :app configured
POST/webhooks/:app/:agentIdNone (self-authenticating)Inbound webhook delivery — specific agent

Skill API

MethodPathAuthDescription
GET/api/v1/agents/:agentId/skillsKeyList all skills (workspace + module + shared)
GET/api/v1/agents/:agentId/skills/:nameKeyGet a single skill's content
POST/api/v1/agents/:agentId/skillsWriteCreate a new skill
POST/api/v1/agents/:agentId/skills/installAdminInstall a skill from a GitHub/raw URL
DELETE/api/v1/agents/:agentId/skills/:nameWriteDelete a skill
GET/api/v1/agents/:agentId/skill-metricsKeySkill self-improvement effectiveness rollup
GET/api/v1/agents/:agentId/memory-metricsKeyTwo-lane memory metrics: budget hygiene, archive/shared coverage, dreaming ledger, session-drop invariant

App Store API

MethodPathAuthDescription
GET/api/v1/apps/registryKeyFetch community registry (5-min cached)
GET/api/v1/apps/registry/:nameKeyGet versions of a registry app
GET/api/v1/appsKeyList installed apps
POST/api/v1/apps/installAdminStart async install → jobId
POST/api/v1/apps/inspectAdminRead-only preview of a source → required/generated secrets (no install)
GET/api/v1/apps/jobs/:jobIdKeyPoll install/update job status + logs
GET/api/v1/apps/:nameKeyGet installed app info
DELETE/api/v1/apps/:nameAdminUninstall app
POST/api/v1/apps/:name/startAdminStart stopped app
POST/api/v1/apps/:name/stopAdminStop running app
POST/api/v1/apps/:name/restartAdminRestart app
GET/api/v1/apps/:name/versionKeyCheck installed vs latest version
POST/api/v1/apps/:name/updateAdminStart async update with rollback → jobId
POST/api/v1/apps/:name/reconfigureAdminStart async env/host-port reconfigure (keeps volumes) → jobId
POST/api/v1/apps/housekeepingAdminDocker build-cache & orphan reclaim report (mode:"report") or safe prune (mode:"prune")
POST/api/v1/apps/:name/backupAdminStart async snapshot of volumes, bind-mount data dirs & config → jobId
POST/api/v1/apps/:name/restoreAdminRestore volumes, bind-mount data dirs & config from a backup → jobId
GET/api/v1/apps/:name/backupsKeyList backups (newest first)
DELETE/api/v1/apps/:name/backups/:idAdminDelete one backup
GET/app/:name/:portName/*NoneReverse proxy to installed app

Backup retention (gateway.appBackup): backups are pruned by the union of a count cap and an age cap — a backup is removed when it exceeds retention (keep N newest per app, default 3, 0 = unbounded) or is older than maxAgeDays (default 30, 0 = disabled). Pruning runs after each successful backup and once per day via a scheduler at cleanupHour (0-23, default 0) in cleanupTimezone (IANA, default "UTC", falling back to gateway.timezone when unset or invalid).

Boot restore (gateway.appRestore): at startup every app stored as running is brought back up in the background. When an image the app needs is missing from the local daemon, the restore first runs docker compose pull --ignore-buildable and docker compose build, each under buildTimeoutMs (default 1800000, 30 min); it then runs docker compose up -d --wait under waitTimeoutMs (default 180000, 3 min). The two budgets are separate because a timeout SIGKILLs the compose CLI, and while that only abandons the healthcheck wait once images exist, it cancels an in-progress build — so a cold host with no image cache must not have its rebuild bounded by the short wait budget. When the images are already present both cold-start steps are skipped entirely, so a warm reboot is unaffected. Any non-numeric, non-finite or non-positive value falls back to the default. See restoreError under GET /api/v1/apps.

Connectors API

MethodPathAuthDescription
GET/api/v1/connectorsKeyList every connector with its connected state
GET/api/v1/connectors/:id/statusKeyConnected boolean for a single connector (for polling)
POST/api/v1/connectors/:id/connectAdminStore a pasted token
POST/api/v1/connectors/:id/oauth/receiveAdminAccept an access_token + connector shape pushed by an external control plane
DELETE/api/v1/connectors/:idAdminDisconnect — clears the credential; removes the whole entry for none/external connectors
POST/api/v1/connectors/customAdminAdd a user-pasted connector
POST/api/v1/connectors/custom/:id/oauth/startAdminBegin the gateway-owned OAuth 2.1 + PKCE sign-in → authorizeUrl
GET/oauth/mcp/callbackNone (single-use state)OAuth redirect target — the provider sends the end user's own browser here

Cron API

MethodPathAuthDescription
GET/api/v1/cronsKeyList jobs (filtered to key's accessible agents)
GET/api/v1/crons/statusKeyScheduler status (total, enabled, running)
POST/api/v1/cronsKeyCreate a new job
GET/api/v1/crons/:idKeyGet a single job
PUT/api/v1/crons/:idKeyUpdate a job
DELETE/api/v1/crons/:idKeyDelete a job
POST/api/v1/crons/:id/runKeyTrigger a job manually
GET/api/v1/crons/:id/runsKeyGet run history (last 20 by default)

Chat History API

MethodPathAuthDescription
GET/api/v1/agents/sessionsAdminList all sessions across all agents (nested by agent)
GET/api/v1/agents/:agentId/chatsKeyList all chats for an agent
GET/api/v1/agents/:agentId/chats/:chatId/sessionsKeyList sessions for a specific chat
GET/api/v1/agents/:agentId/chats/:chatId/messagesKeyPaginated message history (cursor-based)
GET/api/v1/agents/:agentId/chats/:chatId/messages/searchKeyFull-text search across messages (SQLite FTS5)
GET/api/v1/agents/:agentId/chats/:chatId/messages/active-daysKeyDistinct local calendar days with >= 1 message in a window (jump-to-date dots)
POST/api/v1/agents/:agentId/chats/:chatId/sessions/:sessionId/messagesKeyInject a message into an existing channel session (SSE stream)

Media API

MethodPathAuthDescription
POST/api/v1/agents/:agentId/mediaKeyUpload a media file (image/* or PDF) — returns mediaPath
GET/api/v1/agents/:agentId/media/*KeyServe a media file by path

File Share Bridge API

See File Share Bridge API.

PTY Shell API

See PTY Shell API.

Claude Code inside.