Skip to main content
The control plane listens on RELAY_CONTROL_PORT (default 8081), separate from the inference port. It serves the control API under /api and the admin UI on the same origin.
API routes are mounted under /api (for example GET /api/providers) so they do not shadow the admin UI’s own routes (/models, /policies, …): a hard reload of /models returns the UI, not JSON. Any path not claimed by the API falls through to the UI, except under /api, where an unknown path answers a JSON 404. Set RELAY_UI_DISABLE=1 to serve the API without the UI.
A few paths sit at the listener root instead: The generated OpenAPI document at GET /api/openapi.json is the complete, typed list of operations, with request and response schemas; GET /api/docs renders it. This page groups the routes and links the page that explains each area.

Authentication

Public, with no credentials: GET /api/version, GET /api/healthz, GET /api/livez, POST /api/auth/login, the OIDC sign-in routes, GET /api/schemas/* and /config.json. Every other route requires a session or the admin token and is authorized per action; under RELAY_AUTHZ=rbac the caller’s role bindings decide. See Authentication. Control-plane actions are recorded in the audit log, which describes what is recorded.

Resource CRUD

Every kind shares one shape:
List endpoints accept q (free text), sort, limit, offset, label=key=value (repeatable), and per-kind field filters; an unknown filter answers 400. The OpenAPI document lists each kind’s filters. Every read returns metadata.resourceVersion, an opaque string that changes on every write to the row. Send it back unchanged in the PUT body to make the update conditional: if the row changed since you read it, the PUT fails with 409 and the code stale_resource_version, and nothing is written. A PUT without resourceVersion replaces the row unconditionally. Every write is applied to each pod’s in-memory catalog within about a second; no reload is needed. Edits and deletes of catalog-owned rows are governed by the governance:* settings; see Settings.

References and detach

Available for providers, hosts, models, pricings, policies, host-keys, rate-limits, teams, projects, service-accounts, groups and roles. Detach deletes nothing.

Host keys

A PUT cannot change a host key’s value; rotation is explicit. An env-referenced key is rotated by changing the variable, and the rotate call answers 400. See Key pooling for breaker states and Stored secrets for how stored values are sealed.

Relay keys

spec.principal is required. Optional fields: policyId, expiresAt, enabled, passthroughAllowed (proxy mode) and payloadLoggingEnabled. Relay stores only a hash of the plaintext; save it on receipt, it cannot be read again. A PUT never changes the key’s value, hash or principal.

Policies

Model overlays

See Overlays.

Catalog views

Read-only projections for building UIs and checking a configuration:
Compare /api/debug/snapshot with the list endpoints when a row does not seem to reach inference.

Settings

Sections with their own route: inference, parsing, proxy-mode, usage-logging, payload-logging, otlp-receiver, audit, catalog-source, auth:oidc, auth:scim, auth:tokens, governance:provider, governance:host, governance:model, governance:policy. license is listed by GET /api/settings but has no route of its own: it is written with PUT /api/license. A PUT replaces the whole section, except the auth:tokens signing-key references, which only rotation changes; changes apply without a restart. Writing usage-logging, payload-logging, audit, auth:oidc, auth:scim or auth:tokens takes an admin. See Settings for each section’s fields.

GitOps

See GitOps.

Sign-in, tokens and the master key

Who may revoke which token, and how revocation reaches inference, is on Authentication. Sign-in with an identity provider is on SSO.

Users, access review and audit

User endpoints authorize at the global scope. Disabling a user signs them out on their next request, refuses their login with 401 account_disabled, and revokes their inference tokens; re-enabling does not bring the tokens back. The access review answers 501 under RELAY_AUTHZ=single. See Checking access and Audit log.

SCIM clients

See SCIM.

Secret keys

Admin only. No response carries key bytes. See Stored secrets and key rotation for the refusals each call can answer.

License

See License.

Usage and request logs

Filters, grouping and comparison are on Usage tracking; captured bodies and erasure on Payload logging.

Operations

/api/reload is a fallback; normal writes reach every pod on their own.