A service agent is the workspace identity used by one software worker or robot. Operators can create and archive those identities directly, or issue single-claim or fleet enrollment tokens so each claimant receives its own credential.
Identity precedes credentials
The service-agent record holds lifecycle, metadata, availability, and optional robot linkage. API credentials authenticate that identity; deleting an agent archives it and revokes its credentials.
Enrollment avoids shared fleet secrets
An operator enrollment token has a claim limit and expiry. Each successful claim provisions a distinct agent and credential, so telemetry, commands, revocation, and auditing remain attributable per unit.
Before you begin
A signed-in browser session with a selected workspace backed by an active membership is required; an archived workspace remains readable but rejects mutations. Every /api/v1/operator endpoint rejects API credentials and bearer tokens, regardless of their scopes.
Any active membership can read service-agent records. Enrollment listing exposes token prefixes, scopes, and expiry, so it—and every create, update, archive, issue, or revoke operation—requires owner or admin.
Choose an agent type, framework, security role, capabilities, tags, and stable slug that describe the runtime rather than a human user.
How it works
Design the identity
Any role on an active membership may search existing agents by name, slug, framework, type, status, or availability to avoid duplicates. An owner or admin can then create through /app/agents/service-agents or prepare an enrollment with the minimum claim count and lifetime.
Complete provisioning
For direct agents, issue a separate least-privilege credential. For enrollment, deliver the claim token only to the intended bootstrap process, monitor claims, and revoke any unused active enrollment.
Examples
These examples are illustrative. Replace the sample values with your own.
Keep credentials in environment variables or a secret manager, never in client-side code.
Find unavailable service agents
This query helps distinguish registered identities from runtimes currently reporting availability.
javascript
const response = await fetch("/api/v1/operator/service_agents?filter%5Bavailability%5D=offline", {
credentials: "same-origin",
headers: {"Accept": "application/json"}
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${body.detail}`);
console.log(body);
What to expect
200 OK with {"service_agents": []} when none match. Populated rows include status, security_role, availability, last_seen_at, credentials metadata, and optional robot summary.
Troubleshooting
A machine credential cannot provision peers
Enrollment and service-agent management are session-only owner/admin operations. Use the operator UI or a CSRF-aware same-origin client; public machine scopes do not cross this boundary.
A claimed token returns conflict
The enrollment may be expired, revoked, or already at its claim limit. Have an owner or admin read the enrollment list and create a fresh bounded token rather than reusing a consumed one.
Endpoint reference
Ready to integrate? Open an endpoint for its required permissions, request fields,
response format, and status codes. The examples above explain the workflow;
these details define each individual request.
GET
/api/v1/operator/agent_enrollments
Web Session
List agent enrollments
Description
Lists enrollment history for the active workspace without exposing token secrets. Owner or admin membership is required, matching create and revoke.
Auth
Web Session
Responses
200
Agent enrollment history
403
Owner or admin membership required
POST
/api/v1/operator/agent_enrollments
Web Session
Create an agent or fleet enrollment token
Description
Creates a short-lived enrollment token. A single-use token (`max_claims` of 1, the default) also creates the canonical service-agent identity, and robot enrollments create and link the robot record. A fleet claim token (`max_claims` > 1) creates no identity up front — each claim mints its own. Owner or admin membership is required. The same mint/revoke surface is /app/agents/enrollments in the operator console.
Auth
Web Session
Request Body
Field
Type
Required
Description
enrollment
object
Yes
Agent or robot enrollment attributes
enrollment.name
string
Yes
Agent or robot name
enrollment.kind
string (agent, robot)
No
Enrollment kind
enrollment.scopes
array<object>
No
Explicit scopes overriding the preset
enrollment.cohort_id
string
No
Cohort every claimed unit joins. Cleared if the cohort is deleted.
enrollment.serial_number
string
No
Required for robot enrollments
enrollment.robot_type
string (amr, drone, manipulator, humanoid)
No
Robot type
enrollment.default_tags
array<object>
No
Tags applied to every claimed unit (lowercased and trimmed)
enrollment.expires_in_minutes
integer
No
Token lifetime from 5 to 1440 minutes
enrollment.max_claims
integer
No
How many times the token may be claimed (1 to 1000, default 1). Above 1 the token becomes a fleet claim token.
enrollment.scope_preset
string (read_only, worker, robot)
No
Minimal preconfigured scope set
enrollment.serial_allowlist
array<object>
No
Serial numbers permitted to claim this token. Empty means any serial is accepted.
Responses
201
Enrollment created; token returned once
403
Owner or admin membership required
422
Validation error, including cohort_id not belonging to this workspace (detail "invalid cohort")
429
Plan agent or robot quota reached while creating the single-use identity (type problems/quota-exceeded). Fleet claim tokens (max_claims > 1) do not create an identity up front and do not hit this gate on create.
DELETE
/api/v1/operator/agent_enrollments/:id
Web Session
Revoke an active enrollment
Description
Invalidates an enrollment token that has not been used up.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
id
path
string
Yes
Enrollment UUID
Responses
200
Enrollment revoked
403
Owner or admin membership required
404
Enrollment not found
409
Enrollment is no longer active
GET
/api/v1/operator/service_agents
Web Session
List service agents
Description
Returns one page of the current workspace's service agents, ordered by name. Pass next_cursor back as cursor for the next page; it is null on the last page. Each agent's api_credentials lists only its live (unrevoked, unarchived) credentials; GET /api/v1/operator/service_agents/:id returns the full credential history.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
query
query
string
No
Search name, slug, framework, or agent type
status
query
string
No
Filter by lifecycle status
availability
query
string
No
Filter by runtime availability
limit
query
integer
No
Maximum service agents to return (default 100, maximum 500)
cursor
query
string
No
Opaque next_cursor from the previous page
Responses
200
List of service agents
Response Body
Field
Type
Required
Description
next_cursor
string
No
Opaque cursor for the next page; null on the last page
service_agents
array<object>
Yes
Array of service agents
service_agents[].id
string
Yes
Service agent UUID
service_agents[].name
string
Yes
Service agent name
service_agents[].status
string (active, paused, revoked)
Yes
Current status
service_agents[].description
string
No
Description
service_agents[].metadata
object
No
Arbitrary metadata
service_agents[].inserted_at
datetime (ISO 8601)
Yes
Creation time
service_agents[].updated_at
datetime (ISO 8601)
Yes
Last update time
service_agents[].tags
array<string>
No
Tags
service_agents[].slug
string
Yes
URL-safe slug
service_agents[].agent_type
string
No
Agent type
service_agents[].capabilities
array<string>
No
Declared capabilities
service_agents[].framework
string
No
Framework name
service_agents[].framework_version
string
No
Framework version
service_agents[].availability
string
No
Current availability
service_agents[].last_seen_at
datetime (ISO 8601)
No
Last heartbeat or activity time
service_agents[].robot
object
No
Assigned robot summary, null when unassigned
service_agents[].robot.id
string
Yes
Robot UUID
service_agents[].robot.name
string
Yes
Robot name
service_agents[].robot.status
string
Yes
Robot status
service_agents[].robot.serial_number
string
No
Serial number
service_agents[].robot.robot_type
string
No
Robot type
service_agents[].security_role
string (admin, operator, agent)
Yes
Security role for gateway authorization
service_agents[].archived_at
datetime (ISO 8601)
No
Archive timestamp
service_agents[].last_token_issued_at
datetime (ISO 8601)
No
Last API key issuance time
service_agents[].api_credentials
array<object>
Yes
API credentials (live only on index; full history on show)
Creates a new service agent in the current workspace. The slug is auto-generated from the name if not provided. The slug account-api is reserved for the workspace's primary-key identity.
Auth
Web Session
Request Body
Field
Type
Required
Description
service_agent
object
Yes
Service agent attributes
service_agent.name
string
Yes
Service agent name (2-120 characters)
service_agent.status
string (active, paused, revoked)
No
Initial status
service_agent.description
string
No
Service agent description
service_agent.metadata
object
No
Arbitrary metadata key-value pairs
service_agent.slug
string
No
URL-safe slug (auto-generated from name if omitted)
service_agent.security_role
string (admin, operator, agent)
No
Security role for gateway authorization (defaults to 'agent')
Updates a service agent's configuration. slug, archived_at, last_seen_at and last_token_issued_at are ignored (archive with DELETE, which also revokes the agent's credentials), as are the reserved metadata keys kind and system.
Archives a service agent: sets archived_at (status becomes revoked for an active agent), revokes all of its live credentials, disconnects their sockets and revokes its unclaimed enrollments. The row is kept and GET /api/v1/operator/service_agents/:id still returns it with archived_at set.