Platform
Authentication methods and token lifecycle
Authenticate each caller with the credential designed for it: machine API keys and access tokens, short-lived socket tokens, browser sessions, SCIM tokens, partner keys, or bounded engagement tokens.
On this page
Start here
Choose the credential that matches the caller. Service agents use an agk_ key or 30-day access token, realtime clients mint a 10-minute socket token, people use sessions, identity providers use SCIM tokens, and marketplace integrations use partner or engagement credentials.
Before you begin
- The Robots Center base URL and the route your client needs to call
- An administrator who can issue the right key with minimal scopes
Put it into practice
-
Acquire the right credential
Generate a workspace key, use an agent credential, create a SCIM token in /app/admin, or obtain a partner credential. Save one-time secrets immediately.
-
Make one safe request
Put an agk_ key in Authorization: Bearer and call GET /api/v1/agents/me. Never place secrets in URLs, logs, screenshots, or source control.
-
Exchange only when useful
POST an agk_ key to /api/v1/agent_tokens with x-agent-api-key to mint a 30-day, optionally narrower access token. Mint a socket token separately just before opening /socket.
GET /api/v1/agents/me returns the service-agent identity bound to the credential, and every short-lived token has the expected scopes and expiry.
01 Agent Token Auth
exampleMachine-to-machine
Protected /api/v1 routes accept Authorization: Bearer {token} or the same API key in the x-agent-api-key header. Accepted credentials: primary workspace API key (format: agk_<base64>.<base64>) or a 30-day access token. Access tokens expire after 2,592,000 seconds. Credentials carry explicit scopes (e.g., traces:write, gateway:check, agent_commands:read).
POST /api/v1/agent_tokens is an exchange, not a Bearer source
The exchange route is unauthenticated. Send the API key in x-agent-api-key or as api_key in the JSON body. A Bearer token without an API key in either supported source returns 400 "This endpoint accepts an API key (agk_...), not a Bearer token." A revoked or archived key is 401 (api_key_revoked / api_key_archived). 403 is only service_agent_inactive, insufficient_scopes, or workspace_frozen|workspace_paused|workspace_archived.
Socket tokens
POST /api/v1/socket_tokens mints a 600-second token for /socket. The caller must already be authenticated on the machine API and must hold the exact scope sockets:connect. Frozen, paused, or archived workspaces are refused with 403 workspace_frozen|workspace_paused|workspace_archived before the controller runs.
Workspace primary key
Owners and admins generate, rotate, and delete the workspace primary API key at /app/agents/workspace-key. It lives on a hidden account-api service agent that never appears in GET /api/v1/operator/service_agents, has no operator REST, and always has credentials:write stripped from its scopes.
# Use illustrative values only; keep the real secret out of source control.
export AGENTOPS_BASE_URL="https://your-robots-center.example"
export AGENTOPS_API_KEY="agk_value_from_your_secret_manager"
# An agk_ key works directly on protected machine routes.
curl --fail-with-body --silent --show-error \
"$AGENTOPS_BASE_URL/api/v1/agents/me" \
-H "Authorization: Bearer $AGENTOPS_API_KEY" \
-H "Accept: application/json"
# Optional: exchange it for a 30-day token with narrower scopes.
TOKEN_RESPONSE=$(curl --fail-with-body --silent --show-error \
-X POST "$AGENTOPS_BASE_URL/api/v1/agent_tokens" \
-H "x-agent-api-key: $AGENTOPS_API_KEY" \
-H "Content-Type: application/json" \
--data '{"scopes":["agents:read"]}')
printf '%s' "$TOKEN_RESPONSE" | jq '{credential_id, service_agent_id, scopes, expires_in}'
export AGENTOPS_ACCESS_TOKEN="$(printf '%s' "$TOKEN_RESPONSE" | jq -r '.token')"
curl --fail-with-body --silent --show-error \
"$AGENTOPS_BASE_URL/api/v1/agents/me" \
-H "Authorization: Bearer $AGENTOPS_ACCESS_TOKEN"
02 Session Auth
detailsOperator browser sessions
Transport: session cookie (_agent_ops_key) set after login. Session lifetime: 14 days. Tokens older than 7 days are automatically reissued. Remember me cookie: _agent_ops_web_user_remember_me (14-day max age). Operator socket identity is tied to the authenticated session.
03 SCIM Token Auth
detailsEnterprise provisioning
Transport: HTTP Authorization: Bearer {scim_token}. Tokens are created (workspace owners only) and revoked on Workspace admin at /app/admin, not on /app/workspace. Endpoints: all routes under /scim/v2/*. Content type: application/scim+json. SCIM tokens do not expire; rotate by creating a new token and revoking the old one on /app/admin.
04 Password reset
detailsRequesting a link
A signed-out user requests a reset at /users/forgot-password. The response is identical whether or not the address has an account: the page always states that a link was sent if the address has one, and never echoes the address back, so nothing on it can be used as an account-existence oracle. Requests are throttled per IP and per address (10 and 5 respectively per 15 minutes), and a throttled submit renders that same panel.
Using the link
The link is single use and expires 60 minutes after it is issued. Following it opens /users/reset-password/:token. Changing the account's email address or suspending the account invalidates outstanding links. An unknown, expired, or already-used token renders one dead-end panel with a link back to request a new one.
After a reset
Setting a new password deletes every token the user holds -- remaining reset links and all browser sessions -- and live sessions are disconnected immediately. An unconfirmed account is confirmed by the reset, since receiving the emailed link proves control of the address. Issuing a new link never invalidates one already in the inbox.
05 When to use which
reference| Consumer | Auth method | Token source |
|---|---|---|
| Service agent (HTTP) | Bearer token or x-agent-api-key | Direct agk_ key, or POST /api/v1/agent_tokens with x-agent-api-key |
| Service agent (WebSocket) | Socket token (requires sockets:connect) | POST /api/v1/socket_tokens (600s TTL) |
| Operator (browser) | Session cookie | Login via /users/log-in |
| Identity provider (SCIM) | SCIM Bearer token | /app/admin |
| Marketplace partner | Authorization: Bearer mpk_… (PartnerAuth) | Issued, scoped, rotated, and suspended on /admin/partners (shown once) |
| Engagement runtime | Authorization: Bearer engagement token (EngagementAuth) | POST /api/v1/partner/engagements/:id/tokens — default TTL 86400, hard-capped at 604800 |
06 Partner and engagement authentication
detailsmpk_ partner keys and engagement tokens
Partner routes authenticate Authorization: Bearer mpk_… via PartnerAuth, not an agk_ key. Engagement ingest authenticates an engagement token, not a workspace key. Like the machine /api/v1 and OTLP routes, the partner, engagement, and SCIM planes throttle unauthenticated 401 responses at 30 per client address (IPv6 per /64) per 60 seconds, each plane in its own bucket, then return shared 429 problem JSON; an authenticated 403, or a 401 for a verified credential refused for its state (closed engagement, revoked token, suspended partner), does not spend that failure budget.
Troubleshooting
- 401 Unauthorized
- Confirm the credential type, header, expiry, and revocation state. An agk_ exchange key belongs in x-agent-api-key on /agent_tokens, while normal protected routes accept it as Bearer.
- 403 Forbidden
- Inspect required_scopes and workspace state. A valid token can still lack the exact scope, belong to an inactive agent, or be blocked by a frozen, paused, or archived workspace.
- A token works on one surface only
- Do not interchange machine, socket, session, SCIM, partner, and engagement tokens. Each has a different authentication path.