Relay docs

Authentication & keys

Every gateway request (except GET /health) authenticates with a Relay API key using the ApiKey scheme.

Authorization: Bearer app_live_xxxxxxxxxxxxxxxxxxxxxxxx

#Issuing keys

Create keys in the control panel under API Keys. The full key is shown once at creation — copy it then. Keys belong to the workspace you have selected, which is how usage, budgets and cost attribution are grouped; it is stamped server-side and never typed in.

Manage keys via the control-plane API too: POST /api/ApiKeys/search, POST /api/ApiKeys, PUT /api/ApiKeys/{id}, POST /api/ApiKeys/{id}/revoke, DELETE /api/ApiKeys/{id}.

#What a key controls

Everything below is settable at creation and editable afterwards:

SettingEffectEmpty / unset means
NameIdentifies the key in the panel and in cost attribution.— (required)
ScopesCapabilities the key may exercise: chat.completions, embeddings, models.read, workflows.run.Every scope allowed.
Model allow-listModels the key may call. A request for anything else returns 403 model_not_allowed.Any enabled model.
Rate limitRequests per minute for this key.No per-key limit.
ExpiryThe key stops working after this date (end of day).Never expires.

An empty scope list or allow-list means unrestricted, not nothing — so adding a new scope to the gateway never retroactively locks out existing keys.

#Editing a key

A key's details can be changed at any time; the secret cannot. Editing changes the name, scopes, allow-list, rate limit and expiry, and leaves the key its holder is using working exactly as before.

There is deliberately no way to rotate a key in place. Repointing an existing key at a new secret would either break every caller silently or, worse, leave two secrets believed to be one. Rotation is revoke + issue a new key, which leaves an audit trail that an edit would not.

Nor is the key retrievable. Only a SHA-256 hash is stored, so after creation the panel can show the identifiable prefix (app_live_xxxxxxxx…) and nothing more — not because it is being withheld, but because the rest was never kept.

#Budgets

A workspace has one spend ceiling, optionally divided into per-member allocations. When workspace spend reaches a hard-stop cap, the router rejects further requests with 402 before anything is sent upstream. Spend is recomputed periodically from telemetry (Gateway:BudgetRefreshMinutes), so the stop engages within that window rather than instantly. See Budgets & spend limits.

#Control-panel authentication

The control panel is a separate app that authenticates admins with Microsoft Entra (cookie auth) — not API keys. The api/* control-plane endpoints require a signed-in admin session; the public /v1/* API requires an API key. Keep the two mental models separate:

Gateway API (/v1/*)Control panel (api/*)
WhoApplicationsAdmins / team owners
AuthAPI key (Bearer)Entra sign-in (cookie)

#Good practice

  • One key per app or environment, so you can revoke narrowly.
  • Set a model allow-list on keys that only need a specific model.
  • Put every app's key behind the team that should own its cost.