Agent Chats
GET /api/orgs/{org_id}/agents/{agent_id}/chats/
Section titled “GET /api/orgs/{org_id}/agents/{agent_id}/chats/”List Chats
List chat conversations for an agent (no message content — summary only).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| limit | query | integer | no | |
| offset | query | integer | no | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | ChatListResponse |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/agents/{agent_id}/chats/
Section titled “POST /api/orgs/{org_id}/agents/{agent_id}/chats/”Create Chat
Create a new chat conversation with an agent.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| sandbox_enabled | boolean | no | |
| title | string | no |
Responses
| Status | Description | Body |
|---|---|---|
| 201 | Successful Response | ChatResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}
Section titled “GET /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}”Get Chat
Get a chat conversation with all messages.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | ChatResponse |
| 422 | Validation Error | HTTPValidationError |
PATCH /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}
Section titled “PATCH /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}”Update Chat
Update a chat — title, archived state, and/or shared visibility.
At least one of title, archived or shared must be provided.
shared (private↔shared visibility) is creator-only.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| archived | boolean | no | |
| shared | boolean | no | |
| title | string | no |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | ChatResponse |
| 422 | Validation Error | HTTPValidationError |
DELETE /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}
Section titled “DELETE /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}”Delete Chat
Soft-delete a chat conversation.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/messages
Section titled “POST /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/messages”Send Message
Send a user message and dispatch the agent turn to the worker.
Persists the user message immediately (for optimistic echo + sidebar bump),
then dispatches a CONVERSATION_TURN_REQUESTED event to the worker.
The worker owns LLM execution, assistant-message persistence, cost rollup,
and title generation.
Returns 202 Accepted with the persisted user message id. Returns 503 if the worker dispatch fails (a silent 202 would leave the turn never running).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| attachment_ids | string (uuid)[] | no | |
| content | string | yes | |
| model | string | no | |
| provider | string | no | |
| reasoning_effort | string | no |
Responses
| Status | Description | Body |
|---|---|---|
| 202 | Successful Response | SendMessageResponse |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/stop
Section titled “POST /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/stop”Stop Chat
Stop the current generation run — keep the chat ACTIVE.
Flips chat.status from RUNNING to ACTIVE so the in-flight
worker aborts at its next LLM step (pre_llm_checks raises
AssignmentCancelledError whenever chat.status != RUNNING).
Unlike /terminate the chat is not closed: no completed_at,
no archived_at, and no HITL resolution. The chat stays live and the
user can immediately send another message.
Idempotent: if the chat is not RUNNING (already ACTIVE, PAUSED, or in a terminal state) 200 is returned without mutation — stopping a non-running chat is always a no-op.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | TerminateChatResponse |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/terminate
Section titled “POST /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/terminate”Terminate Chat
Terminate a chat — set status to ARCHIVED and resolve any pending HITL.
Flips chat.status to ARCHIVED (the user-closed terminal state) and
sets completed_at to now. The ORM listener fires a status_changed
realtime envelope so the frontend receives the update immediately.
Any pending HITL request for this chat is resolved to cancelled so the
chat is not left awaiting human input.
Idempotent: if the chat is already in a terminal status (ERRORED, ARCHIVED, ABANDONED) 200 is returned without re-mutating.
Setting status away from RUNNING signals an in-flight runner to abort at its
next LLM step (pre_llm_checks raises AssignmentCancelledError). No
extra worker call is needed.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | TerminateChatResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/timeline
Section titled “GET /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/timeline”Get Conversation Timeline
Get the unified conversation-spine timeline for a chat.
Returns a newest-first list of events composed from:
-
All
agent_eventsfor thischat_id— regardless of whether each row hasassignment_idset or NULL. This capturesagent_stepprose rows written by a chat-lane turn before or without span attribution, which the per-assignment endpoint misses. -
Synthetic
user_message_receivedevents derived fromagent_chat_messages WHERE role='user'for this chat. User messages are not on the event spine, but the frontend renders the whole conversation from this single feed, so user turns are synthesised here.metadata.contentcarries the message text;metadata.attachmentscarries any file attachments so the frontend can render file chips.
The merged list is sorted newest-first (same convention as
GET /assignments/{id}/timeline) so the frontend buildTurns
(which does [...events].reverse()) works unchanged.
Pagination: limit / offset are applied AFTER the merge-sort, so
the total reflects the combined event + user-message count.
Requires membership in the organization and that the chat belongs to the given agent.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| limit | query | integer | no | Max events to return |
| offset | query | integer | no | Pagination offset |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | ConversationTimelineResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/toggles
Section titled “GET /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/toggles”Get Chat Toggles
Get the available composer toggles for a chat with their current enabled state.
Always includes a system:web entry for the web-search bundle. Also
includes one entry per ACTIVE Composio integration connected to this org.
The enabled field reflects whether the scope is currently active for
the chat (i.e. is present in enabled_scopes).
Only Composio integrations are surfaced here — MCP-server and other integration types are not toggle-able via this surface.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | TogglesResponse |
| 422 | Validation Error | HTTPValidationError |
PUT /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/toggles
Section titled “PUT /api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/toggles”Update Chat Toggles
Update the composer toggle state for a chat.
Replaces enabled_scopes with the provided list. Every scope in the
request body must be one of the allowed values for this chat (system:web
or a composio:<toolkit> scope for an ACTIVE Composio integration in this
org) — unknown scopes are rejected with 422.
Returns the updated toggle list (same shape as GET /{chat_id}/toggles).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| chat_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| enabled_scopes | string[] | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | TogglesResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/agents/{agent_id}/chats/unified
Section titled “GET /api/orgs/{org_id}/agents/{agent_id}/chats/unified”List Unified Sidebar
Unified sidebar list: conversations ordered by activity.
Phase 2 (chat-outcomes model): chatless assignment items are gone — every work unit is a chat.
Returns a keyset-paginated list of conversations for the agent sidebar.
When archived=true, only archived conversations are returned.
The response includes archived_count=0 on this branch.
When archived=false (default), only active (non-archived) conversations
are returned. The response includes archived_count with the total number
of archived conversations for this agent.
Keyset pagination: cursor encodes (activity_at ISO, id) as base64. Use next_cursor from the response to fetch the next page.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string (uuid) | yes | |
| archived | query | boolean | no | When true, return archived conversations only; when false (default), return active (non-archived) conversations and chatless assignments. |
| cursor | query | string | no | Opaque keyset cursor |
| limit | query | integer | no | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | UnifiedSidebarResponse |
| 422 | Validation Error | HTTPValidationError |