Skip to content

HTTP routes

Every route below is served on PITOT_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.

The table includes every route the binary can register. These routes depend on configuration:

  • /debug/pprof/*: only when PITOT_PPROF_ENABLED is true, which is not the default. Enabling it also turns on mutex and block sampling.
  • /mcp, /api/mcp, /api/auth/oauth/*, /oauth/* and /.well-known/*: only when PITOT_MCP_ENABLED is true, which is the default.
  • /api/agent/*: only when PITOT_AI_PROVIDER selects anthropic or openai, with that provider’s required key. An empty provider disables chat.
  • /api/auth/oidc/start and /api/auth/oidc/callback: only in PITOT_AUTH_MODE=oidc. They return 503 unavailable with Retry-After until provider discovery succeeds.

Everything else is always registered. A path shown with :name or * is the pattern Echo matches on, not a literal URL.

The /api/* routes serve the browser client and can change without migration paths. MCP is the agent interface. OTLP ingest and operational endpoints have their own contracts.

Manage alert rules on the Alerts page or through the HTTP API. Administrators manage ingest tokens on Connect telemetry or with /api/settings/ingest/tokens.

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:

StatusCode
400bad_request
401unauthorized
403forbidden
404not_found
405method_not_allowed
409conflict
413payload_too_large
415unsupported_media_type
422unprocessable
429rate_limited
500internal
502bad_gateway
503unavailable
504timeout

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. GET /api/telemetry/schema returns 503 schema_busy with Retry-After when a new window and namespace cannot start a discovery yet, or when the discovery is still running after 15 seconds; it keeps running, so a retry finds it cached. Cached ones are always served. An unknown window is 400 bad_request. 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.

Roles maps capabilities to roles.

MethodPathRequires
GET/none
GET/*none
GET/.well-known/oauth-authorization-serverprotocol handshake
GET/.well-known/oauth-protected-resourceprotocol handshake
GET/.well-known/oauth-protected-resource/mcpprotocol handshake
POST/api/agent/runsagent:run
GET/api/agent/threadsagent:run
DELETE/api/agent/threads/:idagent:run
GET/api/agent/threads/:idagent:run
PATCH/api/agent/threads/:idagent:run
GET/api/alerting/alertstelemetry:read
GET/api/alerting/emailtelemetry:read
GET/api/alerting/rulestelemetry:read
POST/api/alerting/rulesalerts:manage
DELETE/api/alerting/rules/:idalerts:manage
PUT/api/alerting/rules/:idalerts:manage
POST/api/alerting/rules/:id/testalerts:manage
GET/api/alerting/summarytelemetry:read
POST/api/annotations/querytelemetry:read
POST/api/auth/code/sendnone
POST/api/auth/code/verifynone
POST/api/auth/link/verifynone
POST/api/auth/logoutany signed-in user
GET/api/auth/meany signed-in user
GET/api/auth/oauth/authorizeany signed-in user
POST/api/auth/oauth/authorizeany signed-in user
GET/api/auth/oauth/connectionsany signed-in user
POST/api/auth/oauth/connections/:id/revokeany signed-in user
GET/api/auth/oidc/callbacknone
GET/api/auth/oidc/startnone
POST/api/auth/setupnone
GET/api/auth/statusnone
GET/api/dashboardsdashboards:manage-own
POST/api/dashboardsdashboards:manage-own
DELETE/api/dashboards/:iddashboards:manage-own
GET/api/dashboards/:iddashboards:manage-own
PATCH/api/dashboards/:iddashboards:manage-own
PUT/api/dashboards/:iddashboards:manage-own
GET/api/dashboards/:id/versionsdashboards:manage-own
GET/api/dashboards/:id/versions/:versiondashboards:manage-own
POST/api/dashboards/:id/versions/:version/restoredashboards:manage-own
POST/api/fanql/completetelemetry:read
POST/api/fanql/formattelemetry:read
POST/api/fanql/parsetelemetry:read
GET/api/fanql/referencetelemetry:read
GET/api/insightstelemetry:read
Any/api/mcptelemetry:read
POST/api/queries/exemplarstelemetry:read
POST/api/queries/runtelemetry:read
POST/api/queries/variables/resolvetelemetry:read
GET/api/settings/ingestingest:read-metadata
GET/api/settings/ingest/tokensingest:manage
POST/api/settings/ingest/tokensingest:manage
POST/api/settings/ingest/tokens/:id/revokeingest:manage
GET/api/telemetry/schematelemetry:read
GET/api/traces/:idtelemetry:read
GET/api/usersusers:manage
POST/api/usersusers:manage
DELETE/api/users/:idusers:manage
PATCH/api/users/:idusers:manage
POST/api/users/:id/access/revokeusers:manage
PATCH/api/users/:id/roleusers:manage
PATCH/api/users/:id/statususers:manage
GET/debug/pprof/operations:read
GET/debug/pprof/:nameoperations:read
GET/debug/pprof/cmdlineoperations:read
GET/debug/pprof/profileoperations:read
GET/debug/pprof/symboloperations:read
GET/debug/pprof/traceoperations:read
GET/healthznone
Any/mcpprotocol handshake
GET/metricsoperations:read, or a service credential
POST/oauth/registerprotocol handshake
POST/oauth/tokenprotocol handshake
GET/readyznone
GET/scim/v2/UsersSCIM bearer token, when PITOT_SCIM_TOKEN is set
POST/scim/v2/UsersSCIM bearer token, when PITOT_SCIM_TOKEN is set
GET/scim/v2/Users/:idSCIM bearer token, when PITOT_SCIM_TOKEN is set
PATCH/scim/v2/Users/:idSCIM bearer token, when PITOT_SCIM_TOKEN is set
  • none: reachable without a credential.
  • 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.

Any registers every HTTP method with the same authorization requirement. GET /* serves the single-page application for browser paths. Unknown /api/* and OTLP paths return errors.

OTLP admission counts protobuf spans, log records or metric points before converting them into storage rows. Under compaction debt, interactive starvation (refusals or queue-wait timeouts), or the decoded-byte budget, the entire export is refused retryably. Panel queueing alone does not trigger ingest throttling. gRPC responds with RESOURCE_EXHAUSTED and google.rpc.RetryInfo; HTTP responds with 429 and Retry-After in whole seconds rounded up. The message identifies the pressure reason. Rate refusals request a one-to-five-second delay; the hard debt limit requests two seconds. Byte-budget refusals retain their existing retry delay. Enable exporter retries and honor these delays; clients with retries disabled can drop refused telemetry. An acknowledgement still means the accepted export was durably published.

Exemplars and trace detail use a priority read lane with reserved capacity. Panels and interactive reads have separate bounded queues; a refused read retains the existing 503 busy response with Retry-After.