Skip to content

Reference: dashboard routes

Every route below sits behind the dashboard's one identity gate unless noted. Which credential it checks is the dashboard.auth strategy in config.yaml: access — a Cloudflare Access browser session or, for machine callers, a service token (the default when ACCESS_TEAM_DOMAIN and ACCESS_AUD are set); token — an Authorization: Bearer header holding the secret in DASHBOARD_TOKEN (or the env var dashboard.token.env names), which resolves to the one actor dashboard.token.actor names; or none — no credential, served only to loopback callers of a localhost deployment and refused everywhere else (the default without Access). None of them set caching headers that would let a proxy or browser cache a response beyond the request that made it (no-store throughout) — every load is live.

The header lists only the surfaces this installation has: Residents appears when resident environments are configured (execution.resident), Costs when costs is configured with its analytics token, the Scheduled tab when schedules.worker records firings. The docs link is always there: it opens the project's published site. The routes themselves still answer without their subsystem — with a 503 naming the config that turns them on.

RouteShowsNotes
GET /runsActive runs, newest firstDefault view excludes finished runs; each row's link carries that run's capability token — the index itself is gated specifically because of this
GET /runs?all=1Active and finished runsOnly meaningful with runHistory configured — otherwise there's nothing finished to show
GET /runs/<id>One run: request → steps (tool calls, results) → answerLive via SSE while the run is active; served as a static page, no token needed, once it's in history
GET /runs/<id>/eventsRaw SSE event stream for that runWhat the run page itself consumes; resumable via Last-Event-ID
GET /runs/<id>/frictionWhy a finished run was slow, if it wasRead-only diagnosis, no side effects
POST /runs/<id>/stop?mode=soft|hardStops a live run; soft lets it wrap up and answer, hard aborts in-flight
GET /residentsEvery onboarded repo, its lifecycle state, and its disk gauge (used/total)The dashboard twin of repo list
GET /residents/<owner>/<name>One repo's resident: mirror status, warm checkout, active thread worktrees, and its disk — used/total, free, the reserve it keeps back, headroom in "more trees", and every component (mirror, deps, checkout, each thread tree, leftover caches)The same numbers the resident's attach admission decides on — see onboard a repo → Disk
GET /costsDaily spend across every configured groupPriced live from Cloudflare + (optionally) Anthropic billing data, nothing cached
GET /costs/<group>Spend for one group
GET /costs/<group>.jsonSame data, machine-readableFor scripting/alerting, not for embedding a live dashboard elsewhere
GET /mcp/connect/<nonce>The one-time MCP credential-paste formBound to whoever mints it or first opens it; single use, expires in 10 minutes
GET /healthz{ok, inFlight, draining, catchUp}Not gated — this is the process health probe, meant to be hit by the deploy tooling and the container platform

Command routes (/api/<group>.<verb>)

Every registered command has an HTTP twin behind the same dashboard gate, plus an MCP tool of the same name — one definition, every surface (explanation). A write is POST-only; a read takes either verb (GET with a kebab-case query string, POST with a camelCase JSON body). The Scope column is what an operator identity or service token must hold.

RouteMethodsActionWhat it does
/api/help.showGET, POSThelp:readWhat Switchboard can do: agents, per-request directives, and every chat command.
/api/status.showGET, POSTstatus:readWhich build this process runs: version, commit, when it was built and started, runs in flight, draining.
/api/config.showGET, POSTconfig:readThe effective agent/model/effort for you in this channel, the defaults, both scopes, and what is restricted.
/api/config.setPOSTconfig:writeSet the agent, model, or effort for a channel (gated) or for yourself; per-agent forms take --models.<agent> / --efforts.<agent>.
/api/config.clearPOSTconfig:writeDrop every runtime override of a channel (gated) or of yourself; static config.yaml values show through again.
/api/config.instructionsPOSTconfig:writeCustom instructions for a channel (gated) or for yourself — advisory prompt content that never changes agent, model, or permissions.
/api/runs.listGET, POSTruns:readList runs (live and persisted, newest first) — metadata only, never message text.
/api/runs.getGET, POSTruns:readOne run's record; --include messages adds its events with free text wrapped as untrusted content.
/api/runs.eventsGET, POSTruns:readA page of one run's events after --after-seq (server-capped); free text wrapped as untrusted content.
/api/runs.frictionGET, POSTruns:readOne run's friction diagnosis (live: computed now; persisted: as stored).
/api/runs.stopPOSTruns:writeRequest a live run to stop (--mode soft = finish the current step; hard = abort now). Records the caller as the actor.
/api/review.abridgePOSTreview:writeAbridge a finished PR review's reading diff with meat.dev on the bot host (one Opus-class call) and store it on the run; idempotent — a stored one is answered, not recomputed.
/api/friction.reportGET, POSTfriction:readRanked recurring friction patterns across recent runs — read-only, GitHub never consulted.
/api/friction.proposePOSTfriction:writeRun the self-improvement step: cluster recent friction, dedupe against open issues, file the top proposals as labeled issues.
/api/repo.listGET, POSTrepo:readEvery onboarded resident repo with its live state, ref, sha, last refresh, and disk gauge.
/api/repo.onboardPOSTrepo:writeOnboard a repo as an always-warm resident environment (provisions billable compute; admin-gated).
/api/repo.offboardPOSTrepo:writeTear down a resident repo: registry record, schedules, container, R2 snapshots (admin-gated; --dry-run plans only).
/api/repo.reconfigurePOSTrepo:writeChange a resident's default branch and/or command table (admin-gated; takes effect on the next refresh/attach).
/api/repo.rebuildPOSTrepo:writeDiscard a resident's snapshot and reprovision it from scratch (admin-gated; --dry-run plans only).
/api/repo.testPOSTrepo:execRun the repo's onboarded test command with zero model turns (needs coding-agent access; the ref must be a plausible branch).
/api/repo.buildPOSTrepo:execRun the repo's onboarded build command with zero model turns (needs coding-agent access; the ref must be a plausible branch).
/api/memory.listGET, POSTmemory:readYour own memory records and the shared org / repo / channel records, with ids — what influences your runs.
/api/memory.forgetPOSTmemory:writeSoft-delete one memory record so it no longer influences any run (yours freely; shared org/repo/channel records need repo-management rights).
/api/mcp.listGET, POSTmcp:readExternal MCP servers your runs in this channel can use — org-wide, this channel's, and your own — with state and agents; never a credential.
/api/mcp.addPOSTmcp:writeRegister an external MCP server for yourself, this channel, or the org — auth is detected from the server; sign-in or a token happens on a one-time link, never in chat.
/api/mcp.connectPOSTmcp:writeA fresh one-time link to sign in to an OAuth server or enter (or replace) a bearer server's token — only you can complete it; it expires in 10 minutes.
/api/mcp.showGET, POSTmcp:readOne MCP server's entry plus a live probe of the tools it offers (names, read-only flags); never a credential.
/api/mcp.removePOSTmcp:writeRemove an MCP server you added and its stored credential (yours freely; channel ones need channel-config rights, org-wide ones admin rights).
/api/schedule.listGET, POSTschedule:readEvery scheduled job (cron, UTC), which Worker fires it, its next firing, and what its last firing did.
/api/deploy.planGET, POSTdeploy:readThe production deploy plan: checks, Worker order, preflight handling — computed, nothing executed. With --affected, also which Workers this tree actually needs deployed and why.

Screenshots

Residents index — every onboarded repo, its state, last activity:

Residents index

Resident detail — one repo's mirror, warm checkout, and per-thread worktrees:

Resident detail

What's not on the dashboard yet

There is no /mcp listing page — mcp list in chat/CLI/HTTP is the current data contract for "what's connected." The frontend (web/) is a Vue 3 app served entirely from a JSON seed embedded in the page (no client-side data fetching to a separate API for the initial render), which is why every route above renders instantly with no loading spinner for its first paint.