Robots Center Agents Network
Log in Create workspace
Skip to content

API reference

Authentication

One tag: method, path, summary, auth, and scopes. Request and response fields ship in this page — expand a row to read the contract.

Endpoints

4
POST
/api/v1/agent_tokens

Exchange API key for access token

Description

Unauthenticated exchange: send a primary workspace or service-agent API key (agk_<base64>.<base64>) in the x-agent-api-key header or as api_key in the JSON body. Returns a 30-day access token. This route is optional — protected /api/v1 routes also accept the same API key as Authorization: Bearer agk_… or in x-agent-api-key. A Bearer token on this exchange returns 400.

Auth

None
Request Body
Field Type Required Description
scopes array<string> No Optional subset of the credential's scopes to request
api_key string No API key in format agk_<base64>.<base64> (alternative to x-agent-api-key)
Parameters
Name In Type Required Description
x-agent-api-key header string No API key in format agk_<base64>.<base64>. Underscore names are not read.
Responses
200

Token issued

Returns: TokenResponse

Response Body
Field Type Required Description
token string Yes 30-day access token
scopes array<string> Yes Granted scopes
credential_id string Yes API credential UUID
expires_in integer Yes Seconds until expiry (2,592,000)
service_agent_id string Yes Service agent UUID
workspace_id string Yes Workspace UUID
Example
{
  "token": "SFMyNTY.g2gDdAAAAARtAAAADWNyZWRlbnRpYWxfaWRtAAAACMzZODNiNDMzLTAyZjUtNGJjYy04NWNhLTdhM2QwYTgzNjI1Ym0AAAAGc2NvcGVzbQAAAAMAAAAIZnJvbV9vcHNtAAAACXRvX29iamVjdG0AAAAJdG9fYWN0aW9ubgYBy_T1yQFiAAFTgA.ABC123def456",
  "scopes": [
    "traces:write",
    "eval_runs:read",
    "eval_runs:write",
    "eval_suites:read",
    "eval_suites:write",
    "gateway:check",
    "replays:write",
    "workflow_targets:read",
    "workflow_targets:write"
  ],
  "credential_id": "3e83b433-02f5-4bcc-85ca-7a3d0a83625b",
  "expires_in": 2592000,
  "service_agent_id": "a91720d1-1c45-4343-bb45-786e20432f04",
  "workspace_id": "e65ef764-9b2c-4e24-b918-99c7be33506a"
}
400

Authorization: Bearer was sent. This endpoint accepts an API key (agk_...), not a Bearer token. Use x-agent-api-key or api_key.

401

Missing, invalid, expired, archived, or revoked API key. Detail is api_key_required, invalid_api_key, api_key_expired, api_key_archived, or api_key_revoked.

Example
{
  "detail": "api_key_revoked",
  "status": 401,
  "title": "Unauthorized",
  "type": "https://robotscenter.net/problems/unauthorized"
}
403

Credential is recognized but refused. Detail is service_agent_inactive or insufficient_scopes. Frozen, paused, or archived workspaces also return 403 with a top-level error of workspace_frozen, workspace_paused, or workspace_archived.

Example
{
  "detail": "This workspace is frozen. Machine traffic is refused until the freeze is lifted.",
  "error": "workspace_frozen",
  "status": 403,
  "title": "Forbidden",
  "type": "https://robotscenter.net/problems/forbidden"
}
POST
/api/v1/register

Register new user with API access

Description

Creates a new user account, workspace, service agent, and API credentials in a single request. Returns everything needed for immediate API access.

Auth

None
Request Body
Field Type Required Description
name string No Optional display name (2–120 characters). When omitted, register_via_api derives it from the email local part.
password string Yes Password (12–72 characters)
email string Yes User email address
agent_name string Yes Name for the default service agent
workspace_name string Yes Name for the new workspace
Responses
201

Account, workspace, service agent, agk_ API key, and 30-day access token issued

Response Body
Field Type Required Description
user object Yes Created user
user.id string Yes User UUID
user.name string No Display name
user.email string Yes Normalized email
user.confirmed_at datetime (ISO 8601) No Confirmation timestamp
api_key object Yes Primary long-lived workspace API key (shown once)
api_key.type string (api_key) Yes Always api_key
api_key.key string Yes agk_ secret (prefix.secret)
api_key.scopes array<string> Yes Granted scopes
api_key.credential_id string Yes API credential UUID
api_key.service_agent_id string Yes Service agent UUID
access_token object Yes Optional 30-day bearer token for the same credential
access_token.type string (bearer) Yes Always bearer
access_token.token string Yes Access token
access_token.scopes array<string> Yes Granted scopes
access_token.credential_id string Yes API credential UUID
access_token.expires_in integer Yes Seconds until expiry (2,592,000)
access_token.service_agent_id string Yes Service agent UUID
service_agent object Yes Default service agent
service_agent.id string Yes Service agent UUID
service_agent.name string Yes Agent name
service_agent.status string Yes Agent status
service_agent.slug string Yes Agent slug
workspace object Yes Created workspace
workspace.id string Yes Workspace UUID
workspace.name string Yes Workspace name
workspace.status string Yes Workspace status
workspace.plan string Yes Plan slug
workspace.slug string Yes Workspace slug
Example
{
  "user": {
    "id": "7c2f0a11-4b8e-4d3a-9f21-0c1b2a3d4e5f",
    "name": "Ops",
    "email": "[email protected]",
    "confirmed_at": null
  },
  "api_key": {
    "type": "api_key",
    "key": "agk_abc123.def456",
    "scopes": [
      "traces:write",
      "gateway:check"
    ],
    "credential_id": "3e83b433-02f5-4bcc-85ca-7a3d0a83625b",
    "service_agent_id": "a91720d1-1c45-4343-bb45-786e20432f04"
  },
  "access_token": {
    "type": "bearer",
    "token": "SFMyNTY.example.access-token",
    "scopes": [
      "traces:write",
      "gateway:check"
    ],
    "credential_id": "3e83b433-02f5-4bcc-85ca-7a3d0a83625b",
    "expires_in": 2592000,
    "service_agent_id": "a91720d1-1c45-4343-bb45-786e20432f04"
  },
  "service_agent": {
    "id": "a91720d1-1c45-4343-bb45-786e20432f04",
    "name": "Default agent",
    "status": "active",
    "slug": "default-agent"
  },
  "workspace": {
    "id": "e65ef764-9b2c-4e24-b918-99c7be33506a",
    "name": "Example Workspace",
    "status": "active",
    "plan": "starter",
    "slug": "example-workspace"
  }
}
422

Validation error

POST
/api/v1/socket_tokens Agent Token

Issue short-lived socket token

sockets:connect

Description

Returns a short-lived socket token for websocket authentication. Authenticate this request with a service-agent bearer token or API key, then pass the returned token as socket_token in Phoenix connection params instead of exposing a long-lived API credential on the websocket URL. Transport notes: /socket rejects frames above 65 536 bytes (64 KB). Ready, heartbeat, and command handlers also validate decoded payload size. Unrecognized agent events receive %{reason: "unknown_event"}. Production accepts WebSocket upgrades only from the configured HTTPS origin.

Auth

Agent Token

Required Scopes

sockets:connect
Responses
200

Socket token issued

Returns: SocketTokenResponse

Response Body
Field Type Required Description
scopes array<string> Yes Granted scopes carried into the socket connection
socket_path string Yes Phoenix socket path to connect to. Service-agent socket identity is based on credential_id; operator socket identity is tied to the authenticated browser session.
expires_in integer Yes Seconds until the socket token expires
service_agent_id string Yes Service agent UUID bound to the token
workspace_id string Yes Workspace UUID bound to the token
socket_token string Yes Short-lived socket token for websocket authentication
Example
{
  "scopes": [
    "sockets:connect",
    "events:read",
    "agent_commands:read"
  ],
  "socket_path": "/socket",
  "expires_in": 600,
  "service_agent_id": "a91720d1-1c45-4343-bb45-786e20432f04",
  "workspace_id": "e65ef764-9b2c-4e24-b918-99c7be33506a",
  "socket_token": "SFMyNTY.g3QAAAABbQAAAA1jcmVkZW50aWFsX2lkbQAAACQzZTgzYjQzMy0wMmY1LTRiY2MtODVjYS03YTNkMGE4MzYyNWJtAAAAAXMAAAANc29ja2V0X3Njb3Blc20AAAABAAAAD3NvY2tldHM6Y29ubmVjdA.a1b2c3d4"
}
401

Invalid, missing, or expired credential

403

Credential is valid but lacks sockets:connect (detail: The token does not have sufficient scope). The :api_auth plug also refuses frozen, paused, or archived workspaces before the controller runs, with a top-level error of workspace_frozen, workspace_paused, or workspace_archived.

Example
{
  "detail": "This workspace is frozen. Machine traffic is refused until the freeze is lifted.",
  "error": "workspace_frozen",
  "status": 403,
  "title": "Forbidden",
  "type": "https://robotscenter.net/problems/forbidden"
}
POST
/api/v1/enrollments/claim

Claim an agent or fleet enrollment token

Description

Claims an enrollment token. A single-use token returns the canonical service-agent identity created with it; a fleet claim token (`max_claims` > 1) mints a fresh identity per claim, binds to the pre-registered `pending` robot carrying `serial_number` when one exists, and applies the token's cohort and default tags. Every claim returns its own agk_ API key and 30-day access token, returned only once. The claim token itself is never usable as an API credential.

Auth

None
Request Body
Field Type Required Description
token string Yes One-time enrollment token in age_prefix.secret format
serial_number string No Serial of the claiming unit. Required for fleet claim tokens: it selects the pre-registered robot to bind to and is checked against the token's serial allowlist.
agent object No Optional runtime metadata advertised during claim
Responses
201

Enrollment claimed and machine credentials issued

400

Serial not on the token's allowlist, serial already claimed, or no serial supplied for a fleet claim token

401

Invalid enrollment token

403

The workspace is not accepting machine traffic, with a machine-readable `error` of `workspace_frozen`, `workspace_paused` or `workspace_archived`. Nothing is created: the claim is refused before the service agent, robot, credential and access token are issued, and the token keeps its remaining claims.

Example
{
  "detail": "This workspace is frozen. Machine traffic is refused until the freeze is lifted.",
  "error": "workspace_frozen",
  "status": 403,
  "title": "Forbidden",
  "type": "https://robotscenter.net/problems/forbidden"
}
409

Enrollment was already claimed, exhausted or revoked

410

Gone. type problems/enrollment-expired when the token is past expires_at. type problems/robot-decommissioned when the claimed serial belongs to a retired robot — that claim is refused and claims_count is not incremented.

429

Plan robot or agent quota reached