Management API
The gateway's scoped management API -- key lifecycle, spend against the governing policy, and the routable model catalog.
Management API
Alongside the inference surface, the gateway serves a small, fully-typed
management API for key lifecycle, usage and model discovery. It is mounted under
/api/v1/ on the main listener, authenticated with a management-kind issued
key (a runtime key is refused with a 403), and each operation declares the
scope it requires.
The management API is dormant unless you enable it. On a self-hosted
gateway it requires MGMT_API_ENABLED=true, a configured AUTH_TOKEN, and
issued-key handling switched on (GOVERNANCE_ISSUED_KEYS=true). See
Self-hosting.
Authentication and scopes
One credential type covers inference and management. Scopes are a property of the issued key, set when the key is created:
| Scope | Grants |
|---|---|
keys:read | Listing and retrieving runtime keys. |
keys:write | Creating, updating, rotating and revoking runtime keys. |
usage:read | Reading spend against the governing policy. |
models:read | Reading the routable model catalog. |
A key issued with no scopes holds all four. Scope a management key deliberately if you want it narrow.
The operations
Every route, its parameters, its request and response schemas and the scope it requires are in the Management reference, generated from the contract itself. This page covers what those pages cannot tell you: the things worth knowing before you call them.
The surface is small -- key lifecycle (list, create, retrieve, update, revoke, rotate), spend for a key or for any principal, and the routable model catalog.
Keys
Creation returns the plaintext token exactly once. There is no later route that will hand it to you again.
A key's shape is transport only. Business validation -- name rules, whether the policy exists, the issued-key governing-policy invariant -- belongs to the control plane, so a request that satisfies the schema can still be refused on grounds the contract says nothing about.
Usage
Every value that does not apply, or is not yet known, is a literal JSON
null -- never a zero. A 0 in this response would read as "spent
nothing", which is a different and much more reassuring claim than "we do not
know".
Spend is reported against the governing policy, not against the key in isolation: a key owned by a person resolves as that person's identity policy and shares their counter bucket, so a figure here can move because of traffic that key never carried. See API access for why minting a key is never a budget bypass.
The response carries a principal_spent_complete flag alongside the figure.
Check it before treating the number as a total.
Models
A price that is not published is null rather than zero -- an unpublished
component is not a free one. Benchmark scores appear only where the provider
publishes them, so their absence is missing data rather than a score of zero.
Contract versioning
The published contract carries its own semver clock, bumped in the same change as any enforced difference -- routes, override fields, refused fields, headers, or management scopes. Loosening or adding is a minor version; tightening is a major, and is intended to be close to never.
The contract is also held against the implementation by a parity test asserting five equivalences: the routes match the keyed allowlist, the override schema matches the decoder, the refused-field schemas match the refused-field list, the header parameters match the read-and-strip list, and the management operations and scopes match the management router. If those disagree, the contract is what moves.