Provision and manage multi-cloud AI-agent containers, Virtual Workers, terminal sessions, sandbox environments, and the code-API tool-bridge used by in-container agents to act on behalf of the authenticated user.
GET /cli/connect
CLI WebSocket connect
Upgrades to a WebSocket connection routed to the `CLIController` Durable Object. The JWT session token must be passed as the `Sec-WebSocket-Protocol` header value. This is the persistent control-channel connection used by the `bb` CLI and IDE extensions.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
Upgrade | header | string (enum) | yes | Must be `websocket`. |
Responses
| Status | Description |
101 | WebSocket upgrade successful. The connection is now routed to the CLIController DO. |
401 | Missing or invalid session token. |
426 | Upgrade required. The `Upgrade: websocket` header was absent. |
GET /cli/connections
List active CLI connections (admin)
Returns metadata about active CLIController DO connections. Requires administrator-level authentication.
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | Active connection list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
GET /cli/health
CLI service health
Returns a lightweight liveness probe for the CLI WebSocket service. No authentication required.
Public Public: no authentication
Responses
| Status | Description |
200 | Service healthy. |
GET /cli/info
CLI service info
Returns service version and capability metadata used by the CLI to negotiate protocol versions. No authentication required.
Public Public: no authentication
Responses
| Status | Description |
200 | Service info. |
GET /cli/test
CLI WebSocket test page
Returns an HTML page for manually testing CLI WebSocket connections. Intended for development and diagnostics only. No authentication required.
Public Public: no authentication
Responses
| Status | Description |
200 | HTML test page. |
GET /v1/containers/.well-known/jwks.json
Get container token JWKS
Returns the Ed25519 public key set (JWKS) used to verify container connect tokens and data tokens offline (alg=EdDSA). Serves the public key only — the private signing key is never reachable here. Returns an empty key set (200) when no key is configured so a verifier always receives a well-formed JWKS. Cache-Control is set to `public, max-age=300`; verifiers should refresh after that window.
Public Public: no authentication
Responses
| Status | Description |
200 | The JWKS. `keys` contains zero or one Ed25519 public key entry. |
GET /v1/containers/{sessionId}
Get container session status
Returns the current status and metadata for a container session. Sessions belonging to another organization are reported as `404 NOT_FOUND` (anti-enumeration).
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Container session identifier (UUID). |
Responses
| Status | Description |
200 | The session record. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | Session identifier. |
org_id | string<uuid> | Owning organization. |
env_id | string<uuid> | Active environment. |
user_id | string<uuid> | User who owns this session. |
project_id | string | null | Project binding, if any. |
backend | string (enum) cloudflarecontaboawsgcpazureoracle | Supported container backend providers. |
size_key | string | Size key used. |
kind | string (enum) ai_assistantvirtual_worker | Session kind. |
status | string (enum) provisioningrunningidlestoppedteardownerror | Current lifecycle status. |
endpoint | string | null | Public gateway URL when the ingress domain is configured. null otherwise. |
created_at | string<date-time> | |
updated_at | string<date-time> | |
DELETE /v1/containers/{sessionId}
Tear down a container session
Gracefully stops the container and marks the session as torn down. An optional `reason` query parameter is recorded in the audit trail.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Container session identifier (UUID). |
reason | query | string | no | Human-readable teardown reason recorded in the audit trail. |
Responses
| Status | Description |
200 | Session torn down. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | Session identifier. |
org_id | string<uuid> | Owning organization. |
env_id | string<uuid> | Active environment. |
user_id | string<uuid> | User who owns this session. |
project_id | string | null | Project binding, if any. |
backend | string (enum) cloudflarecontaboawsgcpazureoracle | Supported container backend providers. |
size_key | string | Size key used. |
kind | string (enum) ai_assistantvirtual_worker | Session kind. |
status | string (enum) provisioningrunningidlestoppedteardownerror | Current lifecycle status. |
endpoint | string | null | Public gateway URL when the ingress domain is configured. null otherwise. |
created_at | string<date-time> | |
updated_at | string<date-time> | |
POST /v1/containers/{sessionId}/connect
Issue a connect ticket and UI token
Issues a one-time WebSocket connect ticket and a short-TTL Ed25519 UI connect token for the specified session. The ticket is a single-use opaque capability redeemed by the in-container gateway on the WebSocket upgrade; the connect token is an Ed25519 JWT presented to the gateway. Both are bound to the calling user and the session id. The session must be in `running` or `idle` state and must belong to the calling user's org/env. Also returns the public gateway URL (`endpoint`) when the ingress domain is configured.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Container session identifier (UUID). |
Responses
| Status | Description |
200 | Connect ticket and UI token issued. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | `PERMISSION_DENIED` (not the session owner) or `FORBIDDEN` (session not in a live state). |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
ticket | string | Single-use, short-TTL opaque ticket redeemed by the in-container gateway on the WebSocket upgrade. |
connect_token | string | Short-TTL Ed25519 UI connect token (JWT) presented to the in-container gateway to authorize the UI connection. |
connect_token_ttl_seconds | integer | Remaining TTL of the connect token in seconds. |
session_id | string<uuid> | The session this connect pair was issued for. |
endpoint | string | null | Public gateway URL (e.g. `https://containers.example.com/s/<sessionId>/`). Null when the ingress domain is not configured. |
expires_at | string | null | Ticket expiry timestamp. |
GET /v1/containers/data/agent/task
Pull the next agent task for a Virtual Worker session
The in-pod agentic CLI runner pulls the task dispatched to this session. The session is resolved from the verified data token (IDOR guard). Requires scope `agent.task.read`. Returns `null` when no task is pending.
Auth Container data token
Responses
| Status | Description |
200 | The pending agent task, or null when no task is queued. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | `FORBIDDEN` — the data token lacks scope `agent.task.read`. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
task_id | string<uuid> | Task identifier. |
virtual_worker_id | string<uuid> | The Virtual Worker this task belongs to. |
source | string | Task source (e.g. `ticket`, `chat`, `scheduled`). |
ref_kind | string | null | Kind of the linked entity (if any). |
ref_id | string | null | ID of the linked entity (if any). |
payload | any | Task-specific payload. |
created_at | string<date-time> | |
POST /v1/containers/data/agent/task/complete
Report Virtual Worker task completion
The in-pod runner reports the task result. `virtual_worker_id` and `worker_task_id` come from the task pull; the server re-validates both belong to this session (any mismatch is a 4xx). Requires scope `agent.task.complete`. Bridges to the cron-gated completion stored procedure using a platform-side credential the agent never holds.
Auth Container data token
Request Body
| Field | Type | Required | Description |
virtual_worker_id | string<uuid> | yes | The Virtual Worker the completed task belongs to. Must match the session's bound worker. |
worker_task_id | string<uuid> | yes | The task identifier returned by the task pull. Server re-validates ownership. |
task_status | string | no | Final task status to record (e.g. `completed`, `failed`). |
last_error | string | null | no | Error message when `task_status` is `failed`. |
result | any | no | Structured task result payload. |
messages | array of object | no | Conversation messages to record with the turn. |
Responses
| Status | Description |
200 | Task completion recorded. |
400 | `VALIDATION_ERROR` — `virtual_worker_id` or `worker_task_id` is missing. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | `FORBIDDEN` — the data token lacks scope `agent.task.complete`, or the delegated denylist blocked this call. |
404 | `NOT_FOUND` — the `virtual_worker_id` or `worker_task_id` does not belong to this session. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
503 | `SERVICE_UNAVAILABLE` — task completion is not configured. |
GET /v1/containers/data/session
Get the agent's own container session status
Returns the container session record for the calling agent's own session. The session id is taken from the verified data token — the agent cannot read another session by guessing an id. Authorized by the container data token.
Auth Container data token
Responses
| Status | Description |
200 | The container session record. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | Session identifier. |
org_id | string<uuid> | Owning organization. |
env_id | string<uuid> | Active environment. |
user_id | string<uuid> | User who owns this session. |
project_id | string | null | Project binding, if any. |
backend | string (enum) cloudflarecontaboawsgcpazureoracle | Supported container backend providers. |
size_key | string | Size key used. |
kind | string (enum) ai_assistantvirtual_worker | Session kind. |
status | string (enum) provisioningrunningidlestoppedteardownerror | Current lifecycle status. |
endpoint | string | null | Public gateway URL when the ingress domain is configured. null otherwise. |
created_at | string<date-time> | |
updated_at | string<date-time> | |
GET /v1/containers/data/session-log
Read back the agent's own session log
Lists and concatenates the persisted NDJSON chunks for the calling agent's own session in chunk-sequence order. The org and session prefix are derived from the verified data token (IDOR guard). Bounded list pagination and a concatenation cap (32 MiB, 2000 chunks) prevent unbounded buffering; `truncated: true` signals that more chunks remain.
Auth Container data token
Responses
| Status | Description |
200 | Session log chunks concatenated. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
503 | `SERVICE_UNAVAILABLE` — session-log storage is not configured. |
200 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | The session whose log was read. |
chunk_count | integer | Number of chunks concatenated. |
chunk_keys | array of string | R2 keys of the concatenated chunks in order. |
ndjson | string | Concatenated NDJSON content of all returned chunks. |
truncated | boolean | True when more chunks remain beyond the page/byte cap; re-read from the last chunk key. |
POST /v1/containers/data/session-log
Append a session-log chunk
Writes one immutable NDJSON chunk of `SessionLogEvent` records to the session's R2 log store. The org and session prefix are derived from the verified data token — the agent can only write under its own session prefix. Requires scope `terminal.activity.write`. An optional monotonic `chunk_seq` may be supplied as a query parameter or `x-session-log-chunk-seq` header to derive the object key; if omitted the key is the SHA-256 of the body (idempotent re-POST). Max size is enforced via `Content-Length` pre-check and a buffered re-check.
Auth Container data token
Parameters
| Name | In | Type | Required | Description |
chunk_seq | query | integer | no | Monotonic non-negative integer chunk sequence number. |
Request Body
Array of `SessionLogEvent` objects. Max 1 MiB total.
Responses
| Status | Description |
201 | Chunk stored. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | `FORBIDDEN` — the data token lacks scope `terminal.activity.write`, or the delegated denylist blocked this call. |
413 | `PAYLOAD_TOO_LARGE` — the chunk exceeds the maximum allowed size. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
503 | `SERVICE_UNAVAILABLE` — session-log storage is not configured. |
201 response body: data fields
| Field | Type | Description |
chunk_key | string | The R2 object key the chunk was stored under. |
event_count | integer | Number of events in this chunk. |
bytes_written | integer | Bytes persisted to R2. |
decoded_request_bytes | integer | Original body size in bytes. |
GET /v1/containers/data/sizes
List container sizes (data-plane, read context)
Returns the container size catalog for the calling agent's organization. Provisioning new containers is denied to delegated actors. Authorized by the container data token.
Auth Container data token
Responses
| Status | Description |
200 | Size catalog entries. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/containers/data/terminal/activity
Append a terminal activity batch
Writes one bounded batch of already-redacted terminal `ActivityEvent` records to the activity index. The batch's `containerSessionId` must match the principal's own session id. Requires scope `terminal.activity.write`.
Auth Container data token
Request Body
| Field | Type | Required | Description |
containerSessionId | string<uuid> | yes | Must match the principal's own session id. |
terminalId | string | yes | Terminal identifier within the session. |
seqFrom | integer | yes | First event sequence number in this batch. |
seqTo | integer | yes | Last event sequence number in this batch. |
events | array of object | yes | Array of already-redacted `ActivityEvent` objects. |
redactionClasses | array of string | no | Redaction classes applied to this batch. |
cols | integer | no | Terminal column count. |
rows | integer | no | Terminal row count. |
emulation | string | no | Terminal emulation (e.g. `xterm-256color`). |
Responses
| Status | Description |
200 | Activity batch recorded. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | `FORBIDDEN` — scope `terminal.activity.write` missing, `containerSessionId` mismatch, or delegated denylist blocked this call. |
413 | `PAYLOAD_TOO_LARGE` — the batch exceeds the maximum allowed size. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/containers/data/terminal/transcript
Append a terminal bulk-transcript segment
Writes one immutable terminal bulk-transcript segment (redacted NDJSON, ≤16 MiB) to R2 keyed by the principal's org/session prefix, then records the R2 key and advances the monotonic segment watermark in the database. `transcript_seq` is required; `terminal_id` is optional but recommended. Both may be supplied as query parameters or the `x-terminal-id` / `x-transcript-seq` headers. Requires scope `terminal.activity.write`.
Auth Container data token
Parameters
| Name | In | Type | Required | Description |
terminal_id | query | string | no | Terminal identifier. Also accepted via `x-terminal-id` header. |
transcript_seq | query | integer | no | Monotonic non-negative integer segment sequence number. Also accepted via `x-transcript-seq` header. |
Responses
| Status | Description |
200 | Segment persisted and watermark advanced. |
400 | `VALIDATION_ERROR` — `transcript_seq` is missing or invalid, body is empty or unreadable, or terminal id is invalid. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | `FORBIDDEN` — scope `terminal.activity.write` missing, or delegated denylist blocked this call. |
413 | `PAYLOAD_TOO_LARGE` — the segment exceeds 16 MiB. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
503 | `SERVICE_UNAVAILABLE` — transcript storage is not configured. |
GET /v1/containers/data/whoami
Get the in-container agent's own identity
Returns the resolved identity of the in-container agent — user id, org id, environment id, session id, and delegated scope set — derived offline from the verified data token. No database call is made. Authorized by the container data token.
Auth Container data token
Responses
| Status | Description |
200 | The agent's resolved identity. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
200 response body: data fields
| Field | Type | Description |
user_id | string<uuid> | User the session was provisioned for. |
org_id | string<uuid> | Organization. |
env_id | string<uuid> | Active environment. |
session_id | string<uuid> | Container session. |
scope | array of string | Least-privilege delegated scope set minted at provisioning time. |
GET /v1/containers/gw/{sizeKey}/{sessionId}/code-api-config
Fetch code-API config for a CF sandbox container
Used by a Cloudflare sandbox container to retrieve its per-session code-API configuration (bridge URL and short-TTL bridge token). The container presents its `x-bb-config-fetch` credential in a request header; the API validates it against the session's stored hash via the backing Durable Object. Returns only `{ bridge_url, token }` — never the secret reference or refresh credential. `Cache-Control: no-store` is always set. Returns `401` for an invalid/missing credential and `404` for an unknown size or session.
Public Public: no authentication
Parameters
| Name | In | Type | Required | Description |
sizeKey | path | string | yes | Canonical sandbox size key (e.g. `standard-1`). Used to route to the correct Durable Object namespace. |
sessionId | path | string | yes | Container session identifier used as the Durable Object name. |
x-bb-config-fetch | header | string | yes | Per-session config-fetch credential injected into the container at provision time. |
Responses
| Status | Description |
200 | Bridge URL and short-TTL token returned. |
401 | `AUTH_REQUIRED` — the config-fetch credential is missing, invalid, or already used. |
404 | `NOT_FOUND` — unknown `sizeKey` or no gateway bundle for this session. |
GET /v1/containers/policy
Get org container execution policy
Returns the organization-wide container execution policy (allowed backends, sizes, default backend/size, idle settings, billing mode, residency constraints, and the master on/off toggle). The organization is resolved from the session.
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | The org container execution policy. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
containers_enabled | boolean | null | Master on/off toggle. When false, container provisioning is blocked for every member of the org and environment. |
allowed_backends | array | null | Backends members may use. null = all configured backends. |
allowed_sizes | array | null | Size keys members may request. null = all available sizes. |
default_backend | string (enum) cloudflarecontaboawsgcpazureoracle | Supported container backend providers. |
default_size | string | null | Size key used when the caller does not specify one. |
user_selectable | boolean | null | Whether members may choose a backend/size other than the defaults. |
idle_grace_seconds | integer | null | How long an idle container waits before the reap timer starts. |
idle_reap_seconds | integer | null | How long after idle grace expires before the container is stopped. |
idle_billing_mode | string (enum) stop_at_idlebill_until_reap | Whether billing stops at idle or at reap. |
max_concurrent | integer | null | Maximum simultaneous sessions across the org. 0 = unlimited. |
data_residency_regions | array | null | Allowed data-residency region identifiers. null = no restriction. |
GET /v1/containers/policy/projects/{projectId}
Get per-project container policy override
Returns the per-project container execution policy override. When no override is set all fields are null, meaning the project inherits the org policy.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
projectId | path | string<uuid> | yes | Project identifier (UUIDv7). |
Responses
| Status | Description |
200 | The per-project policy override (null fields = inherit org policy). |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
containers_enabled | boolean | null | null = inherit org toggle. |
allowed_backends | array | null | null = inherit org allow-set. |
allowed_sizes | array | null | null = inherit org allow-set. |
GET /v1/containers/saas/{packageId}/config
Get SaaS package container config
Returns the container configuration for a SaaS package, including whether containers are enabled and which backends and sizes the package's subscribers may use.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
packageId | path | string<uuid> | yes | SaaS package identifier (UUID). |
Responses
| Status | Description |
200 | SaaS package container configuration. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
containers_enabled | boolean | Whether containers are enabled for this package's subscribers. |
allowed_backends | array | null | |
allowed_sizes | array | null | |
GET /v1/containers/sizes
List container size catalog
Returns the container size catalog entries available to the caller's organization, including CPU, memory, and per-hour credit cost for each size and backend combination.
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | The size catalog entries. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/sandbox
Provision a sandbox container
Provision a new Cloudflare Container DO sandbox session. Generates a session ID, registers billing, and starts the container. The orgId is prepended to all R2 artifact paths to prevent cross-org IDOR.
The caller needs `project.update` permission when a `project_id` is provided.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
sessionId | string<uuid> | no | Optional caller-supplied session ID. If omitted the server generates one. |
size | string (enum) smallstandardlarge | no | Container size class. Maps to `SandboxContainerSmall`, `SandboxContainerStandard`, or `SandboxContainerLarge`. |
gitRepo | string | no | Optional Git repository to clone on startup. |
gitBranch | string | no | Branch or ref to check out. Defaults to the repo default branch. |
envVars | object | no | Environment variables injected at container start. |
language | string | no | Runtime language hint (e.g. `node`, `python`). |
project_id | string<uuid> | no | Optional project to attribute this session to. |
metadata | object | no | Arbitrary metadata stored with the session. |
timeout_seconds | integer | no | Idle-timeout override in seconds. |
Responses
| Status | Description |
201 | Sandbox provisioned successfully. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
201 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | Session identifier. |
org_id | string<uuid> | Owning organization. |
env_id | string<uuid> | Active environment. |
user_id | string<uuid> | User who owns this session. |
project_id | string | null | Project binding, if any. |
backend | string (enum) cloudflarecontaboawsgcpazureoracle | Supported container backend providers. |
size_key | string | Size key used. |
kind | string (enum) ai_assistantvirtual_worker | Session kind. |
status | string (enum) provisioningrunningidlestoppedteardownerror | Current lifecycle status. |
endpoint | string | null | Public gateway URL when the ingress domain is configured. null otherwise. |
created_at | string<date-time> | |
updated_at | string<date-time> | |
GET /v1/sandbox/artifacts/{sessionId}
List sandbox artifacts
Lists R2 artifact objects for this sandbox session. Each key is prefixed with the org ID to prevent cross-org object enumeration.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
200 | Artifact list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | |
artifacts | array of object | |
GET /v1/sandbox/artifacts/{sessionId}/{name}
Download a sandbox artifact
Downloads a specific named artifact from R2. The `Content-Type` header is enforced based on safe file extension mapping — arbitrary types are not forwarded from R2 metadata to prevent content-type sniffing attacks.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
name | path | string | yes | Artifact name (filename). |
Responses
| Status | Description |
200 | Artifact file contents. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/sandbox/display/{sessionId}
Redirect to remote display (Xpra)
302 redirect to the Xpra remote-display endpoint proxied through `/v1/sandbox/proxy/{sessionId}/xpra/`. Requires the proxy cookie to be set first.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
302 | Redirect to `/v1/sandbox/proxy/{sessionId}/xpra/`. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
GET /v1/sandbox/egress/{sessionId}
Sandbox egress proxy (GET)
Proxies an HTTP GET from the sandbox to an external domain. The target URL must be supplied via the `x-bb-egress-target` header or the `target` query parameter. The domain is validated against the org's egress allowlist, and egress byte usage is reserved before forwarding. Requires `project.update` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
x-bb-egress-target | header | string | no | Full target URL to proxy the request to. Takes precedence over the `target` query parameter. |
target | query | string | no | Full target URL when the header is absent. |
Responses
| Status | Description |
200 | Upstream response proxied transparently. |
400 | Missing or invalid egress target. Error code: `INVALID_REQUEST`. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | Domain not in allowlist or egress quota exceeded. Error codes: `FORBIDDEN`, `LIMIT_EXCEEDED`. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/sandbox/egress/{sessionId}
Sandbox egress proxy (POST)
Proxies an HTTP POST from the sandbox to an external domain. Same domain allowlist and quota reservation as GET. Requires `project.update` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
x-bb-egress-target | header | string | no | Full target URL. |
target | query | string | no | Full target URL when the header is absent. |
Responses
| Status | Description |
200 | Upstream response proxied transparently. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/sandbox/jupyter/{sessionId}
Redirect to Jupyter Lab
302 redirect to the Jupyter Lab endpoint proxied through `/v1/sandbox/proxy/{sessionId}/jupyter/lab`. Requires the proxy cookie to be set first.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
302 | Redirect to `/v1/sandbox/proxy/{sessionId}/jupyter/lab`. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
POST /v1/sandbox/proxy-session/{sessionId}
Create a sandbox proxy cookie
Mints a short-lived (5-minute) `__Secure-bb_sandbox_proxy` cookie (HttpOnly, Secure, SameSite=None) that authorises transparent proxying through `/v1/sandbox/proxy/{sessionId}/*`. Rate-limited.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session to issue the proxy cookie for. |
Responses
| Status | Description |
200 | Proxy cookie set in the `Set-Cookie` response header. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
429 | 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/sandbox/proxy-session/revoke-all
Revoke all sandbox proxy cookies for the current user
Invalidates every active `__Secure-bb_sandbox_proxy` HttpOnly cookie previously issued to the authenticated user. Call this on logout or credential rotation.
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | All proxy cookies revoked. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/sandbox/proxy/{sessionId}/{path}
Transparent proxy into sandbox container
Transparently proxies any HTTP method into the running Cloudflare Container DO for this session. Authentication is via the `__Secure-bb_sandbox_proxy` cookie issued by `POST /v1/sandbox/proxy-session/{sessionId}`. All traffic is org-scoped at the DO level — the orgId prefix in the container name prevents cross-org IDOR.
Public Public: no authentication
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
path | path | string | yes | Remainder of the path inside the container. |
Responses
| Status | Description |
200 | Response from the container application proxied transparently. |
401 | Missing or invalid proxy cookie. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
POST /v1/sandbox/resume/{sessionId}
Resume a stopped sandbox session
Re-starts a previously stopped sandbox session and restores its last snapshot. Requires `project.update` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
200 | Session resume initiated. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/sandbox/snapshot-info/{sessionId}
Get sandbox snapshot metadata
Returns metadata for the most recent R2 snapshot of this sandbox session, if one exists.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
200 | Snapshot metadata. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | |
snapshot_key | string | null | |
snapshot_size | integer | null | |
snapshot_uploaded | string | null | |
GET /v1/sandbox/status/{sessionId}
Get sandbox session status
Returns the live status of a sandbox session, including container state, whether the session can be resumed, and sandbox-specific metadata.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
200 | Session status retrieved. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
active | boolean | |
status | string | |
session | object | A container session record. |
container | object | null | Raw container state from the DO. |
canResume | boolean | |
sandboxInfo | object | null | |
POST /v1/sandbox/teardown/{sessionId}
Tear down a sandbox session
Stops the container, finalises billing, and deletes the session. Requires `project.update` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
200 | Sandbox torn down. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/sandbox/terminal/{sessionId}
Sandbox terminal action
Perform a terminal action inside the sandbox: create a named multiplexed terminal, write input, read pending output, or execute a one-shot command. Requires `project.update` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Request Body
| Field | Type | Required | Description |
action | string (enum) createwritereadexec | yes | Terminal sub-action. |
sessionName | string | no | Named multiplexed terminal session (for `create`, `write`, `read`). |
input | string | no | Input data to write (for `write`). |
command | string | no | Shell command to execute (for `exec`). |
timeout | integer | no | Execution timeout in seconds (for `exec`). Defaults to 30. |
workdir | string | no | Working directory (for `exec`). |
Responses
| Status | Description |
200 | Terminal action succeeded. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/sandbox/vscode/{sessionId}
Redirect to VS Code server
302 redirect to the VS Code code-server endpoint proxied through `/v1/sandbox/proxy/{sessionId}/code-server/`. Requires the proxy cookie to be set first via `POST /v1/sandbox/proxy-session/{sessionId}`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
sessionId | path | string<uuid> | yes | Sandbox session ID. |
Responses
| Status | Description |
302 | Redirect to `/v1/sandbox/proxy/{sessionId}/code-server/`. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
GET /v1/terminal/sessions
List terminal sessions
Returns a filtered list of the user's terminal sessions for the authenticated org.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
status_filter | query | string (enum) | no | Filter by session status. |
host_machine_id | query | string | no | Filter by host machine ID. |
cli_tool | query | string | no | Filter by CLI tool identifier. |
include_terminated | query | boolean | no | When true, include terminated sessions. |
limit | query | integer | no | Maximum number of sessions to return. Defaults to 50. |
Responses
| Status | Description |
200 | Session list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
sessions | array of object | |
POST /v1/terminal/sessions
Create a terminal session
Registers a new CLI/IDE terminal session and returns a one-time producer ticket used to upgrade the WebSocket connection at `GET /v1/terminal/ws`.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
org_id | string<uuid> | yes | Organization to create the session under. |
cli_tool | string | yes | Identifier of the CLI tool creating the session (e.g. `bb-cli`, `vscode-extension`). |
cwd | string | yes | Current working directory on the host machine. |
host_machine_id | string | yes | Stable identifier of the host machine. |
host_extension_id | string | no | Extension or plugin instance identifier on the host. |
cli_session_id | string<uuid> | no | Optional caller-supplied session ID. |
cli_args | array of string | no | CLI arguments passed to the tool. |
cli_display_name | string | no | Human-readable name shown in the session list. |
parent_session_id | string<uuid> | no | Optional parent terminal session for nested shells. |
Responses
| Status | Description |
201 | Session created. The producer_ticket is single-use and short-lived. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
409 | 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate). |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
201 response body: data fields
| Field | Type | Description |
session | object | Created session record. |
producer_ticket | string | Single-use ticket to present as the WebSocket protocol on `GET /v1/terminal/ws`. |
ticket_expires_in_seconds | integer | TTL of the producer ticket. |
POST /v1/terminal/sessions/{id}/join
Join a terminal session as a consumer
Returns a single-use consumer ticket that authorises a read-only (or read-write if `can_input` is true) WebSocket connection to the terminal session DO.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Terminal session ID. |
Responses
| Status | Description |
200 | Consumer ticket issued. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
session_id | string<uuid> | |
can_input | boolean | Whether the consumer is permitted to send input. |
consumer_ticket | string | Single-use ticket for the WebSocket upgrade. |
ticket_expires_in_seconds | integer | |
POST /v1/terminal/sessions/{id}/mark-resumed
Mark a terminal session as active after resumption
Flips a previously-terminated session back to `active` status after the host extension has successfully reconnected. Optionally updates the extension instance ID.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Terminal session ID. |
Request Body
| Field | Type | Required | Description |
host_extension_id | string | no | Updated extension instance identifier, if changed. |
Responses
| Status | Description |
200 | Session flipped to active. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/terminal/sessions/{id}/resume
Resume a terminal session
Returns the resume argv and a fresh producer ticket to reconnect the producer WebSocket for a previously disconnected session.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Terminal session ID. |
Responses
| Status | Description |
200 | Resume info with a fresh producer ticket. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
resume_argv | array of string | |
producer_ticket | string | |
ticket_expires_in_seconds | integer | |
POST /v1/terminal/sessions/{id}/terminate
Terminate a terminal session
Marks a terminal session as terminated and closes the associated WebSocket connections.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Terminal session ID. |
Request Body
| Field | Type | Required | Description |
reason | string (enum) usertimeouthost_exiterrorinactivityadmin | yes | Reason for termination. |
Responses
| Status | Description |
200 | Session terminated. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/terminal/ws
Terminal session WebSocket upgrade
Upgrades to a WebSocket connection routed to the `TerminalSessionDO` for the given session. The one-time ticket previously issued by `POST /v1/terminal/sessions` (producer) or `POST /v1/terminal/sessions/{id}/join` (consumer) must be passed as the `Sec-WebSocket-Protocol` header value. The ticket is single-use and short-lived; it is consumed on the first valid upgrade and cannot be reused.
Auth One-time ?token= ticket
Parameters
| Name | In | Type | Required | Description |
ticket | query | string | yes | Single-use session ticket. |
Upgrade | header | string (enum) | yes | Must be `websocket`. |
Responses
| Status | Description |
101 | WebSocket upgrade successful. The connection is now routed to the TerminalSessionDO. |
401 | Missing, expired, or already-used ticket. |
426 | Upgrade required. The `Upgrade: websocket` header was not present. |
GET /v1/virtual-workers
List Virtual Workers
Returns all Virtual Workers accessible to the authenticated user within the current org.
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | Worker list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers
Create a Virtual Worker
Creates a new Virtual Worker for the authenticated org. The worker is created in `paused` status and must be explicitly resumed before it will process tasks.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
display_name | string | yes | Human-readable worker name. |
job_role | string | no | Semantic role label. |
role_key | string | no | Machine-readable role key. |
container_size | string | no | Preferred container size. |
execution_mode | string (enum) synchronousasync | no | Execution mode. |
manager_kind | string | no | Manager type. |
manager_id | string<uuid> | no | Manager ID. |
timezone | string | no | IANA timezone identifier. |
system_prompt | string | no | Worker-level system prompt. |
Responses
| Status | Description |
201 | Virtual Worker created. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
409 | 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate). |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
201 response body: data fields
| Field | Type | Description |
id | string<uuid> | Worker ID. |
org_id | string<uuid> | Owning organization. |
display_name | string | Human-readable worker name. |
job_role | string | null | Semantic role label (e.g. `Support Agent`, `Code Reviewer`). |
role_key | string | null | Machine-readable role key. |
container_size | string | null | Preferred container size for this worker's sessions. |
execution_mode | string | null | Execution mode (`synchronous` or `async`). |
manager_kind | string | null | Manager type (e.g. `user`, `worker`). |
manager_id | string | null | Manager ID when `manager_kind` is set. |
timezone | string | null | IANA timezone identifier for shift scheduling. |
system_prompt | string | null | Worker-level system prompt prepended to every conversation. |
status | string (enum) activepausedretired | Current worker status. |
created_at | string<date-time> | |
updated_at | string<date-time> | |
POST /v1/virtual-workers/{id}/approvals
Request an autonomy approval
Creates a pending approval request for an action that this worker's autonomy policy requires human sign-off on before proceeding.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Request Body
| Field | Type | Required | Description |
worker_task_id | string<uuid> | yes | The task ID requesting approval. |
capability | string | yes | The capability the worker wants to exercise. |
reason | string | no | Worker-supplied justification for the requested action. |
Responses
| Status | Description |
201 | Approval request created and queued for review. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/virtual-workers/{id}/claude-link
List Claude Max connections
Returns all Claude Max OAuth connections linked to this Virtual Worker.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Responses
| Status | Description |
200 | Connection list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
DELETE /v1/virtual-workers/{id}/claude-link/{connectionId}
Revoke a Claude Max connection
Revokes and deletes a Claude Max OAuth connection from this Virtual Worker.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
connectionId | path | string<uuid> | yes | Connection ID to revoke. |
Responses
| Status | Description |
200 | Connection revoked. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers/{id}/claude-link/complete
Complete Claude Max OAuth link
Completes the server-side PKCE token exchange using the authorization code returned by the Claude OAuth callback. The resulting access token is encrypted at rest.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Request Body
| Field | Type | Required | Description |
link_token | string | yes | Opaque token returned by `/start`. |
code | string | yes | Authorization code from the Claude OAuth callback. |
account_label | string | no | Human-readable label for this connection. |
Responses
| Status | Description |
201 | Claude Max account linked. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
409 | 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate). |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers/{id}/claude-link/start
Start Claude Max OAuth link (PKCE)
Initiates PKCE OAuth flow to link a Claude Max account to this Virtual Worker. Returns an authorization URL to redirect the user to, plus a `link_token` to present on completion.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Responses
| Status | Description |
200 | PKCE flow initiated. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
authorize_url | string | Claude authorization URL. Redirect the user here. |
link_token | string | Opaque token to present when calling `/complete`. |
state | string | PKCE state parameter. |
POST /v1/virtual-workers/{id}/dispatch
Dispatch next queued task to a Virtual Worker
Claims the next pending task from the worker's dispatch queue, runs the AI turn, records it, and optionally posts the result as a note. Returns `claimed: false` when the queue is empty.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Responses
| Status | Description |
200 | Dispatch result. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
claimed | boolean | Whether a task was dequeued and run. False when the queue is empty. |
task_id | string<uuid> | ID of the claimed task. Present when `claimed` is true. |
source | string | Task source (e.g. `ticket`, `chat`). |
conversation_id | string<uuid> | Conversation ID for the AI run. |
ok | boolean | Whether the AI turn succeeded. |
note_posted | boolean | Whether a result note was posted back to the task source. |
POST /v1/virtual-workers/{id}/email
Assign an email mailbox to a Virtual Worker
Binds a bbmail mailbox to this Virtual Worker so incoming messages create tasks in the worker's dispatch queue.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Request Body
| Field | Type | Required | Description |
mailbox_id | string<uuid> | yes | Mailbox ID to bind. |
Responses
| Status | Description |
200 | Mailbox assigned. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/virtual-workers/{id}/holidays
List Virtual Worker holidays
Returns all configured holiday dates for a Virtual Worker. The worker will not process tasks on holiday dates.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Responses
| Status | Description |
200 | Holiday list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers/{id}/holidays
Add a holiday to a Virtual Worker
Adds a specific date on which the Virtual Worker will not process tasks.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Request Body
| Field | Type | Required | Description |
holiday_date | string<date> | yes | Holiday date in `YYYY-MM-DD` format. |
label | string | no | Human-readable label for this holiday. |
is_full_day | boolean | no | Whether the full day is blocked. Defaults to true. |
Responses
| Status | Description |
201 | Holiday added. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
409 | 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate). |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
DELETE /v1/virtual-workers/{id}/holidays/{holidayId}
Delete a Virtual Worker holiday
Removes a previously-added holiday date from the worker.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
holidayId | path | string<uuid> | yes | Holiday entry ID. |
Responses
| Status | Description |
200 | Holiday removed. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers/{id}/run-task
Run a task on a Virtual Worker (direct)
Synchronously runs a real AI turn against this Virtual Worker using the worker's system prompt, tools, and Claude Max connection. Records the turn via the worker session. Returns the AI response and token usage.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Request Body
| Field | Type | Required | Description |
prompt | string | yes | User message to send to the worker. |
task_id | string<uuid> | no | Optional task ID to associate with this run for billing and audit. |
Responses
| Status | Description |
200 | Task run completed. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
200 response body: data fields
| Field | Type | Description |
conversation_id | string<uuid> | |
ok | boolean | |
response | string | AI text response. |
usage | object | Token usage counters. |
GET /v1/virtual-workers/{id}/shares
List Virtual Worker shares
Returns all active capability shares for this Virtual Worker, including cross-org shares.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Responses
| Status | Description |
200 | Share list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers/{id}/shares
Create a Virtual Worker share
Grants a specific capability of this Virtual Worker to a target user, org, or public. Use `scope: 'public'` to enable org-external invocation.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
Request Body
| Field | Type | Required | Description |
scope | string (enum) userorgpublic | yes | Share scope. |
target_id | string<uuid> | no | Target user or org ID. Required when `scope` is `user` or `org`. |
capability | string | no | The capability being shared. Omit to share all capabilities. |
Responses
| Status | Description |
201 | Share created. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
409 | 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate). |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
DELETE /v1/virtual-workers/{id}/shares/{shareId}
Revoke a Virtual Worker share
Revokes a previously-granted capability share. Effective immediately — in-flight tasks already dispatched via the share may still complete.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Virtual Worker ID. |
shareId | path | string<uuid> | yes | Share ID. |
Responses
| Status | Description |
200 | Share revoked. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/virtual-workers/approvals
List pending worker approvals
Returns worker autonomy approval requests pending human decision. Filtered to the authenticated org. Optional `status` query parameter.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
status | query | string (enum) | no | Filter by approval status. |
Responses
| Status | Description |
200 | Approval list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers/approvals/{approvalId}/decide
Decide on a worker approval request
Approves or declines a pending worker approval request. A declined request causes the worker to receive an autonomy denial on the in-progress task.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
approvalId | path | string<uuid> | yes | Approval request ID. |
Request Body
| Field | Type | Required | Description |
decision | string (enum) approveddeclined | yes | Approval outcome. |
reason | string | no | Optional human-provided reason, sent back to the worker. |
Responses
| Status | Description |
200 | Decision recorded. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
404 | 404 Not Found — the requested resource does not exist or is not visible to the caller. |
409 | Approval already decided. Error code: `CONFLICT`. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/virtual-workers/bindings
Create a worker channel binding
Binds a Virtual Worker to an inbound channel (helpdesk, chat, email, SaaS package, or project). Tasks arriving on the bound channel are routed to this worker's dispatch queue.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
virtual_worker_id | string<uuid> | yes | |
channel_kind | string | yes | Channel type (e.g. `helpdesk`, `chat`, `email`, `project`). |
channel_ref | string | no | Channel-specific reference (e.g. queue name or topic). |
saas_package_id | string | null | no | SaaS package the binding is scoped to. |
project_id | string | null | no | Project the binding is scoped to. |
credential_id | string | null | no | Vault credential to inject when this channel fires. |
Responses
| Status | Description |
201 | Channel binding created. |
400 | 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement. |
409 | 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate). |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/virtual-workers/sessions
List Virtual Worker sessions
Returns container sessions associated with Virtual Workers. Optionally filtered by `virtual_worker_id`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
virtual_worker_id | query | string<uuid> | no | Filter to sessions for a specific worker. |
Responses
| Status | Description |
200 | Session list. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |