Agents
Every call needs Authorization: Bearer <key>. 6 calls:
- List agent runs, newest first:
GET /v1/agent-runs - Get an agent run and its steps:
GET /v1/agent-runs/:id - List AI agents, newest first:
GET /v1/agents - Create an AI agent:
POST /v1/agents - Get an AI agent:
GET /v1/agents/:id - Edit an AI agent, or turn it on, put it in shadow or pause it:
PATCH /v1/agents/:id
List agent runs, newest first
GET /v1/agent-runs
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | From 1 to 100. Default 50. |
cursor | string | No | Opaque cursor from next_cursor. Up to 512 characters. |
agent_id | string (uuid) | No | |
conversation_id | string | No | Conversation id (cnv_...). |
outcome | enum | No | One of: running, resolved, handoff, error. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].agent_id | string (uuid) | |
data[].conversation_id | string or null | Conversation id (cnv_...). |
data[].error_code | string or null | |
data[].finished_at | string (date-time) or null | ISO 8601 timestamp. |
data[].handoff_reason | string or null | |
data[].id | string (uuid) | |
data[].input_tokens | integer | From 0 to 9007199254740991. |
data[].model | string or null | |
data[].outcome | enum or null | One of: running, resolved, handoff, error. |
data[].output_tokens | integer | From 0 to 9007199254740991. |
data[].shadow | boolean | |
data[].started_at | string (date-time) | ISO 8601 timestamp. |
data[].tool_calls | integer | From 0 to 9007199254740991. |
data[].trigger_message_id | string or null | Message id (msg_...). |
data[].turns | integer | From 0 to 9007199254740991. |
data[].workflow_run_id | string (uuid) or null | |
next_cursor | string or null | Pass as cursor to get the next page; null at the end. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Get an agent run and its steps
GET /v1/agent-runs/:id
What the agent said appears in the steps only for callers who can read conversations.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
agent_id | string (uuid) | |
conversation_id | string or null | Conversation id (cnv_...). |
error_code | string or null | |
finished_at | string (date-time) or null | ISO 8601 timestamp. |
handoff_reason | string or null | |
id | string (uuid) | |
input_tokens | integer | From 0 to 9007199254740991. |
model | string or null | |
outcome | enum or null | One of: running, resolved, handoff, error. |
output_tokens | integer | From 0 to 9007199254740991. |
shadow | boolean | |
started_at | string (date-time) | ISO 8601 timestamp. |
steps | object[] | |
steps[].at | string (date-time) | ISO 8601 timestamp. |
steps[].code | string | |
steps[].detail | object | |
steps[].kind | enum | One of: model, tool, message, handoff, guard. |
steps[].status | enum | One of: ok, refused, failed, shadowed. |
steps[].tool | string | |
tool_calls | integer | From 0 to 9007199254740991. |
trigger_message_id | string or null | Message id (msg_...). |
turns | integer | From 0 to 9007199254740991. |
workflow_run_id | string (uuid) or null |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List AI agents, newest first
GET /v1/agents
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | From 1 to 100. Default 50. |
cursor | string | No | Opaque cursor from next_cursor. Up to 512 characters. |
status | enum | No | One of: draft, shadow, live, paused. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].created_at | string (date-time) | ISO 8601 timestamp. |
data[].handoff_rules | object | |
data[].handoff_rules.keywords | string[] | Hand off, without asking the model, when the contact’s message has one of these. Up to 50 items. |
data[].handoff_rules.max_turns | integer | From 1 to 100. |
data[].handoff_rules.on_low_confidence | boolean | Hand off when the model answers with neither text nor a tool call. Default true. |
data[].handoff_rules.team_id | string (uuid) or null | Team the conversation is assigned to on handoff. |
data[].handoff_rules.user_id | string (uuid) or null | Person the conversation is assigned to on handoff (P11b). |
data[].id | string (uuid) | |
data[].instructions | string | |
data[].limits | object | |
data[].limits.max_messages_per_conversation | integer | From 1 to 100. |
data[].limits.max_runs_per_conversation_per_day | integer | From 1 to 200. |
data[].limits.max_tokens_per_run | integer | From 1 to 200000. |
data[].limits.max_tool_calls_per_run | integer | From 1 to 20. |
data[].limits.max_turns_per_run | integer | From 1 to 10. |
data[].model | string | |
data[].name | string | |
data[].pool_ids | string[] | |
data[].runs_7d | object | |
data[].runs_7d.conversations | integer | From 0 to 9007199254740991. |
data[].runs_7d.error | integer | From 0 to 9007199254740991. |
data[].runs_7d.handoff | integer | From 0 to 9007199254740991. |
data[].runs_7d.resolved | integer | From 0 to 9007199254740991. |
data[].runs_7d.total | integer | From 0 to 9007199254740991. |
data[].status | enum | One of: draft, shadow, live, paused. |
data[].tools | enum[] | |
data[].updated_at | string (date-time) | ISO 8601 timestamp. |
data[].usable_tools | enum[] | |
next_cursor | string or null | Pass as cursor to get the next page; null at the end. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Create an AI agent
POST /v1/agents
Creates the agent and the service identity its tool calls run with. You can only give it tools your own role can use, and they stay capped by your role. Live and shadow agents need at least one pool. Signed-in members only: API keys are refused.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
handoff_rules | object | No | Default {"keywords":[],"on_low_confidence":true}. |
handoff_rules.keywords | string[] | No | Hand off, without asking the model, when the contact’s message has one of these. Up to 50 items. |
handoff_rules.max_turns | integer | No | From 1 to 100. |
handoff_rules.on_low_confidence | boolean | No | Hand off when the model answers with neither text nor a tool call. Default true. |
handoff_rules.team_id | string (uuid) or null | No | Team the conversation is assigned to on handoff. |
handoff_rules.user_id | string (uuid) or null | No | Person the conversation is assigned to on handoff (P11b). |
instructions | string | No | Up to 20000 characters. |
limits | object | No | Default {}. |
limits.max_messages_per_conversation | integer | No | From 1 to 100. |
limits.max_runs_per_conversation_per_day | integer | No | From 1 to 200. |
limits.max_tokens_per_run | integer | No | From 1 to 200000. |
limits.max_tool_calls_per_run | integer | No | From 1 to 20. |
limits.max_turns_per_run | integer | No | From 1 to 10. |
model | string | Yes | Up to 100 characters. |
name | string | Yes | Up to 80 characters. |
pool_ids | string[] | No | Up to 50 items. |
status | enum | No | One of: draft, shadow, live. Default "draft". |
tools | enum[] | No | Up to 20 items. |
Response 201
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
handoff_rules | object | |
handoff_rules.keywords | string[] | Hand off, without asking the model, when the contact’s message has one of these. Up to 50 items. |
handoff_rules.max_turns | integer | From 1 to 100. |
handoff_rules.on_low_confidence | boolean | Hand off when the model answers with neither text nor a tool call. Default true. |
handoff_rules.team_id | string (uuid) or null | Team the conversation is assigned to on handoff. |
handoff_rules.user_id | string (uuid) or null | Person the conversation is assigned to on handoff (P11b). |
id | string (uuid) | |
instructions | string | |
limits | object | |
limits.max_messages_per_conversation | integer | From 1 to 100. |
limits.max_runs_per_conversation_per_day | integer | From 1 to 200. |
limits.max_tokens_per_run | integer | From 1 to 200000. |
limits.max_tool_calls_per_run | integer | From 1 to 20. |
limits.max_turns_per_run | integer | From 1 to 10. |
model | string | |
name | string | |
pool_ids | string[] | |
runs_7d | object | |
runs_7d.conversations | integer | From 0 to 9007199254740991. |
runs_7d.error | integer | From 0 to 9007199254740991. |
runs_7d.handoff | integer | From 0 to 9007199254740991. |
runs_7d.resolved | integer | From 0 to 9007199254740991. |
runs_7d.total | integer | From 0 to 9007199254740991. |
status | enum | One of: draft, shadow, live, paused. |
tools | enum[] | |
updated_at | string (date-time) | ISO 8601 timestamp. |
usable_tools | enum[] |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Get an AI agent
GET /v1/agents/:id
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
handoff_rules | object | |
handoff_rules.keywords | string[] | Hand off, without asking the model, when the contact’s message has one of these. Up to 50 items. |
handoff_rules.max_turns | integer | From 1 to 100. |
handoff_rules.on_low_confidence | boolean | Hand off when the model answers with neither text nor a tool call. Default true. |
handoff_rules.team_id | string (uuid) or null | Team the conversation is assigned to on handoff. |
handoff_rules.user_id | string (uuid) or null | Person the conversation is assigned to on handoff (P11b). |
id | string (uuid) | |
instructions | string | |
limits | object | |
limits.max_messages_per_conversation | integer | From 1 to 100. |
limits.max_runs_per_conversation_per_day | integer | From 1 to 200. |
limits.max_tokens_per_run | integer | From 1 to 200000. |
limits.max_tool_calls_per_run | integer | From 1 to 20. |
limits.max_turns_per_run | integer | From 1 to 10. |
model | string | |
name | string | |
pool_ids | string[] | |
runs_7d | object | |
runs_7d.conversations | integer | From 0 to 9007199254740991. |
runs_7d.error | integer | From 0 to 9007199254740991. |
runs_7d.handoff | integer | From 0 to 9007199254740991. |
runs_7d.resolved | integer | From 0 to 9007199254740991. |
runs_7d.total | integer | From 0 to 9007199254740991. |
status | enum | One of: draft, shadow, live, paused. |
tools | enum[] | |
updated_at | string (date-time) | ISO 8601 timestamp. |
usable_tools | enum[] |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Edit an AI agent, or turn it on, put it in shadow or pause it
PATCH /v1/agents/:id
Changing its tools or pools makes you the member whose role caps them. Moving a live agent to any other status hands its conversations back to people. A paused organisation can still pause an agent. Signed-in members only: API keys are refused.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
handoff_rules | object | No | |
handoff_rules.keywords | string[] | No | Hand off, without asking the model, when the contact’s message has one of these. Up to 50 items. |
handoff_rules.max_turns | integer | No | From 1 to 100. |
handoff_rules.on_low_confidence | boolean | No | Hand off when the model answers with neither text nor a tool call. Default true. |
handoff_rules.team_id | string (uuid) or null | No | Team the conversation is assigned to on handoff. |
handoff_rules.user_id | string (uuid) or null | No | Person the conversation is assigned to on handoff (P11b). |
instructions | string | No | Up to 20000 characters. |
limits | object | No | |
limits.max_messages_per_conversation | integer | No | From 1 to 100. |
limits.max_runs_per_conversation_per_day | integer | No | From 1 to 200. |
limits.max_tokens_per_run | integer | No | From 1 to 200000. |
limits.max_tool_calls_per_run | integer | No | From 1 to 20. |
limits.max_turns_per_run | integer | No | From 1 to 10. |
model | string | No | Up to 100 characters. |
name | string | No | Up to 80 characters. |
pool_ids | string[] | No | Up to 50 items. |
status | enum | No | One of: draft, shadow, live, paused. |
tools | enum[] | No | Up to 20 items. |
Response 200
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
handoff_rules | object | |
handoff_rules.keywords | string[] | Hand off, without asking the model, when the contact’s message has one of these. Up to 50 items. |
handoff_rules.max_turns | integer | From 1 to 100. |
handoff_rules.on_low_confidence | boolean | Hand off when the model answers with neither text nor a tool call. Default true. |
handoff_rules.team_id | string (uuid) or null | Team the conversation is assigned to on handoff. |
handoff_rules.user_id | string (uuid) or null | Person the conversation is assigned to on handoff (P11b). |
id | string (uuid) | |
instructions | string | |
limits | object | |
limits.max_messages_per_conversation | integer | From 1 to 100. |
limits.max_runs_per_conversation_per_day | integer | From 1 to 200. |
limits.max_tokens_per_run | integer | From 1 to 200000. |
limits.max_tool_calls_per_run | integer | From 1 to 20. |
limits.max_turns_per_run | integer | From 1 to 10. |
model | string | |
name | string | |
pool_ids | string[] | |
runs_7d | object | |
runs_7d.conversations | integer | From 0 to 9007199254740991. |
runs_7d.error | integer | From 0 to 9007199254740991. |
runs_7d.handoff | integer | From 0 to 9007199254740991. |
runs_7d.resolved | integer | From 0 to 9007199254740991. |
runs_7d.total | integer | From 0 to 9007199254740991. |
status | enum | One of: draft, shadow, live, paused. |
tools | enum[] | |
updated_at | string (date-time) | ISO 8601 timestamp. |
usable_tools | enum[] |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.