Axiomancer
API reference — Overview

Admin API

Operator-facing RouteShift endpoints for key lifecycle, usage, routing artifacts, and cache invalidation, with explicit unrestricted and scoped-token boundaries.

The admin API is a separate, operator-facing surface at https://api.routeshift.io/admin. It never accepts a virtual sk-proxy-… key.

Authentication

Authorization: Bearer <operator-admin-token>

Admin credentials are provisioned in the RouteShift deployment:

  • The unrestricted operator credential can call admin reads and mutations.
  • Deployment-configured scoped tokens can call only an allowlist of GET endpoints and only for an allowed team_id.
  • Scoped tokens cannot call admin mutations, even when a matching team_id is present.

Do not expose an operator admin credential to a client application. Customer traffic belongs on the OpenAI-compatible client API with a virtual key.

Keys

Mint a virtual key

POST /admin/keys
Content-Type: application/json
{
  "alias": "prod-agent",
  "allowed_models": ["gpt-4o", "gpt-4o-mini"],
  "expires_at": "2026-12-31T00:00:00Z",
  "rpm": 60,
  "tpm": 200000,
  "monthly_budget_usd": 100,
  "metadata": { "env": "prod", "owner": "agent-team" }
}

This mutation requires the unrestricted operator credential. The response includes the one-time sk-proxy-… token. RouteShift stores only its hash; the plaintext is unrecoverable after this response.

List keys

GET /admin/keys

With the unrestricted credential, returns key metadata without the secret. A deployment-configured scoped token can use this read only with an allowed team_id.

Revoke a key

DELETE /admin/keys/{key_id}

This mutation requires the unrestricted operator credential. Revocation is immediate. In-flight requests finish; new requests return 401.

Usage

Window query

GET /admin/sessions/window?from=2026-04-01T00:00:00Z&to=2026-04-07T23:59:59Z&limit=500&cursor=…

This proxy endpoint requires Authorization: Bearer <ADMIN_SECRET>; the scoped-token allowlist does not include this route. It returns a paginated read of session_metrics; each row contains session ID, team ID, edit/retry turns, one-shot rate, primary model, total cost, and first/last request timestamps. The window cannot exceed seven days.

This endpoint exists primarily to feed the Layer-side yield correlation worker — see Axiom Layer's AI usage tracking.

The response is { sessions, next_cursor }; limit defaults to 200 and is capped at 1,000.

The dashboard's one-shot summary is a separate app route, not an admin-proxy endpoint:

GET /api/usage/one-shot?period=24h

Call it on the dashboard origin with a signed-in team member session. It accepts 24h, 7d (default), or 30d and returns summary plus by_model; it does not accept model, from, or to parameters and does not use the proxy admin token.

SSO device flow

Endpoints for the native SSO device-flow key issuance (RFC 8628) — see SSO device flow for the end-to-end story.

Register an IdP connection

POST /admin/idp-configs
Content-Type: application/json
{
  "team_id": "team_…",
  "provider": "okta",
  "login_domain": "acme.com",
  "issuer": "https://acme.okta.com",
  "client_id": "0oab…",
  "client_secret": "…"
}

Creates one connection for a (team_id, login_domain) pair. provider is google_workspace or okta. RouteShift validates the issuer's OIDC discovery document at create time and encrypts client_secret at rest.

Errors:

  • 400 — invalid provider, malformed login_domain, non-https:// issuer, or unreachable discovery document.
  • 403SSO_DEVICE_FLOW_ENABLED is not set to true on the deployment.
  • 409 — the login_domain is already registered to another team.

Update an IdP connection

PATCH /admin/idp-configs/{id}?team_id=team_…
Content-Type: application/json
{
  "issuer": "https://acme.okta.com",
  "client_id": "0oab…",
  "client_secret": "…"
}

Any subset of issuer, client_id, client_secret can be updated. login_domain and provider are immutable — delete and re-create to change them.

Delete an IdP connection

DELETE /admin/idp-configs/{id}?team_id=team_…

Removes the connection. In-flight device authorizations that reference it are cascaded and start failing on their next poll. Existing SSO-issued keys are not revoked — revoke them separately via DELETE /admin/keys/{key_id} if needed.

Device flow (RFC 8628)

Public endpoints called by CLIs and browsers, not with an admin token. Rate limiting and an enabled, provisioned identity-provider connection still apply; the presence of these routes does not guarantee device login is configured for a team.

Start a device authorization

POST /oauth/device/code
Content-Type: application/json
{ "email": "employee@acme.com" }

Response:

{
  "device_code": "…",
  "user_code": "BCDF-GHJK",
  "verification_uri": "https://api.routeshift.io/oauth/device/verify",
  "verification_uri_complete": "https://api.routeshift.io/oauth/device/verify?user_code=BCDF-GHJK",
  "expires_in": 600,
  "interval": 5
}

Poll for the key

POST /oauth/device/token
Content-Type: application/json
{
  "device_code": "…",
  "grant_type": "urn:ietf:params:oauth:grant-type:device_code"
}

Returns { "access_token": "sk-proxy-…", "token_type": "Bearer", "expires_in": 28800 } once approved. Before approval, returns authorization_pending, slow_down, access_denied, expired_token, or invalid_grant per RFC 8628.

Browser-facing endpoints

  • GET /oauth/device/verify — HTML page where a signed-in employee approves or denies a pending authorization.
  • POST /oauth/device/verify — same-origin JSON submission from the verify page. Content-Type must be application/json.
  • GET /oauth/device/callback — OIDC redirect target. Register ${SSO_CALLBACK_BASE_URL}/oauth/device/callback in each IdP's app console.

Routing

Invalidate alias cache

POST /admin/model-aliases/invalidate

Tells the proxy fleet to drop its in-memory model-alias cache. Issued automatically when you save an alias from the dashboard, but exposed here for tooling that edits aliases out-of-band.

Invalidate preset cache

POST /admin/presets/invalidate
Content-Type: application/json

{ "team_id": "team_01H…" }

Tells the proxy fleet to drop its in-memory copy of one team's presets so the next request resolves the new body immediately. The dashboard calls this automatically after every preset create, publish, delete, or disable — see Presets → Proxy cache invalidation for how the dashboard surfaces success and failure to API callers.

A non-OK response or network failure does not roll back the database write on the dashboard side; the caller receives proxy_cache_invalidated: false and the proxy re-reads the preset when its per-team TTL (60 seconds) expires.

Response shapes

Success responses are endpoint-specific. Authentication and authorization errors use an error object such as:

{
  "error": {
    "message": "Unauthorized"
  }
}
Was this page helpful?

On this page