Log in Create workspace
Skip to content

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.

API docs
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

  1. 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.

  2. 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.

  3. 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.

What success looks like

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

example

Machine-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.

bash
# 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

details

Operator 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

details

Enterprise 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

details

Requesting 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

details

mpk_ 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.

Where to go next

see also