Endpoint reference
The complete map of the gateway's HTTP surface: /v1/, /scim/v2/, /admin/*, /connect.
/v1/* is gated by an enrolled client key (minted by anyray-connect) or a non-human
service key; attribution rides the x-anyray-metadata header. /admin/* is gated by the
admin token (ANYRAY_ADMIN_TOKEN, the
break-glass owner) or a role-scoped console SSO session — and authenticated ≠ privileged: each
route additionally requires the capability in its row, per the
RBAC lattice (viewer → auditor → operator → security_admin → owner). /scim/v2/* uses its own static bearer configured through
PUT /admin/scim/settings; it is not an admin-console session. Inference requests and the VS Code
pre-call hook carry content on the request path under ANYRAY_CONTENT_MODE; SCIM identities,
admin spend records, and request logs remain metadata-only and never expose prompt/response bodies
to humans.
Inference API — /v1/*
OpenAI-compatible, plus the Anthropic-native Messages API. Point any OpenAI/Anthropic SDK's base URL at the gateway. Fully described in the OpenAPI spec and the API reference.
| Method | Path | What it does |
|---|---|---|
| post | /v1/chat/completions | Chat completions (streaming + non-streaming). |
| post | /v1/seat/cursor/chat/completions | Cursor OpenAI-BYOK lane — identical to /v1/chat/completions, but classified as an Anyray subscription seat because Cursor cannot send a seat header. This is API-key-upstream traffic, not the native Cursor Team entitlement. Configured by anyray-connect; not called by hand. |
| post | /v1/extensions/vscode/optimize | Optimize a VS Code extension request before the extension calls its provider. Fails open and does not record client-supplied usage; the optimizer's own savings are metered as a zero-token spend row. |
| post | /v1/completions | Legacy text completions. |
| post | /v1/embeddings | Embeddings. |
| post | /v1/messages | Anthropic-native Messages API. |
| post | /v1/messages/count_tokens | Token counting (no inference; not metered). |
| post | /v1/responses | Responses API — create (GET/DELETE /v1/responses/{id}, GET /v1/responses/{id}/input_items). |
| post | /v1/audio/speech | Text-to-speech. |
| post | /v1/audio/transcriptions · post /v1/audio/translations | Audio transcription / translation. |
| post | /v1/images/generations · post /v1/images/edits | Image generation / edits. |
| post | /v1/files | Upload a file (GET list; GET/DELETE /v1/files/{id}, GET /v1/files/{id}/content). |
| post | /v1/batches | Create a batch (GET list; GET /v1/batches/{id}, POST /v1/batches/{id}/cancel). |
| get | /v1/models | List available models. |
| get | /v1/realtime | Realtime (WebSocket) passthrough. |
Inbound SCIM v2 — /scim/v2/*
Okta, Microsoft Entra ID, and other SCIM clients push verified users and groups to these gateway
routes. Every request sends the SCIM bearer as Authorization: Bearer <token>. SCIM responses use
application/scim+json; errors use the SCIM 2.0 error envelope.
Discovery
| Method | Path | What it does |
|---|---|---|
| get | /scim/v2/ServiceProviderConfig | Advertise PATCH, filtering, paging, and bearer authentication. |
| get | /scim/v2/ResourceTypes | List the User and Group resource types. |
| get | /scim/v2/Schemas | Return the supported core User and Group schemas. |
Users
| Method | Path | What it does |
|---|---|---|
| post | /scim/v2/Users | Create a user from the verified IdP payload. |
| get | /scim/v2/Users | List users. Supports filter=userName eq "dev@example.com", startIndex, and count. |
| get | /scim/v2/Users/:id | Read one user. |
| put | /scim/v2/Users/:id | Replace a user. |
| patch | /scim/v2/Users/:id | Patch activation, display name, or identity type. active:false blocks the user's client keys. |
| delete | /scim/v2/Users/:id | Soft-delete and deactivate a user so existing client keys stay blocked. |
Groups
| Method | Path | What it does |
|---|---|---|
| post | /scim/v2/Groups | Create a group and resolve or create its members. |
| get | /scim/v2/Groups | List groups with startIndex and count paging. |
| get | /scim/v2/Groups/:id | Read one group and its members. |
| put | /scim/v2/Groups/:id | Replace a group and recompute member team/role mappings. |
| patch | /scim/v2/Groups/:id | Add, remove, or replace members; update the display name. |
| delete | /scim/v2/Groups/:id | Delete a group and recompute affected identities. |
Billing app machine API
Served by the Billing app (app.anyray.ai), not the gateway — the gateway calls it with its
adt_ deployment token. Distinct from the inference /v1/* above, and metadata only: usage rollups,
lease state, release metadata, or an explicitly customer-submitted redacted support bundle; never
prompt/response content.
| Method | Path | What it does |
|---|---|---|
| post | /v1/meter | Ingest a usage rollup (+ deployment heartbeat); returns a freshly signed entitlement lease. |
| get | /v1/entitlement | Lease heartbeat — refresh the signed lease without ingesting usage. |
| get | /v1/tenant-context | Fleet mode only: resolve an ark_ key hash to its tenant context. |
| get | /v1/releases/latest | Return the current release-line version and its bounded requirements manifest; manifest may be null. |
| post | /v1/support-bundles | Accept a reviewed, redacted support bundle (deployment bearer, 1,000,000-byte cap, one per deployment per minute), analyze it, and return { receiptId }. |
| post | /v1/connect-events | Gateway-down fallback for connect-health: anyray-connect posts its content-free doctor results here when its gateway is unreachable. Authenticated by a DevCert + Ed25519 proof of possession (not a deployment bearer); the deployment identity comes from the signed cert. Best-effort, throttled, never on the billing path. |
| post | /v1/cert/renew | Roll a live DevCert forward, so a machine in use never has to re-enroll — only a genuinely idle one reaches expiry. Authenticated by a signed challenge proving possession of the enrolled key (the same DevCert + Ed25519 proof of possession as above, not a deployment bearer); identity and deployment come from the signed cert. Refused for a revoked developer or a revoked deployment — renewal is never a way around revocation. An SSO-issued certificate is also refused when the tenant's SSO policy is absent or unreadable, rather than falling back to a longer default key lifetime. |
| post | /v1/cli-sso/start | Start the Billing app's deployment-authenticated identity half of a CLI login. Receives the gateway session id + user code; returns the browser activation URL. |
| post | /v1/cli-sso/poll | Return pending or the WorkOS-verified identity, governed team list/default, resolved role, and configured key lifetime. Never returns the gateway key. |
| put | /v1/enrollment-identities | Record a deployment-verified roster identity with allowlisted source and type. Used by gateway SCIM reflection. |
CLI self-service login
Pre-key gateway routes used only by anyray-connect login. Start is rate-limited by source IP. Poll
is authorized by the separate high-entropy secret returned once by start; the secret travels in a
header, not the URL, and is stored by the gateway only as a salted hash.
| Method | Path | What it does |
|---|---|---|
| post | /sso/cli/start | Create a durable ten-minute login session, start the Billing app SSO grant, and return { id, browser_url, user_code, poll_secret, interval, expires_in }. |
| get | /sso/cli/poll/:id | With x-anyray-poll-secret, return pending, the eligible team list, or the one-time minted key. Send the selected eligible team in x-anyray-team. |
The Billing app also serves the browser-only /sso/cli/activate/:id, /sso/cli/authorize, and
/sso/cli/callback pages. They confirm the terminal code, complete WorkOS SSO, and JIT-provision the
identity; they are HTML/redirect surfaces, not integration APIs.
Health & settings
| Method | Path | Capability | What it does |
|---|---|---|---|
| get | /admin/health | config:read | Liveness, spend-store ping, schema version (applied vs expected), optimizer reachability. |
| get | /admin/me | — | The caller's identity plus deploymentOwner, which is false for tenant SSO principals in fleet mode (authenticated, no capability required). |
| get | /admin/settings | config:read | Read runtime settings (content mode, seat overflow, flags). |
| put | /admin/settings | content:manage | Update runtime settings (contentMode, heartbeatTier, seatOverflow, seatOverflowHourlyMaxRequests). |
| get | /admin/metering/last-report | config:read | Exact final payload from this process's last successful, verified usage report, plus the active heartbeat tier and metering state. |
| get | /admin/update-status | config:read | Self-updater status: available vs running version, the local preflight verdict (missing environment-variable names + breaking notes), the computed updateClass (soft = image-only, self-applies on Compose installs · hard = operator action required, never applied unattended), the autoSoftUpdates policy, and the last unattended apply attempt. |
| put | /admin/update/settings | update:run | Update policy: {"autoSoftUpdates": true|false} — whether soft (image-only) updates apply unattended (Compose installs; other platforms are always notify-only). Default on. |
| get | /admin/auth | — | Auth-mode probe (pre-session; reports whether SSO is required). |
| get | /admin/auth/update | update:run | Trigger a self-update check/apply. |
Spend & governance
The spend surface and per-user token caps. In the OpenAPI spec and the explorer.
| Method | Path | Capability | What it does |
|---|---|---|---|
| get | /admin/spend | config:read | In-memory spend summary: requests + tokens per attributed user. |
| get | /admin/spend/dashboard | config:read | Windowed dashboard — money by billing class, trend, top strategies, latency, prompt-cache economics. ?window=. |
| get | /admin/spend/usage | config:read | Per-user usage detail — per-model & per-day breakdown, org per-model rollup, cap gauges. ?window=, ?limit=. |
| get | /admin/spend/quality-parity | config:read | Holdout-vs-treated outcome parity (turns, output tokens, error rate, latency) with CIs. ?window=. |
| get | /admin/spend-connectors | config:read + deployment owner | Read redacted Cursor, Devin, and GitHub Copilot connector state and poll status. Credentials are never returned. |
| put | /admin/spend-connectors | providerkeys:manage + deployment owner | Partially set, rotate, or remove write-only connector credentials. Omitted connectors stay unchanged; null or {} removes one. |
| post | /admin/spend-connectors/sync | providerkeys:manage + deployment owner | Sync vendor usage. Returns safe per-connector counts or skipped/failed. |
| get | /admin/spend-connectors/usage | config:read + deployment owner | Aggregate content-free vendor-native usage. ?days= accepts 1–90 and defaults to 30. |
| get | /admin/auth-events | config:read | Reason-coded auth/cap rejections (per-developer diagnostics) with remediation hints. ?user=, ?limit=. |
| get | /admin/user-caps | config:read | Per-user monthly token caps + current-month usage + cap-alert posture (webhook URL never returned). |
| put | /admin/user-caps | usercaps:write | Set caps and cap-approach alert settings (thresholds + Slack-compatible webhook). |
Spend connector rules
Connector credentials (cursor.adminApiKey, devin.serviceUserToken, and githubCopilot.token) are
write-only. Responses show configuration and poll status, safe counts, and GitHub's non-secret
scope and slug. They never return credentials, vendor payloads, signed URLs, or vendor errors.
POST /admin/spend-connectors/sync returns {connectors: [...]}. Each connector reports
fetched, inserted, and duplicate counts, {skipped: true} when another replica is syncing, or
{failed: true} without the vendor error. Usage keeps each vendor's units separate. Copilot's
public list value is an estimate, not an invoice total.
These routes manage the whole deployment. In fleet mode, tenant SSO users cannot use them even with the listed capability. Use the deployment owner credential or an unbound local owner session.
The deprecated /admin/spend/connectors GET/PUT path uses the same encrypted store for older
Cursor/Copilot clients. New clients should use /admin/spend-connectors.
Optimizer, pricing & routing
| Method | Path | Capability | What it does |
|---|---|---|---|
| get | /admin/optimizer/settings | config:read | Read the optimizer pipeline config. |
| put | /admin/optimizer/settings | optimizer:write | Update the optimizer pipeline config. |
| post | /admin/optimizer/purge | optimizer:purge | Purge optimizer caches / session state. |
| get | /admin/pricing | config:read | The read-only official price table. |
| get | /admin/model-aliases | config:read | Read model-alias mappings. |
| put | /admin/model-aliases | modelaliases:write | Update model-alias mappings. |
| get | /admin/routing-config | config:read | Read routing (single / loadbalance / fallback / conditional). |
| put | /admin/routing-config | routing:write | Update routing config. |
| post | /admin/test-request | playground:run | Console playground: send a test request through the gateway. |
Providers
| Method | Path | Capability | What it does |
|---|---|---|---|
| get | /admin/provider-keys | providerkeys:manage | List configured providers (slugs only — key values never returned). |
| put | /admin/provider-keys | providerkeys:manage | Set server-held provider API keys. |
Access, SSO & enrollment
| Method | Path | Capability | What it does |
|---|---|---|---|
| get | /admin/idp-config | config:read | Read the SSO / IdP configuration. |
| put | /admin/idp-config | idp:manage | Configure SSO / IdP. |
| delete | /admin/idp-config | idp:manage | Remove the SSO / IdP configuration. |
| get | /admin/scim/settings | config:read + deployment owner | Read redacted SCIM state, admin group, and group-to-team mappings. The bearer and hash are never returned. |
| put | /admin/scim/settings | idp:manage + deployment owner | Set or rotate the SCIM bearer and update group mappings. Omitting bearerToken preserves it. |
| post | /admin/workos-portal-link | idp:manage | Mint a WorkOS admin-portal link. |
| get | /admin/sso/start | — | Begin the console SSO login handshake (pre-session). |
| get | /admin/sso/callback | — | SSO redirect callback (pre-session). |
| post | /admin/sso/logout | — | End the console SSO session. |
| get | /admin/client-keys | config:read | List minted client keys (enrolled users). |
| post | /admin/client-keys | clientkeys:manage | Mint a client key. |
| delete | /admin/client-keys/:id | clientkeys:manage | Revoke a client key. |
| get | /admin/service-keys | config:read | List non-human service keys. Metadata only; tokens and hashes are never returned. |
| post | /admin/service-keys | clientkeys:manage | Mint an ark_svc_… key for an AI agent, CI job, or SDK script. |
| delete | /admin/service-keys/:id | clientkeys:manage | Revoke a service key. |
| get | /admin/enrollment-links | config:read | List enrollment / setup links. |
| post | /admin/enrollment-links | enrollment:manage | Create an enrollment link. |
| delete | /admin/enrollment-links/:id | enrollment:manage | Disable an enrollment link. |
| delete | /admin/enrollment-links/:id/hard | enrollment:manage | Hard-delete an enrollment link. |
| get | /admin/provisioning-tokens | config:read | List deployment provisioning tokens. |
| post | /admin/provisioning-tokens | provisioning:manage | Mint a provisioning token. |
| delete | /admin/provisioning-tokens/:id | provisioning:manage | Revoke a provisioning token. |
| post | /admin/provisioning-tokens/:id/rotate | provisioning:manage | Rotate a provisioning token. |
Privacy, support & observability
| Method | Path | Capability | What it does |
|---|---|---|---|
| get | /admin/gdpr/users/:user/export | gdpr:manage | Export a user's spend records. |
| delete | /admin/gdpr/users/:user | gdpr:manage | Erase a user's spend records (and cap-alert dedup rows). |
| get | /admin/support/bundle | config:read | Generate a support bundle for remote debugging. |
| post | /admin/support/bundle/share | content:manage | Explicitly rebuild, redact, and send a support bundle to the Billing app; return its receipt and audit metadata. |
| get | /admin/observability/traces/:id | observability:read | Fetch one trace (content redacted unless observability:read-content). |
| get | /admin/observability/* | observability:read | Proxy to the observability read API for the console. |
| get | /admin/team-skills | config:read | Read team-skill / onboarding metadata. |
| put | /admin/team-skills | teamskills:write | Update team-skill / onboarding metadata. |
| get | /admin/wizard-status | config:read | Onboarding wizard progress. |
| put | /admin/wizard-confirm | wizard:write | Confirm an onboarding wizard step. |
Service key request and response
post /admin/service-keys accepts a non-empty name and team, plus an
optional non-negative monthlyBudgetUsd. name becomes the key label and attributed service
identity.
{
"name": "synthetic-release-agent",
"team": "platform",
"monthlyBudgetUsd": 50
}
The 201 response returns the raw ark_svc_… value exactly once. The record is metadata only and
is also returned by get /admin/service-keys inside { "keys": [...] }.
{
"key": "ark_svc_synthetic-once-only",
"record": {
"id": "synthetic-key-id",
"user": "synthetic-release-agent",
"team": "platform",
"label": "synthetic-release-agent",
"tenant": "default",
"createdAt": "2030-06-01T00:00:00.000Z",
"keyType": "service",
"monthlyBudgetUsd": 50,
"source": "service",
"type": "service"
}
}
The cap covers the key's successful request cost in the current UTC calendar month. Once completed
spend is at or above the cap, inference returns HTTP 402 with
error.code: "service_key_budget_exceeded". Enforcement is a soft cap: completed requests update
the counter after the response, so concurrent in-flight requests can overshoot. Counter read/write
failures pass traffic through so a budget-store outage does not stop agents or CI. Omitting the
budget, or setting it to 0, leaves the key unlimited.
delete /admin/service-keys/:id returns { "ok": true }. The raw key cannot
be recovered after minting; revoke it and mint a replacement.
anyray-connect contract — /connect/*
Called by the anyray-connect CLI and its hooks, not by end apps. Metadata only (savings beacons,
policy, CCR retrieve/recall). No admin capability — authenticated as the connected client.
| Method | Path | What it does |
|---|---|---|
| post | /connect/verify | Verify a client key / enrollment. |
| get | /connect/policy | Fetch the client's effective policy. Optional ?model=<id> also returns modelContext.contextTokens — that model's real context window — so a client can budget against the true window instead of its own default. Omitted when the model is unknown. |
| get | /connect/savings | Report realized savings for the client. |
| post | /connect/hook-savings | Record hook-trim savings (PostToolUse). |
| post | /connect/optimize-output | Optimize a tool output at the source. |
| post | /connect/recall · post /connect/retrieve | CCR recall / retrieve of externalized context. A human/CLI caller sends x-anyray-retrieve-probe: 1 (the anyray-connect retrieve / recall verbs do) so the call does not latch retrieve capability — only the MCP server’s calls prove the model can pull spans back. |
| post | /connect/mcp-heartbeat | MCP-server session-start heartbeat; records explicit retrieval availability without overriding persistent-client safety. |
| post | /connect/health | Record the content-free results of anyray-connect doctor checks (gateway reachability, retrieval loop, per-tool MCP registration, enrollment, connect run) plus the reporting client's own version. Best-effort — always 200; the gateway forwards a rolling 24h rollup to the Billing app on the next meter round. Metadata only, never content. |
/public/* (console login: /public/auth, /public/auth/session, /public/logs) and /log/stream
back the console UI's in-browser session. They aren't part of the integration surface — use
/admin/* with the admin token for automation.