ClouisleClouisle

嵌入集成 API

面向第三方网站与 iframe 嵌入的 Agent 对话与工作流执行 API

嵌入集成 API(Embed API)专门用于将 Clouisle 的 Agent 对话组件和工作流执行集成到第三方网页、内部平台或无 Cookie 客户端中。基础路径为 /api/v1/embed。

认证与安全策略

所有嵌入端点均仅支持 API Key 认证(前缀为 clou_),不接受 Cookie 会话。认证凭据可通过以下两种方式传入:

  • 请求头:Authorization: Bearer clou_...
  • 查询参数:?token=clou_...

解析顺序是先看 token 查询参数,再看 Authorization 头;两处都必须以 clou_ 开头,否则视同缺少凭据并返回 401(业务码 2000,embed_api_key_required)。

除鉴权外,目标还必须处于可嵌入状态:Agent 与工作流必须是 published,且 embed_config.enabled 为 true,否则分别返回 404(agent_not_found / workflow_not_found)与 403(embed_not_enabled)。

浏览器嵌入页面

除 REST 命名空间外,产品还提供两个可直接用于 <iframe> 的页面(不经过 /api/v1 前缀):

页面用途查询参数
/embed/agent/{agent_id}完整的免登录 Agent 聊天界面(复用公开聊天页)token=clou_...(必填)、mode=fullscreen 或 bubble(默认 fullscreen)
/embed/workflow/{workflow_id}工作流运行界面(复用运行详情页)token=clou_...(必填)
<iframe
  src="https://your-domain.com/embed/agent/550e8400-e29b-41d4-a716-446655440000?token=clou_xxx&mode=bubble"
  style="width: 420px; height: 640px; border: 0"
></iframe>

为避免把 API Key 暴露在 URL 中,页面支持通过 postMessage 传递凭据:iframe 加载后会向父窗口发送 { "type": "clouisle:ready" },父窗口回传 { "type": "clouisle:token", "token": "clou_..." } 即可;URL 中的 token 仍可用作兜底。若两者都没有,页面停在加载态(Agent 页面)或提示 invalidToken(工作流页面)。

iframe 还会向父窗口发送两类事件,便于宿主页面联动:{ "type": "clouisle:conversation", "conversationId": "..." }(会话创建/切换时)与 { "type": "clouisle:close" }(用户点击关闭)。

嵌入模式的能力边界:会话历史保存在浏览器 localStorage(键为 clouisle:embed:history:agent:{agent_id}),不依赖登录态;消息编辑、重新生成与版本切换在嵌入模式不可用(前端直接禁用)。

域名白名单校验(allowed_domains)

若 Agent 或工作流在 embed_config 中配置了 allowed_domains:

  1. 服务端将提取请求头中的 Origin 或 Referer,并与配置的白名单逐一比对(支持通配符子域名如 *.example.com)。
  2. 若来源域名不匹配,服务端拒绝请求并返回 403 Forbidden(业务码 3000,错误提示 embed_domain_not_allowed)。
  3. 无来源头的内部直接调用(如测试阶段)或未配置域名白名单时,允许访问。
  4. 工作流流式事件订阅(GET /workflows/runs/{run_id}/stream)豁免域名校验。

Agent 嵌入端点

方法路径说明
GET/api/v1/embed/agents/{agent_id}/info获取嵌入组件所需的公共配置与变量
POST/api/v1/embed/agents/{agent_id}/chat/streamSSE 流式发送聊天消息
POST/api/v1/embed/agents/{agent_id}/chat/runs创建持久化异步 Agent 运行(返回 202)
GET/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/stream订阅持久化运行的重放与实时 SSE 事件流
GET/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}查询持久化运行的状态
GET/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/events按序号回放已缓冲的运行事件
POST/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/inputs运行过程中发送干预引导(steer)或追问消息
POST/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/answers提交模型调用 ask_user 等待的结构化答案
POST/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/stop协作式终止当前运行
GET/api/v1/embed/agents/{agent_id}/conversations/{conversation_id}/messages获取嵌入会话的历史消息列表
POST/api/v1/embed/agents/{agent_id}/upload/file上传嵌入会话中的附件文件

1. 获取嵌入 Agent 信息

GET /api/v1/embed/agents/{agent_id}/info HTTP/1.1
Authorization: Bearer clou_api_key

成功响应(200 OK)

{
  "code": 0,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "在线客服助手",
    "description": "回答用户关于退换货和价格的问题",
    "icon": "🤖",
    "avatar_url": null,
    "opening_message": "您好!请问有什么可以帮助您?",
    "suggested_questions": [
      "如何办理退换货?",
      "发票怎么开具?"
    ],
    "variables": [],
    "enable_attachments": true,
    "attachment_config": {
      "max_file_count": 5,
      "max_file_size_mb": 10
    },
    "hide_tool_calls": false,
    "hide_message_actions": false,
    "hide_reasoning": false,
    "embed_config": {
      "enabled": true,
      "allowed_domains": ["https://example.com"]
    }
  },
  "msg": "success"
}

2. 流式发送聊天消息

POST /api/v1/embed/agents/{agent_id}/chat/stream HTTP/1.1
Authorization: Bearer clou_api_key
Content-Type: application/json

{
  "message": "退换货的期限是几天?",
  "conversation_id": "conv-uuid-optional",
  "variables": {}
}

响应以 text/event-stream SSE 形式返回,事件与主聊天流式端点完全相同(message_start、content_delta、rag_start/rag_context、reasoning_start/reasoning_delta/reasoning_end、tool_call/tool_result、media_result、compression_start/compression_end、output_truncated、iteration_cap_reached、message_end、error),详见 SSE 流式事件。

3. 创建持久化运行(Durable Run)

对于支持断线重连、长流程工具调用的场景,推荐使用运行管理流程:

POST /api/v1/embed/agents/{agent_id}/chat/runs HTTP/1.1
Authorization: Bearer clou_api_key
Content-Type: application/json

{
  "message": "生成本季度销售报告",
  "conversation_id": null,
  "variables": {}
}

响应(202 Accepted)

{
  "code": 0,
  "data": {
    "run_id": "run-uuid-1234",
    "conversation_id": "conv-uuid-5678",
    "status": "queued",
    "stream_url": "/embed/agents/550e8400-e29b-41d4-a716-446655440000/chat/runs/run-uuid-1234/stream"
  },
  "msg": "success"
}

客户端可随时发起 GET /api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/stream?after_sequence=N 订阅事件流,并通过 after_sequence 实现去重与断点续连。

4. 运行控制与查询参数

方法路径查询参数 / 请求体
GET/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/streamafter_sequence(默认 0,负值按 0)——先回放序号更大的缓冲事件再跟随实时流
GET/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/eventsafter_sequence(默认 0)——非流式读取已缓冲事件
GET/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}无——返回 RunOut(status、error_code、pending_tool_* 等)
POST/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/inputsJSON:delivery(steer/follow_up/auto,默认 auto)、content、attachments、request_id(幂等键)
POST/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/answersJSON:tool_call_id(必填)、answers(ID → 答案)、skipped
POST/api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/stop无请求体——协作式终止,随后事件流收到 run_end(status: "stopped")
GET/api/v1/embed/agents/{agent_id}/conversations/{conversation_id}/messages无——返回该会话的可见消息(含 version_count);会话必须属于该 API Key 绑定的用户,否则 404(6210)
POST/api/v1/embed/agents/{agent_id}/upload/filemultipart/form-data,字段名 file,查询参数 category(默认 documents)

运行状态的取值、run_end 的唯一性与断点续连策略与主聊天一致,见 Agent 聊天 API 的持久运行与控制 与 SSE 流式事件。


工作流嵌入端点

方法路径说明
GET/api/v1/embed/workflows/{workflow_id}/info获取工作流嵌入信息(输入参数定义等)
POST/api/v1/embed/workflows/{workflow_id}/run启动嵌入工作流运行
GET/api/v1/embed/workflows/runs/{run_id}/streamSSE 流式订阅工作流节点执行过程与结果

1. 运行工作流

POST /api/v1/embed/workflows/{workflow_id}/run HTTP/1.1
Authorization: Bearer clou_api_key
Content-Type: application/json

{
  "inputs": {
    "query": "分析最近客户反馈",
    "format": "markdown"
  }
}

响应(200 OK)

{
  "code": 0,
  "data": {
    "run_id": "wf-run-uuid-1234",
    "stream_url": "/api/v1/workflows/runs/wf-run-uuid-1234/stream"
  },
  "msg": "success"
}

返回的 stream_url 指向主工作流流式路由(/api/v1/workflows/runs/{run_id}/stream),该路由面向登录会话;嵌入客户端应改为订阅 GET /api/v1/embed/workflows/runs/{run_id}/stream?from_sequence=N。

2. 订阅工作流运行进度

GET /api/v1/embed/workflows/runs/{run_id}/stream?from_sequence=0
参数类型必填默认值说明
from_sequenceinteger否0从该序号之后开始回放,再跟随实时事件;用于断线续读

注意与 Agent 运行流的命名差异:工作流侧用 from_sequence,Agent 侧用 after_sequence。该路由不做域名白名单校验(其余工作流嵌入端点都会校验),但会检查运行必须由当前 API Key 绑定的用户触发,否则返回 404(workflow_run_not_found)。

3. 工作流嵌入信息

GET /api/v1/embed/workflows/{workflow_id}/info

返回 id、name、description、icon、variables(输入参数定义)与 embed_config。工作流必须已发布且开启嵌入,否则返回 404(workflow_not_found)或 403(embed_not_enabled)。


错误代码

错误码标识说明
2000UNAUTHORIZED缺少 API Key、凭据前缀不是 clou_,或 Key 无效/过期(embed_api_key_required)
3000PERMISSION_DENIED未开启嵌入功能(embed_not_enabled),或请求来源域名不在白名单中(embed_domain_not_allowed)
4000NOT_FOUND工作流不存在或未发布(workflow_not_found);工作流运行不存在或不是由该 API Key 用户触发(workflow_run_not_found)
6200AGENT_NOT_FOUNDAgent 不存在或未处于已发布状态(agent_not_found)
6210CONVERSATION_NOT_FOUND会话不存在或不属于当前 API Key 绑定的用户

这篇文章对你有帮助吗?

本页目录