HTTP routes
Every route below is served on FANOUT_ADDR (127.0.0.1:7520 by default;
the image sets :7520).
OTLP shares this listener but uses its own handlers and ingest credential; see
send your first telemetry.
Errors
Section titled “Errors”Application API errors, including unknown routes and wrong methods, return objects shaped like
{"code":"bad_request","message":"Safe explanation"}. Codes are stable
snake_case identifiers; clients branch on code rather than message text.
Invalid dashboard or panel specs also include problems with field paths,
messages and optional hints. Every error response uses Cache-Control: no-store;
HEAD errors have no body. Server failures return a short, safe message; the
underlying error is logged and never returned.
Default codes by HTTP status:
| Status | Code |
|---|---|
| 400 | bad_request |
| 401 | unauthorized |
| 403 | forbidden |
| 404 | not_found |
| 405 | method_not_allowed |
| 409 | conflict |
| 413 | payload_too_large |
| 415 | unsupported_media_type |
| 422 | unprocessable |
| 429 | rate_limited |
| 500 | internal |
| 502 | bad_gateway |
| 503 | unavailable |
| 504 | timeout |
Other 4xx statuses use bad_request; other 5xx statuses use internal.
Specific conditions use already_current, dashboard_version_not_found,
dashboard_version_conflict, invalid_spec and last_active_administrator.
Tool failures carry error: {code, message} inside the tool result.
Panel execution results keep their own status and error fields.
OAuth, OTLP/gRPC, MCP JSON-RPC and AG-UI run errors keep their protocol spelling.
Operational responses at /healthz, /readyz and /metrics keep their bodies.
The Requires column is not a description of the rule. It is the answer the authorization middleware gives for that exact method and path, so a route cannot be documented as public while the server treats it otherwise. Capabilities map to roles in roles.
| Method | Path | Requires |
|---|---|---|
GET | / | none |
GET | /* | none |
GET | /.well-known/oauth-authorization-server | protocol handshake |
GET | /.well-known/oauth-protected-resource | protocol handshake |
GET | /.well-known/oauth-protected-resource/mcp | protocol handshake |
POST | /api/agent/runs | agent:run |
GET | /api/agent/threads | agent:run |
DELETE | /api/agent/threads/:id | agent:run |
GET | /api/agent/threads/:id | agent:run |
PATCH | /api/agent/threads/:id | agent:run |
GET | /api/alerting/rules | telemetry:read |
POST | /api/alerting/rules | alerts:manage |
DELETE | /api/alerting/rules/:id | alerts:manage |
PUT | /api/alerting/rules/:id | alerts:manage |
POST | /api/alerting/rules/:id/test | alerts:manage |
GET | /api/alerts | telemetry:read |
GET | /api/alerts/summary | telemetry:read |
POST | /api/annotations | telemetry:read |
POST | /api/auth/code/send | none |
POST | /api/auth/code/verify | none |
POST | /api/auth/link/verify | none |
POST | /api/auth/logout | any signed-in user |
GET | /api/auth/me | any signed-in user |
GET | /api/auth/oauth/authorize | any signed-in user |
POST | /api/auth/oauth/authorize | any signed-in user |
GET | /api/auth/oidc/callback | none |
GET | /api/auth/oidc/start | none |
POST | /api/auth/setup | none |
GET | /api/auth/status | none |
GET | /api/dashboards | dashboards:manage-own |
POST | /api/dashboards | dashboards:manage-own |
DELETE | /api/dashboards/:id | dashboards:manage-own |
GET | /api/dashboards/:id | dashboards:manage-own |
PATCH | /api/dashboards/:id | dashboards:manage-own |
PUT | /api/dashboards/:id | dashboards:manage-own |
GET | /api/dashboards/:id/versions | dashboards:manage-own |
GET | /api/dashboards/:id/versions/:version | dashboards:manage-own |
POST | /api/dashboards/:id/versions/:version/restore | dashboards:manage-own |
GET | /api/intelligence | telemetry:read |
Any | /api/mcp | telemetry:read |
POST | /api/panels/exemplars | telemetry:read |
POST | /api/panels/query | telemetry:read |
POST | /api/panels/variables/resolve | telemetry:read |
GET | /api/settings/ingest | ingest:read-metadata |
POST | /api/settings/ingest/token/rotate | ingest:manage |
GET | /api/telemetry/schema | telemetry:read |
GET | /api/traces/:id | telemetry:read |
GET | /api/users | users:manage |
POST | /api/users | users:manage |
DELETE | /api/users/:id | users:manage |
PATCH | /api/users/:id | users:manage |
POST | /api/users/:id/access/revoke | users:manage |
PATCH | /api/users/:id/role | users:manage |
PATCH | /api/users/:id/status | users:manage |
GET | /debug/pprof/ | operations:read |
GET | /debug/pprof/:name | operations:read |
GET | /debug/pprof/cmdline | operations:read |
GET | /debug/pprof/profile | operations:read |
GET | /debug/pprof/symbol | operations:read |
GET | /debug/pprof/trace | operations:read |
GET | /healthz | none |
Any | /mcp | protocol handshake |
GET | /metrics | operations:read, or a service credential |
POST | /oauth/register | protocol handshake |
POST | /oauth/token | protocol handshake |
GET | /readyz | none |
What the requirements mean
Section titled “What the requirements mean”- none — reachable without a credential. The health endpoints are deliberately here: a probe that needs a credential fails for the wrong reason during an outage.
- any signed-in user — a session, but no particular capability.
- protocol handshake — the OAuth and MCP endpoints, which authenticate as part of their own protocol rather than through the middleware.
- a named capability — the caller’s role must carry it.
- or a service credential — additionally reachable without a browser session, which is how a scraper reaches the metrics endpoint.
A method of Any means the route is registered for every verb, and the middleware
gives the same answer for all of them — where it would not, this page fails
to build rather than pick one. GET /* serves the single-page application
for browser paths. Unknown /api/* and OTLP paths return errors instead.