ClouisleClouisle

Agent API

Manage AI agents, publish control, chat interaction, and statistics queries

Endpoint Overview

The Agent API provides agent lifecycle management, chat interaction, and statistics query capabilities. Base path: /api/v1/agents.

MethodPathPurpose
GET/api/v1/agentsList agents accessible to the current user
POST/api/v1/agentsCreate a new agent
GET/api/v1/agents/{agent_id}Get agent details (including full configuration)
PUT/api/v1/agents/{agent_id}Update agent configuration
DELETE/api/v1/agents/{agent_id}Permanently delete an agent
POST/api/v1/agents/{agent_id}/publishPublish an agent
POST/api/v1/agents/{agent_id}/unpublishUnpublish an agent
POST/api/v1/agents/{agent_id}/duplicateDuplicate an agent (the copy is always private + draft)
GET/api/v1/agents/{agent_id}/media/video-statusQuery an async video generation task
GET/api/v1/agents/{agent_id}/publicGet the public agent info used by the chat page
POST/api/v1/agents/{agent_id}/chatNon-streaming chat
POST/api/v1/agents/{agent_id}/chat/streamSSE streaming chat
POST/api/v1/agents/{agent_id}/chat/runsQueue a durable run (202 Accepted)
GET/api/v1/agents/{agent_id}/chat/runs/{run_id}/streamSubscribe to a run's event stream (after_sequence resume)
POST/api/v1/agents/{agent_id}/chat/runs/{run_id}/stopCooperatively stop a run
POST/api/v1/agents/{agent_id}/messages/{message_id}/regenerateRegenerate
POST/api/v1/agents/{agent_id}/messages/{message_id}/edit/streamEdit a user message and create a branch
GET/api/v1/agents/{agent_id}/messages/{message_id}/versionsQuery message versions
POST/api/v1/agents/{agent_id}/messages/{message_id}/switch-versionSwitch version
GET/api/v1/agents/{agent_id}/conversationsList the caller's conversations for one agent
GET/api/v1/agents/conversations/myList all of the caller's conversations
GET/api/v1/agents/conversations/{conversation_id}Get a conversation and its messages
PATCH/api/v1/agents/conversations/{conversation_id}Rename a conversation
DELETE/api/v1/agents/conversations/{conversation_id}Delete a conversation
DELETE/api/v1/agents/conversations/{conversation_id}/messages/{message_id}Delete a single message
GET/api/v1/agents/{agent_id}/statsQuery agent statistics overview
GET/api/v1/agents/{agent_id}/stats/trendsQuery trend data
GET/api/v1/agents/{agent_id}/stats/tool-usageQuery tool usage statistics

Authentication

All endpoints require an authenticated JWT user session. Chat endpoints additionally support API Keys (with bound agent permissions).

Required scopes:

ScopePurpose
agent:readList and view agents
agent:createCreate agents
agent:updateUpdate agents
agent:deleteDelete agents
agent:publishPublish or unpublish agents
agent:chatChat with agents
conversation:readView conversations and their messages
conversation:deleteDelete conversations and conversation messages

List Agents

GET /api/v1/agents

Get all agents accessible to the current user, with pagination, team filtering, status filtering, and keyword search.

Query Parameters

ParameterTypeRequiredDefaultDescription
pageintegerNo1Page number
page_sizeintegerNo20Items per page
team_idstringNo-Filter by team UUID
statusstringNo-Filter by status: draft, published
visibilitystringNo-Filter by visibility: private, team, public (legacy compatibility value)
keywordstringNo-Search by name or description
own_onlybooleanNofalseOnly show agents created by the current user

Request Example

curl -X GET "https://your-domain.com/api/v1/agents?page=1&page_size=20" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response Fields

FieldTypeDescription
idstringAgent UUID
namestringName
descriptionstringDescription
iconstringIcon emoji or URL
avatar_urlstringAvatar URL
teamobjectTeam info (id, name, avatar_url)
modelobjectModel info (id, name, provider, model_id), null if unset
statusstringdraft or published
visibilitystringprivate or team
conversation_countintegerNumber of conversations
message_countintegerNumber of messages
created_byobjectCreator info (id, username, avatar_url)
created_atstringISO 8601 timestamp
updated_atstringISO 8601 timestamp

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "items": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Customer Support Agent",
        "description": "Helps customers with common questions",
        "icon": "🤖",
        "avatar_url": "https://example.com/avatar.png",
        "team": {
          "id": "team-123",
          "name": "Support Team",
          "avatar_url": "https://example.com/team.png"
        },
        "model": {
          "id": "model-456",
          "name": "GPT-4",
          "provider": "openai",
          "provider_display_name": "OpenAI",
          "model_id": "gpt-4"
        },
        "status": "published",
        "visibility": "team",
        "conversation_count": 156,
        "message_count": 1234,
        "created_by": {
          "id": "user-001",
          "username": "alice",
          "avatar_url": "https://example.com/avatars/alice.jpg"
        },
        "created_at": "2026-02-11T10:00:00Z",
        "updated_at": "2026-02-11T15:30:00Z"
      }
    ],
    "total": 42,
    "page": 1,
    "page_size": 20
  },
  "msg": "success"
}

Get Agent Details

GET /api/v1/agents/{agent_id}

Get the complete configuration of a specified agent, including system prompt, tool configuration, knowledge base associations, and RAG parameters.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Request Example

curl -X GET "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response Fields

In addition to the list fields above, the details endpoint returns the full configuration:

FieldTypeDescription
model_idstringTeam model UUID
system_promptstringSystem prompt
max_iterationsintegerMax tool call iterations (1–200, default 5)
hide_tool_callsbooleanHide tool call details in chat UI
hide_message_actionsbooleanHide token usage/speed stats
hide_reasoningbooleanHide reasoning/chain-of-thought
tools_configarrayTool configs (type/name/tool_id/server_id/skill_id/config)
enable_attachmentsbooleanEnable file and image attachments
enable_user_input_requestbooleanEnable model-callable ask_user tool
enable_memorybooleanEnable cross-conversation memory
rag_modestringRAG mode: off, auto, agentic (agentic by default with a knowledge base; normalized to off when the response knowledge_bases list is empty)
variablesarrayChat input variable definitions
knowledge_basesarrayAttached knowledge-base response objects (knowledge_base, retrieval_top_k, score_threshold, search_mode)

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Customer Support Agent",
    "description": "Helps customers with common questions",
    "system_prompt": "You are a helpful customer support agent...",
    "max_iterations": 5,
    "hide_tool_calls": false,
    "tools_config": [
      {
        "type": "builtin",
        "name": "web_search"
      }
    ],
    "enable_memory": false,
    "rag_mode": "agentic",
    "knowledge_bases": [
      {
        "id": "kb-assoc-001",
        "knowledge_base": {
          "id": "kb-789",
          "name": "Product Documentation",
          "description": "Product docs and FAQs",
          "icon": "📚",
          "document_count": 156
        },
        "retrieval_top_k": 5,
        "score_threshold": 0.3,
        "search_mode": "hybrid"
      }
    ],
    "status": "published",
    "visibility": "team",
    "created_at": "2026-02-11T10:00:00Z",
    "updated_at": "2026-02-11T15:30:00Z"
  },
  "msg": "success"
}

Error Response (404 Not Found)

{
  "code": 6200,
  "data": {
    "agent_id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "msg": "Agent not found"
}

Create Agent

POST /api/v1/agents

Create a new AI agent. The agent is in draft status by default and must be published before it can be used for chat.

Request Body

{
  "name": "Customer Support Agent",
  "description": "Helps customers with common questions",
  "avatar_url": "https://example.com/avatar.png",
  "team_id": "team-123",
  "model_id": "model-456",
  "system_prompt": "You are a helpful customer support agent...",
  "max_iterations": 5,
  "hide_tool_calls": false,
  "tools_config": [
    {
      "type": "builtin",
      "name": "web_search"
    }
  ],
  "enable_memory": false,
  "rag_mode": "agentic",
  "knowledge_base_configs": [
    {
      "knowledge_base_id": "kb-789",
      "retrieval_top_k": 5,
      "score_threshold": 0.3,
      "search_mode": "hybrid"
    }
  ],
  "visibility": "team"
}

Request Fields

FieldTypeRequiredDescription
namestringYesName (max 100 chars)
descriptionstringNoDescription (max 500 chars)
iconstringNoIcon emoji or URL (max 500 chars)
avatar_urlstringNoAvatar URL
team_idstringYesTeam UUID
model_idstringNoTeam model UUID; uses team default if unset
system_promptstringNoSystem prompt/instructions
max_iterationsintegerNoMax tool call iterations (1–200, default 5)
hide_tool_callsbooleanNoHide tool call details in chat UI (default false)
hide_message_actionsbooleanNoHide token usage/speed stats (default false)
hide_reasoningbooleanNoHide reasoning/chain-of-thought (default false)
tools_configarrayNoTool configs (type/name/tool_id/server_id/skill_id/config)
tools_credentialsobjectNoTool credentials (API keys, tokens, etc.)
enable_attachmentsbooleanNoEnable file and image attachments (default false)
attachment_configobjectNoAttachment limits configuration
enable_user_input_requestbooleanNoEnable ask_user tool (default false)
enable_memorybooleanNoEnable cross-conversation memory (default false)
memory_configobjectNoMemory configuration
context_compression_configobjectNoContext compression configuration
enable_image_generationbooleanNoEnable image generation tool (default false)
image_generation_configobjectNoImage generation configuration
enable_video_generationbooleanNoEnable video generation tool (default false)
video_generation_configobjectNoVideo generation configuration
rag_modestringNoRAG mode: off, auto, agentic (agentic by default with a knowledge base; normalized to off when no knowledge base is attached)
knowledge_base_configsarrayNoKnowledge-base configs submitted on create/update (knowledge_base_id, retrieval_top_k, score_threshold, search_mode); an empty list forces rag_mode to off
variablesarrayNoChat input variable definitions
opening_messagestringNoOpening message shown in chat
suggested_questionsarrayNoSuggested questions
visibilitystringNoprivate or team (default private; the legacy value public is treated as team)

Request Example

curl -X POST "https://your-domain.com/api/v1/agents" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Customer Support Agent",
    "description": "Helps customers with common questions",
    "team_id": "team-123",
    "model_id": "model-456",
    "system_prompt": "You are a helpful customer support agent...",
    "tools_config": [{"type": "builtin", "name": "web_search"}],
    "knowledge_base_configs": [
      {
        "knowledge_base_id": "kb-789",
        "retrieval_top_k": 5,
        "score_threshold": 0.3,
        "search_mode": "hybrid"
      }
    ],
    "rag_mode": "agentic"
  }'

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Customer Support Agent",
    "description": "Helps customers with common questions",
    "status": "draft",
    "visibility": "team",
    "team": {
      "id": "team-123",
      "name": "Support Team",
      "avatar_url": null
    },
    "model_id": "model-456",
    "model": {
      "id": "model-456",
      "name": "GPT-4",
      "provider": "openai",
      "provider_display_name": "OpenAI",
      "model_id": "gpt-4"
    },
    "created_at": "2026-02-11T10:00:00Z",
    "created_by": {
      "id": "user-001",
      "username": "alice",
      "avatar_url": null
    }
  },
  "msg": "Agent created successfully"
}

Error Response (1001 Validation Error)

{
  "code": 1001,
  "data": {
    "errors": [
      {
        "field": "name",
        "message": "Name is required"
      },
      {
        "field": "model_id",
        "message": "Invalid model ID"
      }
    ]
  },
  "msg": "Validation failed"
}

After creation, the agent is in draft status. Call the publish endpoint to make it available for chat.


Update Agent

PUT /api/v1/agents/{agent_id}

Update the configuration of an existing agent. All fields are optional; only include the fields you want to update.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Request Body

{
  "name": "Updated Agent Name",
  "description": "Updated description",
  "system_prompt": "Updated system prompt...",
  "max_iterations": 8,
  "tools_config": [
    {"type": "builtin", "name": "web_search"},
    {"type": "builtin", "name": "code_interpreter"}
  ],
  "rag_mode": "auto"
}

Request Example

curl -X PUT "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Agent Name",
    "max_iterations": 8
  }'

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Updated Agent Name",
    "max_iterations": 8,
    "updated_at": "2026-02-11T16:00:00Z"
  },
  "msg": "Agent updated successfully"
}

Delete Agent

DELETE /api/v1/agents/{agent_id}

Permanently delete the specified agent. This action cannot be undone.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Request Example

curl -X DELETE "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN"

Success Response (200 OK)

{
  "code": 0,
  "data": null,
  "msg": "Agent deleted successfully"
}

Error Response (6200 Not Found)

{
  "code": 6200,
  "data": {
    "agent_id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "msg": "Agent not found"
}

Publish Agent

POST /api/v1/agents/{agent_id}/publish

Set the agent status to published, making it available for chat. The publish operation does not validate whether a model is configured (model validation occurs in subsequent chat/access paths with error code 6202).

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Request Example

curl -X POST "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000/publish" \
  -H "Authorization: Bearer YOUR_TOKEN"

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "published"
  },
  "msg": "Agent published successfully"
}

The publish endpoint only sets the status and does not validate the model. If the agent is in draft status during a subsequent chat, 6202 Agent not published will be returned.


Unpublish Agent

POST /api/v1/agents/{agent_id}/unpublish

Set the agent status to draft, making it unavailable for chat.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Request Example

curl -X POST "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000/unpublish" \
  -H "Authorization: Bearer YOUR_TOKEN"

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "draft"
  },
  "msg": "Agent unpublished successfully"
}

Duplicate Agent

POST /api/v1/agents/{agent_id}/duplicate

Duplicate an existing agent within the same team, copying:

  • Prompts: system prompt, opening message, suggested questions, powered_by_text
  • Configuration: tools, attachments, memory, context compression, rag_mode, variables, iteration limit
  • Media generation: image and video generation settings (both configs have allow_model_override stripped for security)
  • Knowledge bases: every knowledge base association and its retrieval settings

Requires access to the agent plus the team's agent:create permission.

The copy is always created with visibility: private and status: draft, and its name gets a " (Copy)" suffix. Publish it again before it can be used for chat. Tool credentials (tools_credentials) are not copied — tools in the copy need their keys reconfigured before they can call external services.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID to duplicate

Success Response (200 OK)

Returns the newly created AgentOut (status is draft):

{
  "code": 0,
  "data": {
    "id": "new-agent-uuid",
    "name": "Customer Support Agent (Copy)",
    "status": "draft",
    "visibility": "private"
  },
  "msg": "Agent duplicated successfully"
}

Get Video Generation Status

GET /api/v1/agents/{agent_id}/media/video-status?task_id={task_id}

Poll an asynchronous video generation task started by an agent; requires agent:read and access to the agent. The agent must have video generation enabled (enable_video_generation), otherwise the call returns 400 (code 1002, video_generation_not_enabled_for_agent).

Query Parameters

ParameterTypeRequiredDescription
task_idstringYesVideo generation task ID

The response uses the same media.video shape as the chat media_result event, so clients can decide whether to keep polling:

{
  "code": 0,
  "data": {
    "kind": "media.video",
    "success": true,
    "prompt": "",
    "model": "veo-3",
    "model_ref": "video-model-uuid",
    "task_id": "video-task-uuid",
    "status": "succeeded",
    "progress": 100,
    "video": {
      "url": "/api/v1/upload/files/generated-videos/2026/09/9a8b7c6d5e4f_55667788.mp4",
      "asset_ref": "a1b2",
      "format": "mp4"
    },
    "estimated_time": null,
    "requires_polling": false,
    "poll_interval_ms": 3000,
    "poll_timeout_s": 120,
    "error": null
  },
  "msg": "success"
}
FieldDescription
statusNormalized task status; success is true only when the task has not failed and error is null.
progressTask progress percentage (null when the provider does not report one).
videoThe finished video object (url, asset_ref, format), or null while the task is still running.
requires_pollingtrue while the task is queued/running — keep polling every poll_interval_ms.
poll_interval_ms / poll_timeout_sTaken from the agent's video_generation_config; default 3000 / 120.

Fetch the protected video URL with the active JWT or API key.


Get Public Agent Info

GET /api/v1/agents/{agent_id}/public

Returns the public chat-page view: name, description, icon, opening message, suggested questions, variable definitions, and the attachment switch. The route is implemented in chat.py but mounted under /api/v1/agents, and it does not require agent:read.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Authentication behaviour

The route declares an optional-auth dependency, but the lookup still requires an authenticated identity (an unauthenticated caller gets 401 not_authenticated). Once authenticated, visibility is:

  • private: the creator, a superuser, or — for creator-less legacy rows — any member of the agent's team.
  • team (including the legacy value public): any member of the agent's team; superusers bypass the check.

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Customer Support Agent",
    "description": "Helps customers with common questions",
    "icon": "🤖",
    "avatar_url": "https://example.com/avatar.png",
    "opening_message": "Hi! How can I help you today?",
    "suggested_questions": ["What are your business hours?"],
    "powered_by_text": null,
    "variables": [],
    "enable_attachments": false,
    "attachment_config": null,
    "hide_tool_calls": false,
    "hide_message_actions": false,
    "hide_reasoning": false,
    "created_by": {
      "id": "user-001",
      "username": "alice",
      "avatar_url": null
    }
  },
  "msg": "success"
}

Unlike GET /api/v1/agents/{agent_id}, this response never exposes the model, system prompt, tool configuration, or statistics fields.

ErrorCodeDescription
403 Forbidden6201The caller cannot see this agent
404 Not Found6200Agent does not exist

Chat (Non-Streaming)

POST /api/v1/agents/{agent_id}/chat

Send a message to the agent and synchronously receive the complete response. Suitable for short responses; for long tasks, use the SSE streaming endpoint.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Request Body

{
  "message": "What are your business hours?",
  "conversation_id": "conv-123",
  "file_urls": [
    {
      "asset_id": "asset-456",
      "url": "https://your-domain.com/api/v1/upload/files/general/2026/09/7f3a1c9d2b10_a1b2c3d4.pdf",
      "filename": "7f3a1c9d2b10_a1b2c3d4.pdf",
      "size": 1048576,
      "mime_type": "application/pdf"
    }
  ],
  "variables": {
    "customer_tier": "premium"
  }
}

Submit url, filename, size, and mime_type exactly as returned by the upload response; do not construct /upload/files/{asset_id} from the asset ID. A generated media asset_ref is valid only within its conversation or workflow-run scope, and protected URLs require the active JWT or API key.

Request Fields

FieldTypeRequiredDescription
messagestringYesUser message (max 32000 chars)
imagesarrayNoVision images (asset_id or asset_ref, type, url)
filesarrayNoParsed files (deprecated, use file_urls)
file_urlsarrayNoAsset metadata from the upload response (asset_id, filename, url, size, mime_type)
conversation_idstringNoConversation UUID; creates a new one if not provided
variablesobjectNoVariable values for the chat input form
history_overridearrayNoOverride conversation history (used for version switching/regeneration)

Request Example

curl -X POST "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000/chat" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What are your business hours?",
    "conversation_id": "conv-123"
  }'

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "conversation_id": "conv-123",
    "message": {
      "id": "msg-456",
      "conversation_id": "conv-123",
      "role": "assistant",
      "content": "Our business hours are Monday-Friday, 9 AM to 5 PM EST.",
      "tool_calls": [],
      "tool_name": null,
      "model_used": "gpt-4",
      "token_usage": {
        "prompt": 150,
        "completion": 25,
        "total": 175
      },
      "duration_ms": 2300,
      "rag_context": [
        {
          "document_id": "doc-789",
          "document_name": "Business Hours Policy",
          "chunk_id": "chunk-012",
          "content": "Business hours: Monday-Friday, 9 AM to 5 PM EST",
          "score": 0.95
        }
      ],
      "created_at": "2026-02-11T16:00:00Z",
      "version_number": 1,
      "version_count": 1
    },
    "usage": {
      "prompt": 150,
      "completion": 25,
      "total": 175
    }
  },
  "msg": "success"
}

Chat (Streaming)

POST /api/v1/agents/{agent_id}/chat/stream

Return the response as a stream via SSE (Server-Sent Events). The request body is the same as the non-streaming endpoint; there is no stream flag parameter.

Request Example

curl -X POST "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000/chat/stream" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What are your business hours?",
    "conversation_id": "conv-123"
  }'

SSE Event Format

event: message_start
data: {"conversation_id": "conv-123", "message_id": "msg-456"}

event: content_delta
data: {"delta": "Our"}

event: content_delta
data: {"delta": " business"}

event: content_delta
data: {"delta": " hours"}

event: rag_context
data: {"contexts": [{"document_name": "FAQ", "content": "...", "score": 0.95}]}

event: message_end
data: {"usage": {"prompt_tokens": 150, "completion_tokens": 25, "total_tokens": 175}, "timing": {"first_token_ms": 320, "duration_ms": 2300, "tokens_per_second": 10.9}}
EventDescription
message_startMessage started, returns conversation_id and message_id
content_deltaIncremental text fragment
rag_contextRAG retrieval context (document name, content, relevance score)
message_endMessage ended, returns token usage and timing metrics

SSE clients need to parse the event stream as text/event-stream. See SSE Streaming Events for details.


Regenerate

POST /api/v1/agents/{agent_id}/messages/{message_id}/regenerate

Regenerate the response for a specified message. The request body structure is the same as the chat endpoint, and history_override can be used to adjust the historical context.

Edit Message and Create Branch

POST /api/v1/agents/{agent_id}/messages/{message_id}/edit/stream

Edit a user message and generate a branch response, returned as an SSE stream.

Query Message Versions

GET /api/v1/agents/{agent_id}/messages/{message_id}/versions

Query all versions of a specified message (including historical branches generated by regeneration and editing).

Switch Version

POST /api/v1/agents/{agent_id}/messages/{message_id}/switch-version

Switch to a specified version as the currently active message.


Agent Conversations

These conversation endpoints are registered on the agents router, so the conversation segment resolves to /api/v1/agents/conversations/.... Every route is scoped to the authenticated user (Conversation.user): another user's conversation is treated as not found (404, code 6210).

A separate team/admin-oriented set of routes lives at /api/v1/conversations (GET list, GET detail, single/batch delete, statistics) — see Conversations API. This section covers only the caller's own conversations.

List Conversations for an Agent

GET /api/v1/agents/{agent_id}/conversations

Returns the caller's own conversations for one agent. Requires conversation:read and access to the agent (check_agent_access).

ParameterTypeRequiredDefaultDescription
searchstringNo-Match title or conversation ID (contains)
created_afterstring (ISO 8601)No-Only conversations created at or after this time
created_beforestring (ISO 8601)No-Only conversations created at or before this time
sort_bystringNoupdated_atSort field: created_at, updated_at, message_count (any other value falls back to updated_at)
pageintegerNo1Page number (min 1)
page_sizeintegerNo20Items per page (1-100)

Results are ordered by the sort field descending and returned as a PageData[ConversationListOut] envelope (items, total, page, page_size), with agent_name/agent_icon filled in from the agent.

List My Conversations

GET /api/v1/agents/conversations/my

Returns all of the caller's conversations across agents. Requires conversation:read.

ParameterTypeRequiredDefaultDescription
agent_idstringNo-Filter by agent UUID
pageintegerNo1Page number
page_sizeintegerNo20Items per page

The response is again a PageData[ConversationListOut] envelope; agent_name and agent_icon are null when the agent has been deleted.

Get Conversation

GET /api/v1/agents/conversations/{conversation_id}

Returns the conversation together with its visible messages, each carrying version_count. Requires conversation:read, and only the owner can read it.

The response data is a ConversationWithMessages: the ConversationOut fields (id, agent_id, agent_name, agent_icon, title, variables, message_count, token_usage, created_at, updated_at) plus messages (a MessageOut[]; the message shape is documented in the Chat API).

Update Conversation

PATCH /api/v1/agents/conversations/{conversation_id}

Rename a conversation. Requires conversation:read, and only the owner can update it.

{
  "title": "Updated Conversation Title"
}
FieldTypeRequiredDescription
titlestringNoNew title (1-200 chars)

Omitting title leaves the conversation unchanged; the success response has msg_key conversation_updated.

Delete Conversation

DELETE /api/v1/agents/conversations/{conversation_id}

Permanently delete a conversation (messages cascade). Requires conversation:delete, and only the owner can delete it. The agent's conversation_count and message_count are decremented first.

{
  "code": 0,
  "data": {
    "id": "conv-123"
  },
  "msg": "Conversation deleted successfully"
}

Delete a Single Message

DELETE /api/v1/agents/conversations/{conversation_id}/messages/{message_id}

Delete one message from a conversation. Requires conversation:delete, and the message must belong to the caller's conversation. The conversation's message_count and token_usage are updated in the same row-locked transaction that removes the message, so concurrent deletes cannot drift the counters.

ErrorCodeDescription
404 Not Found6210Conversation does not exist or is not owned by the caller
404 Not Found6211Message does not exist or does not belong to that conversation
{
  "code": 0,
  "data": {
    "id": "msg-456"
  },
  "msg": "Message deleted successfully"
}

Agent Statistics

GET /api/v1/agents/{agent_id}/stats

Query the usage statistics overview of an agent within a specified time range.

Path Parameters

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID

Query Parameters

ParameterTypeRequiredDefaultDescription
periodstringNo7dTime range: 24h, 7d, 30d, all

Request Example

curl -X GET "https://your-domain.com/api/v1/agents/550e8400-e29b-41d4-a716-446655440000/stats?period=30d" \
  -H "Authorization: Bearer YOUR_TOKEN"

Success Response (200 OK)

{
  "code": 0,
  "data": {
    "period": "30d",
    "overview": {
      "total_conversations": 156,
      "total_messages": 1234,
      "user_messages": 620,
      "assistant_messages": 610,
      "tool_messages": 4,
      "active_users": 23
    },
    "tokens": {
      "prompt_tokens": 250000,
      "completion_tokens": 206789,
      "total_tokens": 456789
    },
    "performance": {
      "avg_response_time_ms": 2300,
      "first_token_ms": {
        "p50": 1200,
        "p95": 9000,
        "avg": 2500,
        "samples": 480
      }
    },
    "tools": {
      "tool_call_count": 512
    },
    "health": {
      "completed": 90,
      "failed": 6,
      "stopped": 4,
      "interrupted": 3,
      "unrecognised": 0,
      "in_flight": 2,
      "total": 103,
      "success_rate": 0.8738
    },
    "interventions": {
      "steer": 12,
      "stop": 3,
      "follow_up": 5,
      "total": 20
    }
  },
  "msg": "success"
}

health counts this agent's runs by outcome:

FieldMeaning
completed / failed / stoppedRuns that reached that terminal state.
interruptedTerminal. The worker executing the run was lost (crash, restart, eviction), so the run never reached completion. Counts toward total and lowers success_rate.
unrecognisedA stored status this build does not know (typically written by a different release). Reported separately so enum drift stays visible instead of being folded into a known bucket or failing the request.
in_flightNon-terminal runs (queued, running, stopping, completing, waiting). Excluded from total and from the success_rate denominator.
totalTerminal runs only: completed + failed + stopped + interrupted.
success_ratecompleted / total, or 0 when there are no terminal runs.

Trend Data

GET /api/v1/agents/{agent_id}/stats/trends

Returns a clock-aligned point grid: 24 points for 24h, 7 for 7d, 30 for 30d. Missing buckets are filled with 0.

{
  "code": 0,
  "data": {
    "period": "24h",
    "granularity": "hour",
    "data": [
      {
        "timestamp": "2026-09-13T13:00:00+08:00",
        "label": "13:00",
        "conversations": 12,
        "messages": 87,
        "tokens": 32100,
        "avg_response_time_ms": 2150.5,
        "first_token_p50_ms": 1180.0,
        "first_token_p95_ms": 8700.0
      }
    ]
  },
  "msg": "success"
}

first_token_p50_ms and first_token_p95_ms are null for a bucket with no measured sample, so the latency line breaks instead of dropping to 0; clients must handle null.

Tool Usage

GET /api/v1/agents/{agent_id}/stats/tool-usage

tools[].name is the internal tool identifier and display_name is the localized label (MCP tools render as a server prefix plus the tool name). Tools are sorted by call count descending, and total_calls sums every call.

{
  "code": 0,
  "data": {
    "period": "7d",
    "tools": [
      {
        "name": "web_search",
        "display_name": "Web Search",
        "count": 312
      }
    ],
    "total_calls": 512
  },
  "msg": "success"
}

This endpoint deliberately disables MCP enumeration (enumerate_mcp_tools=False), so a statistics request never makes a network call to an external MCP server. MCP tool labels therefore use the known server prefix rather than a live tool list.

Other Statistics Endpoints

Both supplemental statistics endpoints require the /api/v1 prefix, a valid JWT current user, and pass through check_agent_access:

EndpointDescriptionParameters
GET /api/v1/agents/{agent_id}/stats/trendsTrend dataperiod: 24h/7d/30d
GET /api/v1/agents/{agent_id}/stats/tool-usageTool usage statisticsperiod: 24h/7d/30d/all

Period boundary behaviour: for the overview and tool-usage endpoints any value other than 24h, 7d, or 30d is treated as all; the trends endpoint treats anything other than 24h or 7d as 30d.

Access control: the statistics endpoints call check_agent_access(..., require_write=True) — superusers are allowed; a private agent is readable only by its creator (creator-less legacy agents fall back to team scope and additionally require a team admin); team/public agents require team access, and a non-creator must be a team admin. In other words, agent statistics are an admin/monitoring view; an ordinary team member cannot read them. Denied requests return 403, missing resources 404.


Access Boundaries

  • The agent must be in published status to be used for chat.
  • The API Key must have the corresponding permissions; if the API Key is bound to a specific agent, it can only access agent IDs in the allowlist.
  • The agent's attachment limits, tool iteration caps, and model quotas still apply during API calls.

Error Codes

CodeMessageDescription
6200Agent not foundAgent does not exist
6201Access deniedCurrent user does not have access to the agent
6202Agent not publishedAgent is in draft status
3000Permission deniedInsufficient permissions
1001Validation failedInvalid request data
5104Duplicate nameAgent name is already taken

The current endpoints do not implement individual rate limiting; there is no rate-limit middleware.


  • API Get Started — Create an API Key, configure the base URL, and send your first request
  • Agent Chat — Send messages, attachments, variables, and consume streaming responses
  • SSE Streaming Events — Parse SSE events for agents and workflows
  • Error Handling — Recover by HTTP status and business error codes

How is this guide?

On this page