Manage AI assistant sessions, conversations, messages, cost tracking, multi-environment access matrices, sharing, AI model and provider configuration, finite-state-machine skills, multi-agent engine sessions, global system prompts, and the vision-verdict endpoint.
GET /v1/ai-model-config
Get org AI model configuration
Returns the merged AI model catalog for the caller's org: relational catalog fused with JSONB-stored org overrides (org wins on collision). Requires admin or owner role.
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | Merged AI model 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. |
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 |
providers | array of object | |
models | array of object | |
default_model_id | string | null | Id of the default model (references a model `id` in this catalog). |
usage | object | null | Optional usage statistics for the current billing period. |
PUT /v1/ai-model-config
Update org AI model configuration
Full-replace of the org AI model catalog (providers + models + default_model_id). Provider `cloudflare_secret_name` values must be org-scoped (prefix `org_<orgId>__`); cross-tenant references are rejected with `400 VALIDATION_ERROR`. Max 100 providers, 500 models. Requires admin or owner role.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
providers | array of object | yes | |
models | array of object | yes | |
default_model_id | string | null | no | Must reference a model `id` in the submitted catalog. |
Responses
| Status | Description |
200 | Updated AI model configuration. |
400 | `VALIDATION_ERROR` — a field failed, or `cloudflare_secret_name` is not org-scoped. |
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 |
providers | array of object | |
models | array of object | |
default_model_id | string | null | Id of the default model (references a model `id` in this catalog). |
usage | object | null | Optional usage statistics for the current billing period. |
GET /v1/ai-models
List org AI models
Returns a paginated list of org-level AI model catalog entries. Optionally filter by `provider_id` or `is_enabled`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
page | query | integer | no | 1-based page number (default 1). |
page_size | query | integer | no | Models per page (max 200, default 50). |
provider_id | query | string<uuid> | no | Filter by provider (UUIDv7). |
is_enabled | query | string (enum) | no | Filter by enabled state. |
Responses
| Status | Description |
200 | Paginated list of org AI model 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/ai-models
Create an org AI model
Adds a new AI model to the org catalog. Cost/credit values are per-million-token.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
provider_id | string<uuid> | yes | |
display_name | string | yes | |
model_key | string | yes | |
context_window | integer | yes | Context window size in tokens. |
max_output_tokens | integer | no | |
temperature | number | no | |
capabilities | array of string | no | |
input_cost_per_million_tokens | number | no | |
output_cost_per_million_tokens | number | no | |
input_credits_per_million_tokens | number | no | |
output_credits_per_million_tokens | number | no | |
is_enabled | boolean | no | |
config | object | no | |
Responses
| Status | Description |
201 | AI model created. |
400 | `VALIDATION_ERROR`. |
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 |
id | string<uuid> | |
org_id | string<uuid> | |
provider_id | string<uuid> | |
display_name | string | |
model_key | string | |
capabilities | array of string | |
is_enabled | boolean | |
created_by | string | null | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
PUT /v1/ai-models/{id}
Update an org AI model
Partial update of an org AI model. All fields are optional; only supplied fields are changed.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | AI model identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
provider_id | string<uuid> | no | |
display_name | string | no | |
model_key | string | no | |
context_window | integer | no | |
max_output_tokens | integer | no | |
temperature | number | no | |
capabilities | array of string | no | |
input_cost_per_million_tokens | number | no | |
output_cost_per_million_tokens | number | no | |
input_credits_per_million_tokens | number | no | |
output_credits_per_million_tokens | number | no | |
is_enabled | boolean | no | |
config | object | no | |
Responses
| Status | Description |
200 | Updated AI model. |
400 | `VALIDATION_ERROR`. |
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 |
id | string<uuid> | |
org_id | string<uuid> | |
provider_id | string<uuid> | |
display_name | string | |
model_key | string | |
capabilities | array of string | |
is_enabled | boolean | |
created_by | string | null | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
DELETE /v1/ai-models/{id}
Delete an org AI model
Deletes an org AI model catalog entry. Returns `204 No Content`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | AI model identifier (UUIDv7). |
Responses
| Status | Description |
204 | AI model deleted. |
400 | `VALIDATION_ERROR` — invalid ID format. |
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/ai-models/available
List available AI models for the org
Returns the paginated set of AI models available to the caller's organization — both the shared relational catalog and any org-specific overrides. `supports_voice=true` filters to voice-capable models only.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
page | query | integer | no | 1-based page number (1–100 000, default 1). |
page_size | query | integer | no | Models per page (1–500, default 100). |
supports_voice | query | string (enum) | no | Filter to voice-capable models only. |
Responses
| Status | Description |
200 | Paginated list of available AI models (system catalog merged with org overrides). |
400 | `VALIDATION_ERROR`. |
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/ai-models/system
List system AI models with org override state
Returns the paginated list of system AI models along with each model's enabled/disabled state for the caller's organization.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
page | query | integer | no | 1-based page number (default 1). |
page_size | query | integer | no | Models per page (max 200, default 50). |
Responses
| Status | Description |
200 | Paginated list of system AI models with per-org enabled state. |
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. |
PUT /v1/ai-models/system
Batch-set system AI model enabled overrides
Full-replace of system model enabled/disabled overrides (max 200 entries). Requires super-admin role in the platform root organization.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
overrides | array of object | yes | |
Responses
| Status | Description |
200 | Updated system model override result. |
400 | `VALIDATION_ERROR`. |
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/ai-models/system/override
Create (upsert) a system model override
Upserts a single enabled/disabled override for a system model. Requires super-admin role in the platform root organization.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
system_model_id | string<uuid> | yes | |
is_enabled | boolean | yes | |
Responses
| Status | Description |
200 | Upserted override. |
400 | `VALIDATION_ERROR`. |
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 |
system_model_id | string<uuid> | |
is_enabled | boolean | |
PUT /v1/ai-models/system/override
Upsert a system model override
Upserts a single enabled/disabled override for a system model. Semantically equivalent to `POST /system/override`. Requires super-admin role in the platform root organization.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
system_model_id | string<uuid> | yes | |
is_enabled | boolean | yes | |
Responses
| Status | Description |
200 | Upserted override. |
400 | `VALIDATION_ERROR`. |
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 |
system_model_id | string<uuid> | |
is_enabled | boolean | |
GET /v1/ai-providers
List AI providers
Returns a paginated list of org-level AI provider configurations. API keys are never included in responses.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
page | query | integer | no | 1-based page number (default 1). |
page_size | query | integer | no | Providers per page (max 200, default 50). |
is_enabled | query | string (enum) | no | Filter by enabled state. |
Responses
| Status | Description |
200 | List of AI provider records. |
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 |
providers | array of object | |
POST /v1/ai-providers
Create an AI provider
Creates a new AI provider. The API key is stored encrypted and never returned. The `api_base_url` undergoes SSRF validation: HTTPS required, no private/RFC-1918 IPs, vendor hostname suffix pinning for known protocol types. Requires admin or owner role.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
provider_name | string | yes | |
protocol_type | string (enum) anthropicopenaigooglecustom | yes | |
api_base_url | string | null | no | Base URL for the provider API. Must use HTTPS. For `anthropic`/`openai`/`google` protocol types the hostname must match the vendor's canonical domain. For `custom` the URL undergoes DNS-resolve SSRF validation — private/RFC-1918 IPs are rejected. |
api_key | string | no | Provider API key. Stored encrypted; never returned in any response. |
rate_limit_rpm | integer | no | |
rate_limit_tpm | integer | no | |
config | object | no | |
Responses
| Status | Description |
201 | AI provider created (no API key in response). |
400 | `VALIDATION_ERROR` / `INVALID_PARAMETER` (SSRF guard on `api_base_url`). |
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 | `CONFLICT` — duplicate provider name. |
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> | |
org_id | string<uuid> | |
provider_name | string | |
protocol_type | string (enum) anthropicopenaigooglecustom | |
api_base_url | string | null | |
is_enabled | boolean | |
rate_limit_rpm | integer | null | |
rate_limit_tpm | integer | null | |
config | object | null | |
created_by | string | null | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
GET /v1/ai-providers/{id}
Get an AI provider
Returns a single AI provider record. API key not included. Requires admin or owner role.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | AI provider identifier (UUIDv7). |
Responses
| Status | Description |
200 | AI provider 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 |
id | string<uuid> | |
org_id | string<uuid> | |
provider_name | string | |
protocol_type | string (enum) anthropicopenaigooglecustom | |
api_base_url | string | null | |
is_enabled | boolean | |
rate_limit_rpm | integer | null | |
rate_limit_tpm | integer | null | |
config | object | null | |
created_by | string | null | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
PUT /v1/ai-providers/{id}
Update an AI provider
Partial update of an AI provider. All fields are optional; only supplied fields are changed. Same SSRF guard on `api_base_url`. Pass `api_key: null` to clear the stored credential.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | AI provider identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
provider_name | string | no | |
protocol_type | string (enum) anthropicopenaigooglecustom | no | |
api_base_url | string | null | no | Same SSRF constraints as on create. |
api_key | string | null | no | Provide a new key to rotate. Pass `null` to clear the stored credential. |
is_enabled | boolean | no | |
rate_limit_rpm | integer | null | no | |
rate_limit_tpm | integer | null | no | |
config | object | no | |
Responses
| Status | Description |
200 | Updated AI provider (API key omitted). |
400 | `INVALID_ID_FORMAT` / `VALIDATION_ERROR` / `INVALID_PARAMETER` (SSRF). |
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 |
id | string<uuid> | |
org_id | string<uuid> | |
provider_name | string | |
protocol_type | string (enum) anthropicopenaigooglecustom | |
api_base_url | string | null | |
is_enabled | boolean | |
rate_limit_rpm | integer | null | |
rate_limit_tpm | integer | null | |
config | object | null | |
created_by | string | null | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
DELETE /v1/ai-providers/{id}
Delete an AI provider
Deletes an AI provider and its encrypted API key. Returns `204 No Content`. Requires admin or owner role.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | AI provider identifier (UUIDv7). |
Responses
| Status | Description |
204 | AI provider deleted. |
400 | `INVALID_ID_FORMAT`. |
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/assistant/conversations
List assistant conversations (assistant mount)
Returns the paginated list of conversations for the authenticated user in their current organization. This endpoint is served from the `/v1/assistant` mount and is an alias for the conversations accessible via the AssistantDO. The canonical conversation CRUD lives under `/v1/conversations`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
limit | query | integer | no | Maximum number of conversations to return (1–100). |
offset | query | integer | no | Number of conversations to skip. |
Responses
| Status | Description |
200 | Paginated list of conversations. |
400 | `INVALID_PARAMETER` — a query parameter has an invalid value. |
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/assistant/conversations/{id}
Get conversation history (assistant mount)
Returns the full conversation record, including messages, for the given conversation id. A conversation that does not exist or belongs to a different tenant returns `404 NOT_FOUND` (anti-enumeration — indistinguishable from missing).
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Responses
| Status | Description |
200 | The conversation record with its message history. |
400 | `INVALID_ID_FORMAT` — the supplied id is not a valid UUIDv7. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
404 | `NOT_FOUND` — the conversation 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 |
id | string<uuid> | |
org_id | string<uuid> | |
user_id | string<uuid> | |
project_id | string | null | |
task_id | string | null | |
context_type | string (enum) projecttaskassistantgeneral | |
model | string | null | |
system_prompt | string | null | |
title | string | |
is_archived | boolean | |
metadata | object | null | |
messages | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
GET /v1/assistant/ws
WebSocket upgrade for the AI assistant Durable Object
Upgrades an HTTP connection to a WebSocket session routed to the per-user AssistantDO. The caller must pass a valid, unexpired session access token in the `token` query parameter (the WebSocket protocol does not support custom headers during upgrade). The token is validated (signature, expiry, token-version revocation) before the connection is forwarded. Feature-flag gating on AI operations is enforced inside the Durable Object on each prompt submission, not at upgrade time, so conversation history and presence are always available once connected.
Auth One-time ?token= ticket
Parameters
| Name | In | Type | Required | Description |
token | query | string | yes | Valid session access token (JWT). Required because the WebSocket upgrade cannot carry an Authorization header. Token must be unexpired and must pass revocation check. |
Responses
| Status | Description |
101 | Switching Protocols — WebSocket connection established to the AssistantDO. |
400 | `VALIDATION_ERROR` — `Upgrade: websocket` header missing, or `token` query parameter absent or empty. |
401 | `AUTH_TOKEN_EXPIRED` — token is expired. `AUTH_TOKEN_INVALID` — token signature invalid, claims missing, or the token has been revoked. |
426 | `VALIDATION_ERROR` — `Upgrade: websocket` header missing (HTTP 426 Upgrade Required variant emitted by the handler). |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/conversations
List conversations
Returns a paginated list of conversations in the caller's organization, filtered by optional criteria. Results are scoped to the caller's organization and visible conversations via Row-Level Security.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
project_id | query | string<uuid> | no | Filter by project (UUIDv7). |
task_id | query | string<uuid> | no | Filter by task (UUIDv7). |
context_type | query | string (enum) | no | Filter by conversation context type. |
is_archived | query | string (enum) | no | Filter by archived state (`true` or `false`). |
search | query | string | no | Full-text search term (max 200 chars). |
limit | query | integer | no | Maximum number of conversations to return (1–100, default 25). |
offset | query | integer | no | Number of records to skip. |
Responses
| Status | Description |
200 | Paginated list of conversations. |
400 | `VALIDATION_ERROR` — a query parameter failed validation. |
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/conversations
Create a conversation
Creates a new conversation in the caller's organization, optionally associated with a project or task. Returns the created conversation record with a platform-assigned id.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
title | string | no | |
project_id | string<uuid> | no | |
task_id | string<uuid> | no | |
context_type | string (enum) projecttaskassistantgeneral | no | |
model | string | no | |
system_prompt | string | no | |
metadata | object | no | |
Responses
| Status | Description |
201 | Conversation created. |
400 | `VALIDATION_ERROR` — a body field failed validation. |
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. |
201 response body: data fields
| Field | Type | Description |
id | string<uuid> | |
org_id | string<uuid> | |
user_id | string<uuid> | |
project_id | string | null | |
task_id | string | null | |
context_type | string (enum) projecttaskassistantgeneral | |
model | string | null | |
system_prompt | string | null | |
title | string | |
is_archived | boolean | |
metadata | object | null | |
messages | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
GET /v1/conversations/{conversationId}/messages
List conversation messages
Returns the paginated messages for a conversation. Uses page-based pagination (page/page_size). Rejects unknown query keys with `400 VALIDATION_ERROR`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
conversationId | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
page | query | integer | no | 1-based page number (1–100 000, default 1). |
page_size | query | integer | no | Messages per page (1–500, default 100). |
Responses
| Status | Description |
200 | List of messages and pagination metadata. |
400 | `INVALID_ID_FORMAT` / `VALIDATION_ERROR`. |
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 |
messages | array of object | |
meta | object | Pagination metadata. Endpoints use either page/pageSize or limit/offset style; fields present depend on the endpoint. |
POST /v1/conversations/{conversationId}/messages/{messageId}/attachments
Add a file attachment to a message
Records a file attachment on an existing conversation message. The attachment is identified by the caller-supplied `file_url` (e.g., an R2 pre-signed URL obtained before this call). Org-scoped IDOR protection is enforced by the stored procedure.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
conversationId | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
messageId | path | string<uuid> | yes | Message identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
file_name | string | yes | |
file_url | string | yes | URL of the already-uploaded file (e.g. an R2 pre-signed URL). |
file_size | integer | no | |
mime_type | string | no | |
Responses
| Status | Description |
201 | Attachment record created. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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. |
201 response body: data fields
| Field | Type | Description |
attachment | object | A file attachment on a conversation message. |
GET /v1/conversations/{id}
Get a conversation
Returns a single conversation by id. A conversation that does not exist or belongs to another tenant returns `404 NOT_FOUND`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Responses
| Status | Description |
200 | The conversation record. |
400 | `INVALID_ID_FORMAT` — the id is not a valid UUIDv7. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
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 |
id | string<uuid> | |
org_id | string<uuid> | |
user_id | string<uuid> | |
project_id | string | null | |
task_id | string | null | |
context_type | string (enum) projecttaskassistantgeneral | |
model | string | null | |
system_prompt | string | null | |
title | string | |
is_archived | boolean | |
metadata | object | null | |
messages | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
PUT /v1/conversations/{id}
Update a conversation
Updates a conversation's title, archive state, or metadata. At least one field is required. Returns the updated conversation.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
title | string | no | |
is_archived | boolean | no | |
metadata | object | no | |
Responses
| Status | Description |
200 | The updated conversation record. |
400 | `INVALID_ID_FORMAT` / `VALIDATION_ERROR`. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
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 |
id | string<uuid> | |
org_id | string<uuid> | |
user_id | string<uuid> | |
project_id | string | null | |
task_id | string | null | |
context_type | string (enum) projecttaskassistantgeneral | |
model | string | null | |
system_prompt | string | null | |
title | string | |
is_archived | boolean | |
metadata | object | null | |
messages | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
DELETE /v1/conversations/{id}
Delete a conversation
Deletes a conversation and its associated data. Returns `{ deleted: true }` on success.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Responses
| Status | Description |
200 | The conversation was deleted. |
400 | `INVALID_ID_FORMAT`. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
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 |
deleted | boolean (enum) true | |
POST /v1/conversations/{id}/costs
Record an AI cost entry for a conversation
Persists a per-message (or conversation-level) AI cost record: model name, input/output token counts, and USD cost. Used by the AI/conversation runtime to maintain per-org billing ledger entries. The calling user and organization are derived from the session context (RLS). The stored procedure verifies the conversation exists and the caller has the `conversation.create` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
model | string | yes | |
input_tokens | integer | yes | |
output_tokens | integer | yes | |
cost_usd | number | yes | USD cost for this invocation (stored as NUMERIC(10,6); must be 0–9999). |
message_id | string<uuid> | no | If cost is attributable to a specific message. Omit for conversation-level aggregate cost. |
Responses
| Status | Description |
201 | Cost entry recorded. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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. |
201 response body: data fields
| Field | Type | Description |
cost | object | A recorded AI cost entry. |
GET /v1/conversations/{id}/env-matrix
Get AI session environment matrix
Returns the per-session environment access matrix for the conversation — the list of environments the AI assistant is permitted to read from or write to. Authorization is enforced inside the stored procedure based on the caller's own env access.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Responses
| Status | Description |
200 | The environment matrix for the conversation. |
400 | `INVALID_ID_FORMAT`. |
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> | |
matrix | array of object | |
PUT /v1/conversations/{id}/env-matrix
Set AI session environment matrix
Full-replace of the per-session environment access matrix. Each entry specifies an environment and its read/write permissions. An empty `matrix` array clears the matrix (reverts to home-env default). The stored procedure enforces that every requested env_id is accessible to the caller — inaccessible or duplicate entries are rejected. Unknown body keys are rejected with `400 VALIDATION_ERROR`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
matrix | array of object | yes | Full replacement list of environment access entries. Empty array clears the matrix. |
Responses
| Status | Description |
200 | The updated environment matrix. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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> | |
matrix | array of object | |
POST /v1/conversations/{id}/env-matrix/read
Multi-environment read for AI session
Executes a read across exactly the environments in the conversation's `can_read` matrix and returns merged, environment-labeled results. Only environments the caller can access and that the matrix grants read permission to are queried. Unknown query keys are rejected with `400 VALIDATION_ERROR`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
limit | query | integer | no | Optional per-environment row cap (1–2000). |
Responses
| Status | Description |
200 | Merged multi-environment read result. |
400 | `INVALID_ID_FORMAT` / `VALIDATION_ERROR`. |
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/conversations/{id}/shares
List conversation shares
Returns the active (and optionally revoked) sharing grants for a conversation. `include_revoked=true` surfaces historical revoked grants for audit purposes. Unknown query keys are rejected at 400.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
include_revoked | query | string (enum) | no | Include revoked shares in the response. |
Responses
| Status | Description |
200 | List of share grants. |
400 | `INVALID_ID_FORMAT` / `VALIDATION_ERROR`. |
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 |
shares | array of object | |
POST /v1/conversations/{id}/shares
Create a conversation share
Creates a sharing grant on a conversation. Only the conversation creator or a super-admin may manage shares. Public sharing additionally requires an admin/owner role and the org's `conversation_public_sharing_allowed` setting. Unknown body keys are rejected at 400.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
scope | string (enum) userrolegroupdepartmentprojectorgglobalpublic | no | |
target_id | string | no | |
capability | string (enum) readwrite | no | |
recipient_org_id | string<uuid> | no | |
recipient_user_id | string<uuid> | no | |
Responses
| Status | Description |
201 | Share created. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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 | `CONFLICT` — a duplicate share already exists. |
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 |
share | object | A sharing grant on a conversation or artifact. |
DELETE /v1/conversations/{id}/shares/{shareId}
Revoke a conversation share
Revokes a sharing grant on a conversation.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Conversation identifier (UUIDv7). |
shareId | path | string<uuid> | yes | Share grant identifier (UUIDv7). |
Responses
| Status | Description |
200 | The share was revoked. |
400 | `INVALID_ID_FORMAT`. |
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. |
PATCH /v1/conversations/artifacts/{id}
Update a conversation artifact
Updates metadata fields on an existing conversation artifact (file_name, r2_key, mime_type, file_size, checksum_sha256, metadata). At least one field must be supplied. Org-scoped IDOR protection is enforced by the stored procedure. Unknown body keys are rejected with `400 VALIDATION_ERROR`.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Artifact identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
file_name | string | no | |
r2_key | string | no | |
mime_type | string | no | |
file_size | integer | no | |
checksum_sha256 | string | no | Lowercase or uppercase hex SHA-256 digest (exactly 64 hex characters). |
metadata | object | no | |
Responses
| Status | Description |
200 | The updated artifact record. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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 | `CONFLICT` — a unique constraint was violated. |
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 |
artifact | object | A conversation artifact (generated file). |
GET /v1/conversations/artifacts/{id}/shares
List artifact shares
Returns the sharing grants on a conversation artifact. `include_revoked=true` includes revoked grants for audit purposes.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Artifact identifier (UUIDv7). |
include_revoked | query | string (enum) | no | Include revoked shares (`true` or `false`). |
Responses
| Status | Description |
200 | List of artifact share grants. |
400 | `INVALID_ID_FORMAT` / `VALIDATION_ERROR`. |
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 |
shares | array of object | |
POST /v1/conversations/artifacts/{id}/shares
Create an artifact share
Creates a sharing grant on a conversation artifact. The artifact creator, the parent-conversation creator, or a super-admin may manage artifact shares. Public sharing requires admin/owner role and the org's `conversation_public_sharing_allowed` setting.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Artifact identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
scope | string (enum) userrolegroupdepartmentprojectorgglobalpublic | no | |
target_id | string | no | |
capability | string (enum) readwrite | no | |
recipient_org_id | string<uuid> | no | |
recipient_user_id | string<uuid> | no | |
Responses
| Status | Description |
201 | Artifact share created. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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. |
201 response body: data fields
| Field | Type | Description |
share | object | A sharing grant on a conversation or artifact. |
DELETE /v1/conversations/artifacts/{id}/shares/{shareId}
Revoke an artifact share
Revokes a sharing grant on a conversation artifact.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Artifact identifier (UUIDv7). |
shareId | path | string<uuid> | yes | Share grant identifier (UUIDv7). |
Responses
| Status | Description |
200 | The artifact share was revoked. |
400 | `INVALID_ID_FORMAT`. |
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/engine/sessions
List multi-agent engine sessions
Returns the paginated list of multi-agent engine sessions visible to the caller. Requires `project.view` permission. Optionally filter by status.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
status | query | string (enum) | no | Filter by session status. |
limit | query | integer | no | Max sessions to return (1–100, default 25). |
offset | query | integer | no | Number of records to skip. |
Responses
| Status | Description |
200 | List of engine sessions. Cursor-based pagination — `has_more: true` indicates additional pages exist (use `offset` to advance). |
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 |
sessions | array of object | |
has_more | boolean | True when additional sessions exist beyond this page. |
GET /v1/engine/sessions/{id}/agents
Get agents for an engine session
Returns the agent list for an engine session. Requires `project.view` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Engine session identifier (UUIDv7). |
Responses
| Status | Description |
200 | Session agent 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 | `SESSION_NOT_FOUND`. |
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 |
agents | array of object | |
POST /v1/engine/sessions/{id}/cancel
Cancel an engine session
Signals the multi-agent engine to cancel the specified session. Requires `project.update` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Engine session identifier (UUIDv7). |
Responses
| Status | Description |
200 | Session cancel signal sent. |
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 | `SESSION_NOT_FOUND`. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/engine/sessions/{id}/pause
Pause an engine session
Signals the multi-agent engine to pause the specified session. Requires `project.update` permission. Returns `SESSION_NOT_FOUND` if the session key does not exist in the engine store.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Engine session identifier (UUIDv7). |
Responses
| Status | Description |
200 | Session pause signal sent. |
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 | `SESSION_NOT_FOUND`. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
POST /v1/engine/sessions/{id}/resume
Resume an engine session
Signals the multi-agent engine to resume a paused session. Requires `project.update` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Engine session identifier (UUIDv7). |
Responses
| Status | Description |
200 | Session resume signal sent. |
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 | `SESSION_NOT_FOUND`. |
500 | 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side. |
GET /v1/engine/sessions/{id}/status
Get engine session status
Returns the current status record for an engine session. Returns `404 SESSION_NOT_FOUND` when the session key does not exist in the engine store. Requires `project.view` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Engine session identifier (UUIDv7). |
Responses
| Status | Description |
200 | Engine session status. |
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 | `SESSION_NOT_FOUND` — no session with this id exists. |
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 |
id | string<uuid> | |
status | string (enum) runningpausedcompletedcancelledfailed | |
progress | object | null | |
error | string | null | |
GET /v1/engine/sessions/{id}/tasks
Get tasks for an engine session
Returns the task list for an engine session. Requires `project.view` permission.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Engine session identifier (UUIDv7). |
Responses
| Status | Description |
200 | Session task 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 | `SESSION_NOT_FOUND`. |
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 |
tasks | array of object | |
GET /v1/skills
List skills
Returns the list of skills in the caller's organization. Results are filtered to skills the caller can access via visibility policies (admins/super-admins see all). Supports search, type filter, and offset pagination.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
skill_type | query | string (enum) | no | Filter by skill type. |
is_enabled | query | string (enum) | no | Filter by enabled state ('true' or 'false'). |
search | query | string | no | Search filter applied to skill name, description, status, and overall prompt (case-insensitive). |
limit | query | integer | no | Max skills to return (1–100, default 25). |
offset | query | integer | no | Number of records to skip. |
Responses
| Status | Description |
200 | List of skills. |
400 | `VALIDATION_ERROR` — invalid query parameters. |
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 |
skills | array of object | |
total_count | integer | Total number of skills matching the filter (before offset/limit). |
POST /v1/skills
Create a skill
Creates a new FSM-based skill in the org. Accepts an optional FSM states array (max 100) and transitions array (max 300). Unknown body keys are rejected (`.strict()`). Returns `409 DUPLICATE` if a skill with the same name already exists. Requires appropriate org permission.
Auth Session JWT (Bearer)
Request Body
| Field | Type | Required | Description |
name | string | yes | |
description | string | no | |
skill_type | string (enum) promptchainagentcomposite | no | Defaults to `agent` when omitted. |
config | object | no | |
status | string (enum) activedraftdisabled | no | |
overall_prompt | string | no | |
default_model | string | null | no | |
prompt_template | string | no | Alias for `overall_prompt`; merged at write time. |
visibility_policy_id | string | null | no | |
test_visibility_policy_id | string | null | no | |
live_visibility_policy_id | string | null | no | |
states | array of object | no | |
transitions | array of object | no | |
Responses
| Status | Description |
201 | Skill created. |
400 | `INVALID_JSON` / `VALIDATION_ERROR`. |
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 | `DUPLICATE` — a skill with the same name already exists. |
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> | |
org_id | string<uuid> | |
name | string | |
description | string | null | |
skill_type | string (enum) promptchainagentcomposite | |
config | object | null | |
status | string (enum) activedraftdisabled | |
overall_prompt | string | null | |
default_model | string | null | |
prompt_template | string | null | |
visibility_policy_id | string | null | |
test_visibility_policy_id | string | null | |
live_visibility_policy_id | string | null | |
states | array of object | |
transitions | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
GET /v1/skills/{id}
Get a skill
Returns a single skill by id.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Skill identifier (UUIDv7). |
Responses
| Status | Description |
200 | Skill 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 |
id | string<uuid> | |
org_id | string<uuid> | |
name | string | |
description | string | null | |
skill_type | string (enum) promptchainagentcomposite | |
config | object | null | |
status | string (enum) activedraftdisabled | |
overall_prompt | string | null | |
default_model | string | null | |
prompt_template | string | null | |
visibility_policy_id | string | null | |
test_visibility_policy_id | string | null | |
live_visibility_policy_id | string | null | |
states | array of object | |
transitions | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
PUT /v1/skills/{id}
Update a skill
Partial update of a skill — all fields are optional. Unknown body keys are rejected (`.strict()`). Returns `400 INVALID_ID_FORMAT` when the path `id` is not a valid UUID. Returns `404 NOT_FOUND` when the skill does not exist. Returns `409 CONFLICT` on name collision.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Skill identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
name | string | no | |
description | string | no | |
skill_type | string (enum) promptchainagentcomposite | no | |
config | object | no | |
status | string (enum) activedraftdisabled | no | |
overall_prompt | string | no | |
default_model | string | null | no | |
prompt_template | string | no | |
visibility_policy_id | string | null | no | |
test_visibility_policy_id | string | null | no | |
live_visibility_policy_id | string | null | no | |
states | array of object | no | |
transitions | array of object | no | |
Responses
| Status | Description |
200 | Updated skill. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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 | `DUPLICATE` / `CONFLICT`. |
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 |
id | string<uuid> | |
org_id | string<uuid> | |
name | string | |
description | string | null | |
skill_type | string (enum) promptchainagentcomposite | |
config | object | null | |
status | string (enum) activedraftdisabled | |
overall_prompt | string | null | |
default_model | string | null | |
prompt_template | string | null | |
visibility_policy_id | string | null | |
test_visibility_policy_id | string | null | |
live_visibility_policy_id | string | null | |
states | array of object | |
transitions | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
DELETE /v1/skills/{id}
Delete a skill
Deletes a skill and its FSM configuration.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Skill identifier (UUIDv7). |
Responses
| Status | Description |
200 | Skill deleted. |
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/skills/{id}/publish
Publish a skill to live stage
Snapshots the current test-stage FSM and publishes it to the live stage. Accepts an optional `version` number; defaults to the skill's current version. Returns `400 INVALID_ID_FORMAT` if the path `id` is not a valid UUID. Returns `404 NOT_FOUND` if the skill does not exist.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Skill identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
version | integer | no | Explicit version number to publish. Defaults to the skill's current version when omitted. |
Responses
| Status | Description |
200 | Skill published. |
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 |
id | string<uuid> | |
org_id | string<uuid> | |
name | string | |
description | string | null | |
skill_type | string (enum) promptchainagentcomposite | |
config | object | null | |
status | string (enum) activedraftdisabled | |
overall_prompt | string | null | |
default_model | string | null | |
prompt_template | string | null | |
visibility_policy_id | string | null | |
test_visibility_policy_id | string | null | |
live_visibility_policy_id | string | null | |
states | array of object | |
transitions | array of object | |
created_at | string<date-time> | |
updated_at | string<date-time> | |
POST /v1/skills/{id}/requests
Submit a skill capability feature request
Creates a capability/feature request for a skill. Used to record user-requested enhancements against a specific skill and stage (test or live). Returns `400 INVALID_ID_FORMAT` if the path `id` is not a valid UUID. Returns `404 NOT_FOUND` if the skill does not exist.
Auth Session JWT (Bearer)
Parameters
| Name | In | Type | Required | Description |
id | path | string<uuid> | yes | Skill identifier (UUIDv7). |
Request Body
| Field | Type | Required | Description |
title | string | yes | |
description | string | no | |
stage | string (enum) testlive | no | Which skill stage this request is against. Defaults to `test`. |
Responses
| Status | Description |
201 | Feature request created. |
400 | `INVALID_ID_FORMAT` / `INVALID_JSON` / `VALIDATION_ERROR`. |
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. |
201 response body: data fields
| Field | Type | Description |
id | string<uuid> | |
skill_id | string<uuid> | |
stage | string (enum) testlive | |
title | string | |
description | string | |
requested_by | string<uuid> | User who created the request. |
status | string | Request status (e.g. `open`, `in_progress`, `resolved`). |
created_at | string<date-time> | |
updated_at | string<date-time> | |
GET /v1/skills/policies
List skill visibility policies
Returns the list of visibility policies available for use with skills in the caller's organization.
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | List of skill visibility policies. |
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 |
policies | array of object | |
GET /v1/skills/workspace
Get skill workspace plan entitlements
Returns the plan-scoped AI model entitlements for the skill editor UI — the list of models available to this org's active pricing plan, along with full plan entitlement details (credits, storage, capabilities).
Auth Session JWT (Bearer)
Responses
| Status | Description |
200 | Skill workspace plan entitlements. |
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 |
model_options | array of object | AI models available to this org under the active pricing plan. |
plan_entitlements | any | Full plan entitlement record, or null if no active plan subscription is found. |
POST /v1/vision/verdict
AI vision content verdict
Submits a base64-encoded image to an AI vision model and returns a structured verdict (`yes`/`no`/`unclear`/`refused`). Useful for content moderation, verification workflows, and automated image triage.
Authentication: accepts either a session JWT (bearer) or an API key — whichever the caller holds. In both cases the caller must also hold the `vision` API key scope and the `vision.verify` permission in their organization. AI budget credit is reserved before the call and committed on success (rolled back on model or policy failure).
Rate limited to 60 requests per minute per user:org pair.
Auth Session JWT (Bearer) or API key (Bearer bb_live_…)
Request Body
| Field | Type | Required | Description |
image_b64 | string | yes | Base64-encoded image data. Maximum decoded size is 5 MB. |
image_mime | string (enum) image/pngimage/jpegimage/gifimage/webpimage/heicimage/heif | no | MIME type of the image. |
prompt | string | yes | The question or instruction to send to the vision model alongside the image. |
provider | string (enum) workers-aianthropic | no | |
model | string | no | Optional model override. Defaults to the provider's configured default vision model. |
redact_pii | boolean | no | When `true`, PII found in the image or AI response is redacted before storage. |
Responses
| Status | Description |
200 | Vision verdict produced. |
400 | `INVALID_JSON` / `VALIDATION_ERROR` — a required field is missing or out of bounds. |
401 | 401 Unauthorized — missing, expired, malformed, or revoked credentials. |
403 | `FORBIDDEN` — caller lacks the `vision` API key scope or the `vision.verify` permission. |
422 | `CONTENT_POLICY_VIOLATION` — the AI model refused to process the image due to a content policy violation. |
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. |
503 | `INTERNAL_ERROR` — AI budget gate is temporarily unavailable. Retry after a brief delay. |
200 response body: data fields
| Field | Type | Description |
verdict | string (enum) yesnounclearrefused | `yes`/`no` when the model can answer the prompt clearly; `unclear` when confidence is low; `refused` when the model declines due to content policy. |
reason | string | null | Human-readable explanation of the verdict from the model. |
model | string | The exact model identifier used. |
provider | string | The provider that served the request. |
latency_ms | integer | End-to-end model call latency in milliseconds. |
usage | object | Token usage for this call. |