文档中心/ 百度搭子/ 生态开放平台指南/ 标准化OpenAPI接入指南

标准化OpenAPI接入指南

本文档介绍如何通过标准化 OpenAPI 将搭子的核心能力接入到硬件或软件应用中。通过 OpenAPI,可接入的搭子能力包括:

  • 会话与消息:创建会话、发送消息、接收流式回复、管理历史会话
  • 对话交互:处理搭子的澄清问答与权限申请弹窗
  • 文件:上传文件、获取会话产出物(报告、文档、图片等)
  • 积分:查询余额、发放与消费流水
  • Skill 管理:初始化、查询 Skill 列表与详情
  • 定时任务:查询定时任务列表
  • 个性化配置:定制首页 Logo、slogan 与推荐问

1 快速开始

1.1 接入总览

接入遵循以下流程:

  1. 申请 API Key:按 1.2 API Key 申请步骤注册账号并获取沙盒 / 线上两套 Key。
  2. 获取访问凭证:调用 DescribeToken 获取渠道用户 Token({dumateToken}),用于后续所有接口鉴权。
  3. 创建会话:调用 POST /session 创建会话,获得 sessionID。
  4. 发送消息:调用 POST /session/:sessionID/prompt_async 发送用户输入。
  5. 接收回复:通过 GET /event(SSE)订阅实时事件,接收搭子产生的文本、工具调用、任务进度等消息。
  6. 管理会话:按需调用停止消息、历史会话/消息查询、文件与积分等接口。

1.2 API Key 申请步骤

API Key 是账号级凭证,所有接口均通过 Authorization: Bearer {apiKey} 携带。申请流程如下:

步骤 操作 说明
1. 注册账号 在百度智能云注册账号 需提供企业或个人实名信息,用于身份核验
2. 提交入驻申请 请在 硬件合作申请 中提交相关信息 说明接入用途(如"自研 App 内搭子"),便于审核
3. 审核 等待服务方审核 "申请中 → 审核通过",通过后可进入控制台创建 Key;审核驳回会说明原因
4. 创建沙盒 Key 在控制台创建一个"沙盒环境"API Key 用于联调环境测试(见 1.3),额度与线上隔离
5. 创建线上 Key 审核通过后创建"线上环境"API Key 用于生产环境,涉及真实积分扣减
6. 环境绑定 将两把 Key 分别用于对应环境 沙盒与线上 Key 不可混用;线上请求必须使用线上 Key

说明:

  • Key 创建后在控制台仅展示一次,请立即保存到安全的密钥管理位置(环境变量 / 密钥服务),不要硬编码在代码或提交到仓库。
  • Key 泄露可在控制台吊销后重新创建,吊销会使对应环境所有请求鉴权失败。
  • {route} 路由段与沙盒域名会随入驻审核通过一并提供(见 1.3)。

1.3 环境与地址

所有接口提供联调(沙盒)与线上两套环境,接入阶段请先使用沙盒环境联调,通过后切换到线上环境。

环境 标准 OpenAPI 地址 Dispatch 服务地址
沙盒 https://www.dumate.cn/openapi-sandbox?Action=ActionName 域名与路由前缀由服务方在入驻时提供
线上 https://www.dumate.cn/openapi?Action=ActionName https://www.dumate.cn/dispatch/{route}/...

说明:

  • ActionName 为接口名称,下文各接口均以 Action=接口名 方式调用(除 dispatch 服务外默认走标准 OpenAPI)。
  • Dispatch 服务地址中的 {route} 为服务方分配的接入路由段,非公开通用值,接入时向服务方获取。
  • 沙盒环境的 dispatch 域名与路由段由服务方在入驻时提供,本文用 {sandbox-host} / {sandboxRoute} 表示;线上统一为 www.dumate.cn / {route}。
  • 沙盒与线上环境使用不同的 API Key,请勿混用。

1.4 请求方式与鉴权

  • 请求方式:如无特别说明,默认 POST,请求体为 JSON。
  • 鉴权方式:Bearer Token,所有接口均需在请求 Header 中携带 Authorization(API Key)与 X-Dumate-Token(用户 Token),详见 2 鉴权。

1.5 第一个请求示例(获取 Token)

Bash
1curl -X POST 'https://www.dumate.cn/openapi?Action=DescribeToken' \
2  -H 'Authorization: Bearer {apiKey}' \
3  -H 'X-Dumate-User-Id: {X-Dumate-User-Id}' \
4  -H 'X-Dumate-Token: {dumateToken}' \
5  -H 'Content-Type: application/json'

响应:

JSON
1{
2  "token": "{dumateToken}",
3  "expired_at": "2026-07-10T13:58:49.23978Z"
4}

1.6 端到端最小示例

以下 5 步串起一次完整对话(沙盒环境,全部使用沙盒 Key 与沙盒域名)。可直接复制调试,再按 1.7 切换线上。

Step 1 获取 Token(DescribeToken)

Bash
1curl -X POST 'https://www.dumate.cn/openapi-sandbox?Action=DescribeToken' \
2  -H 'Authorization: Bearer {sandboxApiKey}' \
3  -H 'X-Dumate-User-Id: {X-Dumate-User-Id}' \
4  -H 'Content-Type: application/json'

返回 token(即 {dumateToken})。

Step 2 创建会话(POST /session)

Bash
1curl -X POST 'https://{sandbox-host}/dispatch/{sandboxRoute}/session' \
2  -H 'Authorization: Bearer {dumateToken}' \
3  -H 'X-Dumate-Device-Id: 1|web.{raw-device-id}' \
4  -H 'Content-Type: application/json' \
5  -d '{"title": "首次对话"}'

返回会话对象中的 id 即 {sessionID}。

Step 3 发送消息(POST /session/:sessionID/prompt_async)

Bash
1curl -X POST 'https://{sandbox-host}/dispatch/{sandboxRoute}/session/{sessionID}/prompt_async' \
2  -H 'Authorization: Bearer {dumateToken}' \
3  -H 'X-Dumate-Device-Id: 1|web.{raw-device-id}' \
4  -H 'Content-Type: application/json' \
5  --data-raw '{"parts": [{"type": "text", "text": "你好,请介绍一下你自己"}]}'

返回 HTTP 204,无响应体。

Step 4 接收回复

  • 方案 A(推荐,实时):通过 GET /event(SSE)订阅,等待"消息完成 / 会话空闲"类事件后结束本条消息的等待(事件协议见 3.3)。
  • 方案 B(兜底,轮询):轮询 DescribeSessionStatus 直到该会话不再是 busy(不再出现在结果中),再调用 DescribeSessionMessages 拉取最终文本:
Bash
1# 等待会话空闲
2curl -X POST 'https://www.dumate.cn/openapi-sandbox?Action=DescribeSessionStatus' \
3  -H 'Authorization: Bearer {sandboxApiKey}' \
4  -H 'X-Dumate-Token: {dumateToken}'
5
6# 拉取对话消息
7curl -X POST 'https://www.dumate.cn/openapi-sandbox?Action=DescribeSessionMessages&sessionID={sessionID}&limit=10' \
8  -H 'Authorization: Bearer {sandboxApiKey}' \
9  -H 'X-Dumate-Token: {dumateToken}'

Step 5 验证扣分(DescribePointsUsage)

Bash
1curl -X POST 'https://www.dumate.cn/openapi-sandbox?Action=DescribePointsUsage' \
2  -H 'Authorization: Bearer {sandboxApiKey}' \
3  -H 'X-Dumate-Token: {dumateToken}' \
4  -H 'Content-Type: application/json' \
5  -d '{"startAt": {startAt}, "endAt": {endAt}}'

list 中出现 pointsChange 为负值的记录即表示本次对话已计费(扣分规则见 6.5)。

说明:Step 4 方案 B 中 DescribeSessionStatus 仅返回非空闲会话,会话从结果中消失即可认为处理完成;如需要更精确的完成判定,以 Step 4 方案 A 的 SSE 事件为准。

1.7 沙盒迁移线上切换清单

联调通过后切换线上环境,逐项核对:

检查项 沙盒 线上
1. API Key 沙盒 Key({sandboxApiKey}) 线上 Key(控制台创建)
2. 标准 OpenAPI 域名 openapi-sandbox openapi
3. Dispatch 域名/路由段 {sandbox-host} / {sandboxRoute} www.dumate.cn / {route}
4. 用户 Token 沙盒环境获取 线上环境重新获取(建议线上使用线上环境签发的 Token,沙盒 Token 在线上可能失效)
5. 数据/扣费 测试数据,不产生真实扣费 生产数据,真实扣减积分
6. 回归冒烟 - 用 1.6 的 5 步链路在线上完整跑一遍

2 鉴权

2.1 获取访问凭证 DescribeToken

获取(含刷新)渠道用户 Token,用于后续全部接口调用。首次获取时,Header 中传入 X-Dumate-User-Id,值为 App 跳转时带过去的 userId 字段值。

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeToken
是否鉴权 是(API Key)

请求 Header

Header 必填 说明
Authorization 是 Bearer {apiKey}
Content-Type 是 application/json
X-Dumate-User-Id 首次获取必填 App 跳转时带过去的用户 ID 字段值
X-Dumate-Token 刷新时必填 已持有的用户 Token

请求体:无。

响应参数

字段 类型 说明
token string 访问凭证(Token),后续接口以 X-Dumate-Token Header 携带
expired_at string 过期时间,UTC 格式(例:2026-07-10T13:58:49.23978Z 表示北京时间 2026-07-10 21:58:49 过期)

响应示例

JSON
1{
2  "token": "{dumateToken}",
3  "expired_at": "2026-07-10T13:58:49.23978Z"
4}

注意事项:

  • Token 有过期时间,请关注 expired_at(UTC)并提前刷新,避免接口调用因 Token 过期失败。
  • 首次获取与刷新均使用本接口,首次需额外携带 X-Dumate-User-Id。

Token 刷新标准流程(推荐实现):

  1. 主动预刷新:检测到 expired_at 距今不足 10 分钟时,调用 DescribeToken(携带旧 Token 的 X-Dumate-Token Header)刷新后继续使用新 Token。
  2. 401 被动刷新:任意接口返回 code=401 / PermissionDenied 时,先调用 DescribeToken 刷新 Token,再重试原请求一次(最多一次,避免死循环)。
  3. 保存与同步:刷新成功后立即替换本地 Token 并持久化;多端场景可通过账号体系广播新 Token。

注意:DescribeToken 不带 X-Dumate-Token 时视为首次获取(需 X-Dumate-User-Id);带旧 Token 时视为刷新。两者响应结构一致。

2.2 请求 Header

以下 Header 为全部标准 OpenAPI 接口通用。

Header 值 必填 备注
Authorization Bearer {apiKey} 是 API Key 来源于开放平台控制台;注意区分沙盒与线上环境的 Key
X-Dumate-Token {dumateToken} 是 由 DescribeToken 获取
Content-Type application/json 是 如接口有特殊说明(如文件上传),按具体接口执行

2.3 响应结构

所有接口响应统一包含以下字段:

名称 类型 说明
requestId string 请求 ID,用于问题定位
code string 错误码(仅异常时返回)
message string 错误信息(仅异常时返回)

成功场景:

JSON
1HTTP/1.1 200 OK
2{
3  "requestId": "{requestId}",
4  "otherField": any
5}

失败场景(HTTP 状态码仍为 200,业务错误以 code / message 标识):

JSON
1{
2  "code": "401",
3  "message": "PermissionDenied",
4  "requestId": "{requestId}"
5}

3 会话与消息

3.1 创建会话 POST /session

用户发起新对话时调用,创建会话并启动运行环境。

项目 内容
请求方式 POST
请求路径 /dispatch/{route}/session
是否鉴权 是(用户 Token + 设备 ID)

请求 Header

Header 必填 说明
Authorization 是 Bearer {dumateToken}
X-Dumate-Device-Id 是 格式为 {device-id-ver}|{os}.{raw-device-id},其中:
· device-id-version = 1
· os:darwin / windows / ios / android / harmony / xiaodu 等,其他平台标识以服务方发布为准
· raw-device-id:各端自行确定的设备标识,[a-zA-Z0-9_.-]{16,128}
Content-Type 是 application/json
X-Dumate-Account-Id 否 服务方云账号 ID
User-Agent 否 UA 中加上链路上各种版本信息,其中最开始的发起端加上:
· PC:DumateApp/{版本号}
· Mobile:DumateMobile/{版本号}
样例:[DumateApp/1.0.34.1 go/1.0.0 Chrome/1.23.4]
X-Dumate-Client-Source 否 来源方:dumate-web(dumate 网页端)、dumate-app(dumate 移动端)、partner-channel(合作渠道)
Refer 否 网页端调用时注明来源。样例:https://www.dumate.cn/app

请求体参数

字段 类型 必填 说明
parentID string 否 父会话 ID(ses_ 前缀)。传入时创建子会话
title string 否 会话标题。缺省自动生成(格式 New session - 2026-04-23 14:30:00,UTC+8)
permission PermissionRule[] 否 会话级权限规则集,覆盖默认权限

PermissionRule 结构

JSON
1{
2  "permission": "bash",
3  "pattern": "rm *",
4  "action": "ask"
5}
字段 类型 说明
permission string 权限类型,如 bash、read、mount_directory、*
pattern string 匹配模式,支持通配符,如 *、rm *、*.env
action string 动作:allow 允许 / deny 拒绝 / ask 询问用户

请求示例

Bash
1curl -X POST 'https://www.dumate.cn/dispatch/{route}/session' \
2  -H 'Authorization: Bearer {dumateToken}' \
3  -H 'X-Dumate-Device-Id: 1|web.{raw-device-id}' \
4  -H 'Content-Type: application/json' \
5  -d '{"title": "新任务"}'

响应示例(会话对象,字段结构见 3.6 会话对象数据结构)

JSON
1{
2  "id": "ses_{sessionID}",
3  "slug": "glowing-panda",
4  "version": "0.0.0-dumate_server-202605210956",
5  "projectID": "global",
6  "directory": "/home/work/dumate/{accountId}/workspace",
7  "is_subagent": false,
8  "title": "新任务",
9  "time": {
10    "created": 1779418858625,
11    "updated": 1779418858625
12  }
13}

3.2 发送消息 POST /session/:sessionID/prompt_async

向指定会话发送用户消息并触发搭子处理。采用异步非阻塞模式:服务端触发处理并立即返回 HTTP 204,搭子处理进度与结果通过 SSE 事件推送(见 3.3 接收消息)。

项目 内容
请求方式 POST
请求路径 /dispatch/{route}/session/{sessionID}/prompt_async
是否鉴权 是

请求 Header

Header 必填 说明
Authorization 是 Bearer {dumateToken}
X-Dumate-Device-Id 是 设备标识
X-Dumate-Request-Id 否 请求追踪 ID
X-Dumate-Location-Coarse 否 用户 IP 粗定位。值为 location 序列化为 UTF-8 JSON 后做 percent-encoding 的结果(至少含 province / city / district / town / street 中一个非空字段),放在 Header 而非 Body

请求体参数

参数 必填与否 说明
requestID (string) 否 请求追踪 ID。dumate_server 的 Body Schema 接受该字段,但 prompt_async 路由以 X-Dumate-Request-Id Header 为准
deviceId (string) 否 设备 ID。Body Schema 接受该字段,但 prompt_async 路由以 X-Dumate-Device-Id Header 为准
messageID (string) 否 用户消息 ID,格式通常以 msg_ 开头;不传时由服务端生成
sandboxId (string) 否 Sandbox ID。Body Schema 接受该字段,但 prompt_async 路由以 X-Sandbox-ID Header 为准
dtoken (string) 否 模型访问凭证。Body Schema 接受该字段,但 prompt_async 路由以 X-Dumate-Token Header 为准;云端模式下该 Header 必填
sandboxDomain (string) 否 Sandbox 域名。Body Schema 接受该字段,但 prompt_async 路由以 X-Sandbox-Domain Header 为准
accessToken (string) 否 Envd 访问凭证。Body Schema 接受该字段,但 prompt_async 路由以 X-Envd-Access-Token Header 为准
userAgent (string) 否 调用端信息。Body Schema 接受该字段,但 prompt_async 路由以 User-Agent Header 为准
triggerType (string) 否 请求触发方式。Body Schema 接受该字段,但 prompt_async 路由以 X-Dumate-Trigger-Type Header 为准;cron 表示定时任务
expConfig (object) 否 实验配置。Body Schema 接受该字段,但 prompt_async 路由以 X-Dumate-Exp-Config Header 中的 JSON 为准
expConfig.abExpIds (string[]) 否 AB 实验 ID 列表
expConfig.aiAssistant (object) 否 搭子实验配置
expConfig.aiAssistant.enabled (boolean) 否 是否启用搭子实验能力
model (object) 否 指定本轮使用的模型;不传时使用服务端默认模型
model.providerID (string) model 存在时必填 Provider ID,例如 default
model.modelID (string) model 存在时必填 Model ID,例如 default
agent (string) 否 指定处理本轮消息的 Agent
noReply (boolean) 否 是否不生成搭子回复
tools (Record<string, boolean>) 否 工具开关映射。该字段已废弃,工具与权限应通过 Session permission 配置
format (object) 否 输出格式配置
format.type (string) format 存在时必填 text 或 json_schema。使用 json_schema 时还需传 format.schema
system (string) 否 本轮自定义 System Prompt
variant (string) 否 消息变体标识
parts (array) 是 本轮消息内容列表,可包含文本、文件等 Part

说明:requestID、deviceId、dtoken、userAgent、triggerType、accessToken 等字段在 Body 中可接受,但本接口以对应 Header 传参为准。

Text Part

参数 必填与否 说明
parts[].id (string) 否 Part ID;不传时由服务端生成
parts[].visibility (string) 否 可选值:frontend、model、both。不传时按默认规则处理
parts[].type (string) 是 文本 Part 固定为 text
parts[].text (string) 是 用户输入的文本内容
parts[].synthetic (boolean) 否 是否为系统合成的文本。普通用户输入通常不传
parts[].ignored (boolean) 否 是否忽略该 Part。普通用户输入通常不传
parts[].time (object) 否 Part 的时间信息
parts[].time.start (number) time 存在时必填 开始时间戳,单位为毫秒
parts[].time.end (number) 否 结束时间戳,单位为毫秒
parts[].metadata (object) 否 自定义扩展元数据

File Part

文件二进制通过上传接口(见 5 文件)先上传,本条消息只传文件引用。上传文件后,不需要再次向本接口上传文件二进制,而是在 parts 中传入文件引用。

参数 必填与否 说明
parts[].id (string) 否 Part ID;不传时由服务端生成
parts[].visibility (string) 否 可选值:frontend、model、both
parts[].type (string) 是 文件 Part 固定为 file
parts[].mime (string) 否,建议传 文件 MIME 类型,例如 video/mp4、image/png;不传时服务端尝试根据路径推断
parts[].filename (string) 否;url 为 blob: 时必填 普通文件可表示文件名;线上云端上传链路中承载 CreatePreSessionFile.filePath,例如 /dumate/{userID}/workspace/uploads/{uploadID}/文件名
parts[].url (string) 是 文件引用。必须是带协议的 URL,不能填写 /dumate/... 裸路径
parts[].mediaType (string) 否 上游兼容字段,通常与 mime 相同;当前 dumate_server 的 FilePart Schema 未声明该字段,服务端以 mime 为准
parts[].preview (string) 否 线上请求携带的上传对象相对标识。当前 dumate_server 的文件路径归一化不读取该字段
parts[].source (object) 否 文件来源信息

请求示例(文本 + 文件)

Bash
1curl -X POST 'https://www.dumate.cn/dispatch/{route}/session/{sessionID}/prompt_async' \
2  -H 'Authorization: Bearer {dumateToken}' \
3  -H 'X-Dumate-Device-Id: 1|web.{raw-device-id}' \
4  -H 'Content-Type: application/json' \
5  --data-raw '{
6    "model": {"providerID": "default", "modelID": "default"},
7    "parts": [
8      {"type": "text", "text": "请帮我分析这张图"},
9      {"type": "file", "url": "file:///dumate/{userID}/workspace/uploads/{uploadID}/图片.png", "mime": "image/png"}
10    ]
11  }'

3.3 接收消息 GET /event

订阅当前会话运行环境的实时事件流(SSE,Content-Type: text/event-stream)。接入方在进入会话页后建立一次长连接,此后 UI 的所有状态更新(搭子文本、工具调用、任务进度、权限请求等)均由该事件流驱动。

项目 内容
请求方式 GET
请求路径 /dispatch/{route}/event
是否鉴权 是

请求 Header

Header 必填 说明
Authorization 是 Bearer {dumateToken}
X-Dumate-Device-Id 是 设备标识(格式见 3.1)
Content-Type 是 application/json
X-Dumate-Account-Id 否 服务方云账号 ID
User-Agent 否 UA 中加上链路上各种版本信息,其中最开始的发起端加上:
· PC:DumateApp/{版本号}
· Mobile:DumateMobile/{版本号}
样例:[DumateApp/1.0.34.1 go/1.0.0 Chrome/1.23.4]
X-Dumate-Client-Source 否 来源方:dumate-web(dumate 网页端)、dumate-app(dumate 移动端)、partner-channel(合作渠道)
Refer 建议 网页端调用时注明来源。样例:https://www.dumate.cn/app

请求示例

Bash
1curl 'https://www.dumate.cn/dispatch/{route}/event' \
2  -H 'Authorization: Bearer {dumateToken}' \
3  -H 'X-Dumate-Device-Id: 1|web.{raw-device-id}' \
4  -H 'Referer: https://www.dumate.cn/app/session/{sessionID}'

3.3.1 事件流协议

事件流采用 SSE 规范:每个事件由 event: 事件名与 data: 负载(JSON)组成,空行分隔。事件负载为 JSON,事件名区分事件类型。具体事件名与字段结构请以服务方提供的《SSE 事件说明》为准(接入时向服务方索取),本节给出事件类别的行为清单,供接入方规划 UI 与状态机:

事件类别 触发时机 推荐客户端动作
文本增量 搭子生成回复过程中,文本逐段产出 追加渲染到当前消息,保持 loading
推理过程 模型推理/思考过程产出 可选展示,收起/展开
工具调用更新 搭子调用工具(命令执行、文件读写、Skill 等)时 展示工具名、状态(进行中/完成/失败)
任务进度更新 搭子更新 Todo 任务列表时 刷新任务进度 UI(见 3.5)
权限请求出现 搭子需要用户授权(bash/read/write/location 等)时 弹权限框(见 4.5),等待用户回复
澄清问题出现 搭子需要补充信息时 弹澄清框(见 4.1)
消息完成 单条搭子消息产出完成 结束 loading,标记消息完成
会话空闲 整轮处理结束、无待办 结束本轮 loading,刷新会话/文件/任务状态

3.3.2 连接建立时机

  • 用户进入会话页即可建立连接(未发送消息也可空连接)。
  • 建议每会话一条连接;若实现为全局单连接,需按会话过滤事件(事件负载含 sessionID 标识,以《SSE 事件说明》字段为准)。
  • 连接鉴权失败(如 Token 过期)返回错误后,按 2.1 刷新 Token 重连。

3.3.3 断线重连与对账

SSE 连接可能因网络切换、网关空窗等原因断开,接入方需处理重连与状态对账:

  1. 自动重连:检测到连接断开后按退避策略重连(如 1s → 2s → 5s → 10s,封顶 30s,最多重试 N 次)。
  2. 权限对账:重连后调用 GET /permission(见 4.5),补齐断线期间可能遗漏的 pending 权限请求,避免权限弹窗漏显。
  3. 消息对账:重连后调用 DescribeSessionMessages(3.10)拉取最近消息,用于补齐断线期间未接收的增量;有权限请求时先处理权限。
  4. 任务对账:重连后调用 GET /session/:sessionID/todo(3.5)刷新任务进度,避免进度 UI 与真实状态不一致。
  5. 完成判定兜底:若长时间未收到“会话空闲”类事件但会话已无产出,可轮询 DescribeSessionStatus(3.9)确认会话是否仍 busy,作为完成判定的兜底手段。

注意事项:

  • 事件类型、数据结构与响应示例详见服务方提供的《SSE 事件说明》。
  • 同一账号的 /event、权限查询与回复请求需路由到同一服务实例(接入网关按账号做粘性路由)。
  • SSE 是事件推送通道,UI 的权威数据源仍以各查询接口(会话、消息、文件、任务)为准;重连后以查询接口对账补齐。

3.4 停止消息 POST /session/:sessionID/abort

强制中止当前正在进行的搭子任务(模型推理与工具调用循环)。

项目 内容
请求方式 POST
请求路径 /dispatch/{route}/session/{sessionID}/abort
是否鉴权 是

请求体:无。

请求示例

Bash
1curl -X POST 'https://www.dumate.cn/dispatch/{route}/session/{sessionID}/abort' \
2  -H 'Authorization: Bearer {dumateToken}' \
3  -H 'X-Dumate-Device-Id: 1|web.{raw-device-id}'

响应:HTTP 200,true 表示中止成功。

3.5 查询任务进度 GET /session/:sessionID/todo

获取搭子记录的任务列表,用于展示多步骤任务的进度。

项目 内容
请求方式 GET
请求路径 /dispatch/{route}/session/{sessionID}/todo
是否鉴权 是

响应参数(JSON 数组)

字段 类型 说明
id string 任务唯一 ID
content string 任务描述(如“实现功能X”)
status string pending / in_progress / completed
activeForm string 进行中时的展示文案(如“正在实现功能X”)

3.6 会话对象数据结构

创建会话、会话列表与详情接口均返回会话对象,字段如下:

字段 类型 必填 说明
id string 是 Session ID(ses_ 前缀)
slug string 是 URL 友好短标识
projectID string 是 所属项目 ID
workspaceID string 否 所属工作区 ID
directory string 是 会话工作目录(绝对路径)
parentID string 否 父 Session ID(Fork 场景)
is_subagent boolean 是 是否为子 Agent 创建的 Session
title string 是 会话标题
version string 是 创建时的服务端版本号
time.created number 是 创建时间戳(ms)
time.updated number 是 最后更新时间戳(ms)
time.compacting number 否 最后压缩时间戳(ms)
time.archived number 否 归档时间戳(ms)
summary.additions number 否 文件变更新增行数
summary.deletions number 否 文件变更删除行数
summary.files number 否 变更文件数
share.url string 否 分享链接(已分享时存在)
permission object 否 会话级权限规则集
revert.messageID string 否 回退到的消息 ID
revert.partID string 否 回退到的 Part ID
revert.snapshot string 否 快照标识
revert.diff string 否 变更 diff
isPinned boolean 是 是否置顶该会话
source string 否 会话来源

3.7 历史会话列表 DescribeSessions

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeSessions
是否鉴权 是

请求体参数

参数 类型 必填 说明
roots boolean 否 只返回根会话(无 parentID)
search string 否 按标题模糊搜索
limit int 否 返回最大条数
source string 否 来源过滤,可选 manual、scheduled

响应参数:result —— 会话对象数组(结构见 3.6)。

响应示例

JSON
1{
2  "result": [
3    {
4      "deviceId": "{deviceId}",
5      "directory": "/home/work/dumate/workspace",
6      "id": "ses_{sessionID}",
7      "title": "搜索狗狗图片",
8      "source": "manual",
9      "isPinned": false,
10      "time": {"created": 1782203832706, "updated": 1782203857358}
11    }
12  ]
13}

3.8 历史会话详情 DescribeSession

项目 内容
请求方式 POST(参数为 Query 参数,拼接在请求 URL 上)
请求路径 /openapi?Action=DescribeSession&sessionID={sessionID}
是否鉴权 是

请求参数

参数 位置 类型 必填 说明
sessionID Query string 是 会话 ID

响应参数:会话对象(结构见 3.6),另含 permission(会话级权限规则)与 requestId。

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "id": "ses_{sessionID}",
4  "title": "每日任务-123",
5  "source": "scheduled",
6  "permission": [
7    {"permission": "question", "pattern": "*", "action": "deny"},
8    {"permission": "scheduler_create_job", "pattern": "*", "action": "deny"}
9  ],
10  "readStatus": "unread",
11  "time": {"created": 1783558803151, "updated": 1783558806920}
12}

3.9 查询会话状态 DescribeSessionStatus

返回当前账号下所有非空闲(非 idle)会话的状态,空闲会话不在结果中。

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeSessionStatus
是否鉴权 是

请求体:无。

响应参数:JSON 对象,key 为会话 ID。

字段 类型 说明
{sessionID}.type string busy 或 retry
{sessionID}.attempt number 重试次数(仅 retry 状态)
{sessionID}.message string 重试原因(仅 retry 状态)
{sessionID}.next number 下次重试时间戳 ms(仅 retry 状态)

响应示例

JSON
1{
2  "ses_{sessionID}": {
3    "type": "busy"
4  }
5}

3.10 历史会话消息 DescribeSessionMessages

项目 内容
请求方式 POST(参数为 Query 参数)
请求路径 /openapi?Action=DescribeSessionMessages&sessionID={sessionID}&limit={limit}
是否鉴权 是

请求参数

参数 位置 类型 必填 说明
sessionID Query string 是 会话 ID
limit Query number 否 返回消息条数上限。从最新消息开始截取,翻转时间升序返回(如 limit=140 返回最近 140 条);不传返回全部。不支持 offset 分页

响应参数:result —— 消息数组。role=user 的消息字段见下方 User 消息,role=assistant 见 Assistant 消息;每条消息均含 parts 数组(见 Part 类型)。

User 消息字段

字段 类型 必填 说明
id string 是 消息 ID(msg_ 前缀)
sessionID string 是 所属 Session ID
role string 是 固定为 "user"
time.created number 是 创建时间戳(ms)
parts array 是 消息内容片段,见 Part 类型
format string 否 消息格式
summary string 否 摘要(压缩后)
agent string 否 指定 Agent 名称
model.providerID string 否 使用的 Provider ID
model.modelID string 否 使用的模型 ID
system string 否 自定义 system prompt
variant string 否 消息变体标识

Assistant 消息字段

字段 类型 必填 说明
id string 是 消息 ID(msg_ 前缀)
sessionID string 是 所属 Session ID
role string 是 固定为 "assistant"
time.created number 是 创建时间戳(ms)
time.completed number 否 完成时间戳(ms)
parts array 是 消息内容片段,见 Part 类型
error string 否 出错时的错误信息
parentID string 否 父消息 ID(Fork 场景)
modelID string 否 使用的模型 ID
providerID string 否 使用的 Provider ID
mode string 否 执行模式
agent string 否 使用的 Agent 名称
path.cwd string 否 执行时的工作目录
path.root string 否 执行时的项目根目录
summary string 否 摘要(压缩后)
cost number 否 本次消费费用
tokens.total number 否 总 token 数
tokens.input number 否 输入 token 数
tokens.output number 否 输出 token 数
tokens.reasoning number 否 推理 token 数
tokens.cache.read number 否 缓存命中 token 数
tokens.cache.write number 否 缓存写入 token 数
finish string 否 完成原因(stop / length / tool_calls 等)
variant string 否 消息变体标识

Part 类型

所有 Part 均含公共字段:id(prt_ 前缀)、messageID、sessionID、type,类型为 String。各 type 特有字段:

Type 说明 特有字段
text 文本内容 text: string
file 文件引用 url: string;可选 filename: string、mediaType: string
tool 工具调用 callID: string、tool: string(工具名)、state: object(见 ToolState)、metadata: object
reasoning 模型推理过程 text: string;可选 summary: string
step-start 推理步骤开始 无额外字段
step-finish 推理步骤结束 无额外字段
subtask 子任务调用 description: string、sessionID: string
agent Agent 调用 agent: string、description: string、sessionID: string
file-import 文件导入块 files: array(文件块列表)
file-export 文件导出块 files: array(文件块列表)
compaction 上下文压缩记录 summary: string
retry 重试记录 error: string、attempt: number
snapshot 文件快照 snapshot: string
patch 文件 diff patch: string

ToolState(以 type 字段区分状态)

pending(待执行):

字段 类型 说明
type string "pending"
input any 工具调用入参
raw string 原始输入字符串(可选)

running(执行中):

字段 类型 说明
type string "running"
input any 工具调用入参
title string UI 展示标题(可选)
metadata object 附加上下文
time.start number 开始时间戳(ms)

completed(已完成):

字段 类型 说明
type string "completed"
input any 工具调用入参
output any 工具调用输出
title string UI 展示标题(可选)
metadata object 附加上下文
time.start number 开始时间戳(ms)
time.end number 结束时间戳(ms)
time.compacted boolean 是否已被压缩(可选)
attachments string[] 附件列表(可选)

error(执行失败):

字段 类型 说明
type string "error"
input any 工具调用入参
error string 错误信息
metadata object 附加上下文
time.start number 开始时间戳(ms)
time.end number 结束时间戳(ms)

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "result": [
4    {
5      "info": {
6        "id": "msg_{messageID}",
7        "role": "assistant",
8        "sessionID": "ses_{sessionID}",
9        "finish": "stop",
10        "time": {"created": 1781672921612, "completed": 1781672923336}
11      },
12      "parts": [
13        {"id": "prt_{partId}", "type": "step-start"},
14        {"id": "prt_{partId}", "type": "text", "text": "已完成。", "time": {"start": 1781672923007, "end": 1781672923007}},
15        {"id": "prt_{partId}", "type": "step-finish"}
16      ]
17    }
18  ]
19}

3.11 首页推荐问 DescribeRecommendQueries

获取首页推荐问列表,用于在首页展示引导用户提问的推荐内容。

项目 内容
请求方式 POST(参数为 Query 参数)
请求路径 /openapi?Action=DescribeRecommendQueries&clientType={clientType}
是否鉴权 是

请求参数

参数 位置 类型 必填 说明
clientType Query string 是 mobile / desktop / web

响应参数:result —— 推荐问数组。

字段 类型 必填 说明
id int64 是 推荐问 ID
tag string 是 分类标签
query string 是 实际发送给对话服务的 Query
display string 是 当前 clientType 的展示文案
execScope string 否 可执行端,逗号分隔(如 desktop,web,mobile)
displayScope string 否 可展示端,逗号分隔
attachment object 否 推荐问附件(见 Attachment.Info)
skills array 是 关联 Skill(见 Resource.Info),无数据时返回 []
plugins array 是 关联 Plugin(见 Resource.Info),无数据时返回 []
icon string 否 分类标签图标的签名地址

Attachment.Info

字段 类型 必填 说明
bosPath string 是 签名下载地址
fileName string 是 文件名
fileType string 是 文件 MIME 类型
fileSize string 是 格式化文件大小(如 128.5KB)
cfsPath string 否 用户文件路径,可在发起会话时直接引用

Resource.Info(skills / plugins 元素)

字段 类型 必填 说明
type string 是 skill / plugin
displayName string 是 展示名称
name string 是 Skill 名称或 Plugin Code

注意事项(分屏规则):

  • 接口不返回分页字段,result 为扁平数组,客户端每 4 条切分一屏(第 1 屏 result[0:4],第 2 屏 result[4:8],依此类推;候选不足时最后一屏可少于 4 条)。
  • 同一屏不出现重复 id,同屏内优先不同 tag。
  • 服务端会做个性化编排,同一用户多次请求返回的内容和顺序可能变化,请按返回顺序展示。

4 对话交互

搭子在任务执行过程中可能向用户发起两类交互:澄清问答(信息不足时提问)与权限申请(需要访问本地资源或执行敏感操作时请求授权)。

4.1 澄清问答 DescribeConversationQuestions

获取当前所有待回答的澄清问题(搭子主动发起,通常 1-4 个问题)。

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeConversationQuestions
是否鉴权 是

请求体:无。

响应参数:result —— 问题请求数组。

字段 类型 必填 说明
id string 是 问题请求 ID(que_ 前缀),回复时使用
sessionID string 是 所属会话 ID
questions array 是 问题列表(1-4 个)
tool.messageID string 否 触发该问题的工具调用所在消息 ID
tool.callID string 否 触发该问题的工具调用 ID

questions 数组元素

字段 类型 必填 说明
question string 是 完整问题文本,以问号结尾
header string 是 短标签,最多 30 字符,用于 UI 展示
options array 是 选项列表(2-4 个),每项含 label: string(选项文字)与 description: string(选项说明)
custom boolean 否 是否允许用户自定义输入

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "result": [
4    {
5      "id": "que_{requestID}",
6      "sessionID": "ses_{sessionID}",
7      "questions": [
8        {
9          "question": "这份 PPT 是关于什么主题的?用途是什么?",
10          "header": "PPT 主题与用途",
11          "options": [
12            {"label": "工作汇报", "description": "面向团队或管理层的工作总结"},
13            {"label": "学术讲座", "description": "研究进展或学术内容分享"}
14          ]
15        }
16      ]
17    }
18  ]
19}

4.2 回复澄清问题 ReplyConversationQuestion

用户在澄清弹窗中回答后调用,把答案回传给搭子继续执行。

项目 内容
请求方式 POST
请求路径 /openapi?Action=ReplyConversationQuestion
是否鉴权 是

请求体参数

字段 类型 必填 说明
requestID string 是 问题请求 ID,来自 DescribeConversationQuestions 返回的 result[].id,前缀一般是 que_
answers string[][] 是 按 questions 顺序填写,每个元素是该题选中的 label 列表,支持多选;custom=true 时可直接传用户输入内容

请求示例

JSON
1{
2  "requestID": "que_{requestID}",
3  "answers": [
4    ["自动驾驶产品竞品分析"],
5    ["10-20页"]
6  ]
7}

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "result": true
4}

4.3 权限申请 DescribeConversationPermissions

获取当前所有待审批的权限请求(已处理的不在列表中),用于展示权限弹窗。

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeConversationPermissions
是否鉴权 是

请求体:无。

响应参数:result —— 权限请求数组(PermissionRequest)。

字段 类型 必填 说明
id string 是 权限请求 ID(per_ 前缀)
sessionID string 是 所属 Session ID
permission string 是 权限类型,如 bash、read、write
patterns string[] 是 匹配的操作模式,如 ["rm -rf dist"]
metadata object 是 附加上下文(如具体命令参数)
always string[] 是 已被标记为始终允许的 patterns
tool.messageID string 否 触发该权限的工具调用所在消息 ID
tool.callID string 否 触发该权限的工具调用 ID

4.4 回复权限申请 ReplyConversationPermission

用户在权限弹窗中选择允许或拒绝后调用,把审批结果回传给搭子,搭子收到后继续执行或中止。

项目 内容
请求方式 POST
请求路径 /openapi?Action=ReplyConversationPermission
是否鉴权 是

请求体参数

字段 位置 类型 必填 说明
requestID body string 是 权限请求 ID,来自 DescribeConversationPermissions 返回的 result[].id
reply body string 是 审批结果:once / always / reject
message body string 否 可选备注

请求示例

JSON
1{
2  "requestID": "per_{requestID}",
3  "reply": "once",
4  "message": "approve"
5}

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "result": true
4}

4.5 查询待处理权限(实时通道) GET /permission

获取当前会话运行环境中所有尚未回复的权限请求,用于权限弹窗展示,以及页面刷新、SSE 重连或 App 回到前台后的状态对账。只返回 pending 请求,不返回历史或已批准的规则。

项目 内容
请求方式 GET
请求路径 /dispatch/{route}/permission
是否鉴权 是

请求参数

字段 位置 类型 必填 说明
directory Query string 否 工作区目录(通常由接入层补齐或透传)

Console、Agent-Hub 与 qianfan-desk 的路径映射如下:

调用层 HTTP 路径
Console / Web GET /dispatch/clawguard/permission
Agent-Hub GET /v2/dumate/permission
qianfan-desk GET /permission

响应参数:PermissionRequest[],除 4.3 的字段外,还包含服务端生成的展示信息:

字段 类型 必填 说明
id string 是 权限请求 ID,以 per_ 开头;回复接口必须原样使用该值
sessionID string 是 所属会话 ID,以 ses_ 开头
permission string 是 权限类型,例如 location、bash、read、write
patterns string[] 是 本次申请覆盖的操作模式;location 通常为 ["*"]
metadata object 是 附加上下文
always string[] 是 允许持久批准的 pattern;空数组表示不支持持久批准
tool.messageID string 否 触发该权限请求的消息 ID
tool.callID string 否 触发该权限请求的 Tool Call ID
display object 否 服务端生成的展示信息
display.title string 是 弹窗标题
display.riskLevel string 是 风险等级:high、medium 或 low
display.riskLabel string 是 风险标签
display.description string 是 面向用户的权限说明
display.resolvedPaths string[] 是 解析后的相关路径;location 场景为空数组

响应示例(定位权限)

JSON
1[
2  {
3    "id": "per_{requestID}",
4    "sessionID": "ses_{sessionID}",
5    "permission": "location",
6    "patterns": ["*"],
7    "metadata": {},
8    "always": [],
9    "tool": {"messageID": "msg_{messageID}", "callID": "{callID}"},
10    "display": {
11      "title": "获取您的地理位置",
12      "riskLevel": "medium",
13      "riskLabel": "请确认",
14      "description": "请求使用您的当前位置以提供更精准的回答,同意后将仅在本次对话中使用。",
15      "resolvedPaths": []
16    }
17  }
18]

4.6 回复权限请求(实时通道) POST /permission/:requestID/reply

用户允许或拒绝权限请求后调用。服务端使用 requestID 找到对应 pending 请求,并唤醒正在等待结果的搭子流程。

Console、Agent-Hub 与 qianfan-desk 的路径映射如下:

调用层 HTTP 路径
Console / Web POST /dispatch/clawguard/permission/:requestID/reply
Agent-Hub POST /v2/dumate/permission/:requestID/reply
qianfan-desk POST /permission/:requestID/reply

Path 参数

字段 类型 必填 说明
requestID string 是 权限请求 ID,必须取自 GET /permission 返回项的 id 或 permission.asked.properties.id

请求体参数

字段 类型 必填 说明
reply string 是 once、always 或 reject
message string 否 拒绝时可携带用户补充说明
data any 否 权限相关业务数据;仅 askWithData 类型的权限请求会消费。location 权限通过该字段回传位置

location 的 data 结构

字段 类型 必填 说明
province string 否 省或直辖市
city string 否 城市
district string 否 区或县
town string 否 街道或镇
street string 否 门牌或街道地址

请求示例(定位授权)

JSON
1{
2  "reply": "once",
3  "data": {
4    "province": "北京市",
5    "city": "北京市",
6    "district": "海淀区",
7    "town": "上地街道",
8    "street": "信息路"
9  }
10}

请求示例(拒绝)

JSON
1{
2  "reply": "reject",
3  "message": "本次不允许获取位置"
4}

响应:HTTP 200 true。

注意事项(可靠性):

  • 权限等待没有内置超时。若回复在到达服务端前丢失,pending 会继续存在、搭子继续等待,客户端应在回复后重新调用 GET /permission 对账并重试。
  • 服务端已处理但响应丢失时,重新查询该 ID 会从列表消失。
  • 请求 ID 不存在时回复会静默返回(HTTP 仍为 200 true),因此 200 true 只表示调用成功,需结合 GET /permission 结果与会话状态确认处理成功。

5 文件

5.1 上传文件 CreatePreSessionFile

将会话输入框中的文件上传至服务端,供会话使用。具体传参字段和值的形状请以接口实际要求为准。

项目 内容
请求方式 POST
请求路径 /openapi?Action=CreatePreSessionFile
Content-Type multipart/form-data; boundary=xxx(boundary 部分一般由代码或浏览器自动生成)

请求参数

参数 类型 必填 说明
sessionId string 否 会话 ID;当前会话还未生成会话 ID 时传空字符串
file string 是 本地文件(file=@/path/to/your/file.ext),单个文件不超过 10MB

请求示例

Bash
1curl -X POST 'https://www.dumate.cn/openapi?Action=CreatePreSessionFile' \
2  -H 'Authorization: Bearer {apiKey}' \
3  -H 'X-Dumate-Token: {dumateToken}' \
4  -F 'sessionId=' \
5  -F 'file=@/path/to/your/file.ext'

响应参数

字段 类型 说明
filePath string 上传后的文件路径(形如 /dumate/{accountId}/workspace/uploads/{accountId}/{uploadId}.mp4),发起会话时作为文件 Part 的引用使用

响应示例

JSON
1{
2  "filePath": "/dumate/{accountId}/workspace/uploads/{uploadId}/example.mp4"
3}

5.2 获取预上传文件访问地址 DescribePreSessionFile

获取已上传文件的签名下载地址。

项目 内容
请求方式 POST(参数为 Query 参数)
请求路径 /openapi?Action=DescribePreSessionFile&path={path}(path 需 URL 编码)
是否鉴权 是

请求参数

参数 位置 类型 必填 说明
path Query string 是 CreatePreSessionFile 返回的 filePath。
作为 Query 参数传递时请对 path 做 URL 编码

响应参数

字段 类型 必填 说明
path string 是 归一化后路径(形如 /dumate/{accountId}/workspace/uploads/xxx.png)
fileName string 是 文件存储名
mimeType string 否 MIME 类型,无法根据扩展名判断时不返回
size int64 是 文件大小(字节)
downloadUrl string 是 签名下载地址
expireSeconds int 是 downloadUrl 有效期(秒)

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "path": "/dumate/{accountId}/workspace/uploads/{uploadId}.png",
4  "fileName": "{uploadId}.png",
5  "mimeType": "image/png",
6  "size": 656471,
7  "downloadUrl": "http://{bos-host}/{bucket}/{accountId}/workspace/uploads/{uploadId}.png?authorization={signature}",
8  "expireSeconds": 3600
9}

注意:仅支持通过 CreatePreSessionFile 上传的文件。

5.3 单个历史会话的文件产出物 DescribeSessionFiles

获取指定会话生成的文件产出物清单(报告、文档、图片等)。

项目 内容
请求方式 POST(参数为 Query 参数)
请求路径 /openapi?Action=DescribeSessionFiles&sessionID={sessionID}
是否鉴权 是

请求参数

参数 位置 类型 必填 说明
sessionID Query string 是 会话 ID

响应参数:result —— 文件视图数组

响应示例

JSON
1{
2  "result": [
3    {
4      "artifactID": "art_{artifactId}",
5      "downloadUrl": "https://{bos-host}/{bucket}/artifact/global/ses_{sessionID}/art_{artifactId}/报告.docx?authorization={signature}",
6      "errorCode": null,
7      "errorMessage": null,
8      "fileType": "document",
9      "filename": "报告.docx",
10      "mimeType": "xxx",
11      "path": "/home/work/dumate/{accountId}/workspace/ses_{sessionID}/报告.docx",
12      "pdfUrl": "{pdfUrl}",
13      "previewMode": "pdf",
14      "previewStatus": "ready",
15      "previewUrl": "https://{bos-host}/docs/convert/{convertId}.pdf?authorization={signature}",
16      "relativePath": "报告.docx",
17      "timeUpdated": 1784284822612,
18      "uploadStatus": "ready"
19    }
20  ]
21}

5.4 单个文件详情 DescribeSessionFile

项目 内容
请求方式 POST(参数为 Query 参数)
请求路径 /openapi?Action=DescribeSessionFile&sessionID={sessionID}&path={path}(path 需 URL 编码)
是否鉴权 是

请求参数

参数 位置 类型 必填 说明
sessionID Query string 是 会话 ID
path Query string 是 文件绝对路径(对齐会话文件清单的 path 字段)

响应参数:单个文件视图

响应示例

JSON
1{
2  "artifactID": "art_{artifactId}",
3  "downloadUrl": "https://{bos-host}/{bucket}/artifact/global/ses_{sessionID}/art_{artifactId}/报告.docx?authorization={signature}",
4  "errorCode": null,
5  "errorMessage": null,
6  "fileType": "document",
7  "filename": "报告.docx",
8  "mimeType": "xxx",
9  "path": "/home/work/dumate/{accountId}/workspace/ses_{sessionID}/报告.docx",
10  "pdfUrl": "{pdfUrl}",
11  "previewMode": "pdf",
12  "previewStatus": "ready",
13  "previewUrl": "https://{bos-host}/docs/convert/{convertId}.pdf?authorization={signature}",
14  "relativePath": "报告.docx",
15  "timeUpdated": 1784284822612,
16  "uploadStatus": "ready"
17}

5.5 文件预览与下载 FilePreviewView

字段 类型 必填 说明
filename string 是 文件名
path string 是 文件绝对路径
relativePath string 是 相对工作区路径
artifactID string 是 当前路径对应的最新 artifact ID
uploadStatus string 是 上传状态(见下表)
pdfPreviewStatus string 是 预览状态(见下表)
previewMode string 是 pdf / download / none
previewUrl string/null 是 前端推荐直接打开的统一地址
downloadUrl string/null 是 原始文件下载地址(仅 uploadStatus=ready 时保证可用)
pdfUrl string/null 是 PDF 专用预览地址(仅 pdfPreviewStatus=ready 时保证可用)
errorCode string/null 是 失败错误码
errorMessage string/null 是 失败错误信息
timeUpdated number 是 最后更新时间戳(ms)

5.5.1 文件状态字段

uploadStatus

值 说明
pending 文件已注册,尚未开始上传
uploading 文件上传中
ready 上传完成,downloadUrl 可用
failed 上传失败,结合 errorCode / errorMessage 处理

pdfPreviewStatus

值 说明
none 不走 PDF 预览链路
pending 已进入预览流程
converting PDF 转换中
ready 预览生成完成,pdfUrl 可用
failed 预览生成失败

5.5.2 预览相关字段

previewMode

值 说明
pdf 优先打开 PDF 预览
download 无 PDF 预览,直接消费原始下载地址
none 当前无可用预览入口

previewUrl 与 pdfUrl 的区别

这两个字段语义不同,必须区分:

字段 说明
pdfUrl PDF 专用预览地址;只有文档类文件转码成功后才会有值
previewUrl 前端推荐直接打开的统一地址;前端点击“预览/打开”时优先使用它

计算规则:

  • 当 previewMode = "pdf":previewUrl = pdfUrl
  • 当 previewMode = "download":previewUrl = downloadUrl
  • 当 previewMode = "none":previewUrl = null

注意事项:

  • pdfUrl 是 PDF 能力字段,previewUrl 是前端统一消费字段,语义不同,请勿混淆。
  • pdfPreviewStatus=ready 且 pdfUrl 非空时 previewMode=pdf;pdfPreviewStatus=none 且 downloadUrl 非空时 previewMode=download;failed/无可消费 URL 时 previewMode=none。

6 积分

6.1 获取积分详情 DescribePointsOverview

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribePointsOverview
是否鉴权 是

请求体:无。

响应参数

字段 类型 说明
remainingPoints float64 当前用户剩余积分
currentPackage string 当前会员身份,普通用户为空字符串;枚举 plan_pro、plan_max
packageExpireAt int 当前用户会员到期时间(UTC 秒数);普通用户或已过期用户为 0

响应示例

JSON
1{
2  "remainingPoints": 1000.0,
3  "currentPackage": "plan_pro",
4  "packageExpireAt": 1780416000
5}

6.2 发放每日登录积分 IssueLoginBonus

每日发放登录积分,幂等(一天仅发放一次)。

项目 内容
请求方式 POST
请求路径 /openapi?Action=IssueLoginBonus
是否鉴权 是

请求体:无。

响应参数

字段 类型 说明
result bool 是否发放成功

响应示例

JSON
1{
2  "result": true
3}

6.3 获取积分发放记录 DescribePointsCharge

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribePointsCharge
是否鉴权 是

请求体参数

参数 类型 必填 说明
startAt int 是 开始日期当天 0 点的 UTC Unix 秒数
endAt int 是 结束日期当天 24 点的 UTC Unix 秒数
page int 否 页码,不传默认 1
limit int 否 每页条数,不传默认 10
changeType string 否 发放类型,不传默认返回全部类型数据

changeType 枚举值

Go
1const (
2    ChangeTypeOrderPlanPro   string = "order_plan_pro"   // 订阅个人版 Pro
3    ChangeTypeOrderPlanMax   string = "order_plan_max"   // 订阅个人版 Max
4    ChangeTypeOrderPlanPoint string = "order_plan_point" // 订阅积分增量包
5    ChangeTypeOrderPlanTeam  string = "order_plan_team"  // 订阅企业 Team 版
6    ChangeTypeRedeemPlan     string = "redeem_plan"      // 会员兑换,使用会员兑换码进行兑换时使用
7    ChangeTypeFreeGrant      string = "free_grant"       // 免费赠送
8    ChangeTypePointClear     string = "point_clear"      // 积分清零
9    ChangeTypeInviteBonus    string = "invite_bonus"     // 邀请奖励
10    ChangeTypeNewbieTask     string = "newbie_task"      // 新手任务
11)

响应参数

字段 类型 说明
totalCount int 总记录数
list array 本页数据(积分流水,见下),每个元素结构见 PointRecord 结构体

响应示例

JSON
1{
2  "totalCount": 2,
3  "list": [
4    {
5      "packageId": "{packageId}",
6      "createdAt": 1780416000,
7      "changeType": "order_plan_point",
8      "pointsChange": "1000.00"
9    },
10    {
11      "packageId": "{packageId}",
12      "createdAt": 1780329600,
13      "changeType": "order_plan_pro",
14      "pointsChange": "10000.00"
15    }
16  ]
17}

积分流水(PointRecord)

字段 类型 说明
packageId string 资源包 ID
createdAt int 发生时间(UTC Unix 秒数)
changeType string 计费类型
pointsChange string 积分变动值(正/负),保留两位小数

6.4 获取积分消耗记录 DescribePointsUsage

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribePointsUsage
是否鉴权 是

请求体参数

参数 类型 必填 说明
startAt int 是 开始日期当天 0 点的 UTC Unix 秒数
endAt int 是 结束日期当天 24 点的 UTC Unix 秒数
page int 否 页码,默认 1
limit int 否 每页条数,默认 10

请求示例

JSON
1{
2  "startAt": 1780243200,
3  "endAt": 1780416000,
4  "page": 1,
5  "limit": 10
6}

响应参数

字段 类型 说明
totalCount int 总记录数
list array 本页数据(积分使用,见下)

积分使用(PointUsage)

字段 类型 说明
conversationId string 关联会话 ID
conversationTitle string 关联会话名称
createdAt int 发生时间(UTC Unix 秒数)
packageId string 消耗资源包 ID
pointsChange string 积分变动值(正/负),保留两位小数

响应示例

JSON
1{
2  "totalCount": 2,
3  "list": [
4    {
5      "conversationId": "{conversationId}",
6      "conversationTitle": "我的机器人Chat01",
7      "packageId": "{packageId}",
8      "createdAt": 1780416000,
9      "pointsChange": "-227.08"
10    },
11    {
12      "conversationId": "{conversationId}",
13      "conversationTitle": "我的机器人Chat02",
14      "packageId": "{packageId}",
15      "createdAt": 1780329600,
16      "pointsChange": "-1330.20"
17    }
18  ]
19}

6.5 计费与限流说明

6.5.1 计费机制

  • 计费主体:搭子对话按消息消耗积分。单条回复的消耗通过 DescribeSessionMessages 消息中的 cost 字段(见 3.10)查看,与 DescribePointsUsage 的 pointsChange(负值)相互印证。
  • 余额口径:DescribePointsOverview.remainingPoints 为当前可用积分;currentPackage 标识会员身份(plan_pro/plan_max),会员用户按会员权益计费。
  • 流水对账:DescribePointsCharge(发放)与 DescribePointsUsage(消耗)均为按日期的分页流水(UTC 秒),可据此实现积分账单。
  • 余额不足:余额不足以支付本次消耗时如何处理(按余额扣至 0 / 拒绝本次请求),以接口实际返回为准;建议接入方在 remainingPoints 低于阈值时提前引导用户充值/订阅。

6.5.2 限流与并发

接口存在请求频率与并发限制,超限时返回限流错误码(见 10.1,以实际 message 为准)。接入方应在客户端实现退避重试,并向用户提示“请求过于频繁”。

7 Skill 管理

Skill 是搭子可调用的能力单元(如地图查询、百科知识、数据分析等)。

7.1 初始化 Skill InitSkills

初始化/更新用户 Skill 沙箱文件。单个用户多次调用只会触发一次初始化,后续调用会对比用户云上沙箱中的 Skill 版本做自动更新(用户无感)。

项目 内容
请求方式 POST
请求路径 /openapi?Action=InitSkills
是否鉴权 是

请求体:无。

请求示例

Bash
1curl -X POST 'https://www.dumate.cn/openapi?Action=InitSkills' \
2  -H 'Authorization: Bearer {apiKey}' \
3  -H 'X-Dumate-Token: {dumateToken}'

响应参数

字段 类型 说明
success bool 是否初始化成功

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "success": true
4}

7.2 获取用户 Skill 列表 DescribeSkills

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeSkills
是否鉴权 是

请求体参数

参数 类型 必填 说明
nameFilter string 否 按名称过滤
enable string 否 启用状态过滤
sortBy string 否 排序字段,默认 name
appVersion string 否 应用版本,默认空字符串

请求示例

Bash
1curl -X POST 'https://www.dumate.cn/openapi?Action=DescribeSkills' \
2  -H 'Authorization: Bearer {apiKey}' \
3  -H 'X-Dumate-Token: {dumateToken}' \
4  -H 'Content-Type: application/json' \
5  --data '{"nameFilter": "demo"}'

响应参数:skillList —— Skill 元素数组。

Skill 元素字段

字段 类型 说明
name string Skill 唯一标识(code)
description string Skill 描述(英文)
scope string 作用域:project(用户级)/ global(全局)
source string 来源:official(官方)/ user(用户自定义)
version string 当前安装版本(云端广场版本)
labels array 标签列表(见 Label)
authorInfo object 作者信息(见 AuthorInfo)
displayName string Skill 中文显示名称
icon string Skill 图标 URL(可选)
remark string Skill 中文描述

Label

字段 类型 说明
labelCode string 标签代码
labelName string 标签名称
labelIcon string 标签图标(可选)

AuthorInfo

字段 类型 说明
authorId string 作者 ID(可选)
authorName string 作者名称(可选)
authorAvatar string 作者头像(可选)
fromThirdParty string 第三方来源平台标识(可选)

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "skillList": [
4    {
5      "authorInfo": {
6        "authorName": "百度千帆官方"
7      },
8      "description": "The Baidu Baike Component is a knowledge service tool designed to query authoritative encyclopedia explanations for various nouns. Its core function is given a specific \"noun\" (object, person, location, concept, event, etc.) provided by the user, it returns a standardized, detailed entry explanation sourced from Baidu Baike.",
9      "displayName": "百度百科",
10      "icon": "https://{cdn-host}/icons/{iconId}.png",
11      "labels": [
12        {
13          "labelCode": "dumate_skill_official",
14          "labelName": "官方"
15        },
16        {
17          "labelCode": "dumate_skill_noauth",
18          "labelName": "免鉴权"
19        },
20        {
21          "labelCode": "tool_square_industry_service",
22          "labelIcon": "https://{cdn-host}/icons/{iconId}.svg",
23          "labelName": "行业服务"
24        }
25      ],
26      "name": "baidu-baike-data",
27      "remark": "百度百科组件是一个知识服务工具,用于查询各类名词的权威百科解释。其核心功能是:给定用户提供的特定名词(事物、人物、地点、概念、事件等),从百度百科返回标准化、详细的词条说明。",
28      "scope": "global",
29      "source": "official",
30      "version": "1.1.3"
31    }
32  ]
33}

7.3 获取用户 Skill 详情 DescribeSkill

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeSkill
是否鉴权 是

请求参数

参数 类型 必填 说明
name string 是 Skill 名称

请求示例

Bash
1curl -X POST 'https://www.dumate.cn/openapi?Action=DescribeSkill' \
2  -H 'Authorization: Bearer {apiKey}' \
3  -H 'X-Dumate-Token: {dumateToken}' \
4  -H 'Content-Type: application/json' \
5  --data '{"name":"baidu-ai-map"}'

响应参数

result 数据结构(UserSkillDetailResponse):内嵌 SkillUserItem 全部字段,并附加 files、updatedAt。

字段名 类型 说明
name string Skill 唯一标识(code)
description string Skill 描述(英文)
scope string 作用域:project(用户级)/ global(全局)
source string 来源:official(官方)/ user(用户自定义)
version string 当前安装版本(云端广场版本)
labels array 标签列表,结构见 Label(可选)
authorInfo object 作者信息,结构见 AuthorInfo(可选)
displayName string Skill 中文显示名称
icon string Skill 图标 URL(可选)
remark string Skill 中文描述

响应示例

JSON
1{
2  "requestId": "{requestId}",
3  "authorInfo": {
4    "authorName": "百度地图"
5  },
6  "description": "百度地图 API 调用工具,用于获取结构化地图数据。支持:地点检索(POI搜索)、路线规划(驾车/步行/骑行/公交)、地理编码(地址转坐标)、逆地理编码(坐标转地址)。需要 BAIDU_MAP_AUTH_TOKEN 环境变量。",
7  "displayName": "百度地图",
8  "icon": "https://{cdn-host}/icons/{iconId}.svg",
9  "labels": [
10    {
11      "labelCode": "dumate_skill_official",
12      "labelName": "官方"
13    },
14    {
15      "labelCode": "tool_square_industry_service",
16      "labelIcon": "https://{cdn-host}/icons/{iconId}.svg",
17      "labelName": "行业服务"
18    }
19  ],
20  "name": "baidu-ai-map",
21  "remark": "百度地图 API 调用工具,用于获取结构化地图数据。支持:地点检索(POI搜索)、路线规划(驾车/步行/骑行/公交)、地理编码(地址转坐标)、逆地理编码(坐标转地址)。需要 BAIDU_MAP_AUTH_TOKEN 环境变量。适用场景:需要精确坐标、结构化路线数据、地址解析等 API 级能力。不适用:一般性路线查询、地点介绍、旅游攻略等搜索类需求。",
22  "scope": "global",
23  "source": "official",
24  "version": ""
25}

8 定时任务

8.1 任务列表 DescribeSessionJobs

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeSessionJobs
是否鉴权 是

请求体参数

参数 类型 必填 说明
workspaceId string 否 按工作区过滤
sort string 否 latestTriggeredAtDesc(按最近触发倒序);默认 created_at DESC
page int 否 页码,1-based,默认 1
size int 否 每页条数,默认 20,上限 100

响应参数:result —— Job 数组(注:返回的是数组而不是 {items, totalCount} 包裹层;满 size 视为可能还有下一页)。

Job 字段

字段 类型 说明
id string 任务 ID(job_ 前缀)
workspaceId string 所属工作区 ID
name string 任务名称
enabled boolean 是否启用
cronExpr string 调度表达式(5 段格式:分 时 日 月 周)
timezone string 时区
executor.message string 任务执行的指令消息
executor.model string 任务执行模型(实际以服务端返回为准)
concurrency string 并发策略:forbid / allow
retry.maxRetries int 最大重试次数
retry.maxDelayMs int 最大重试延迟(ms)
timeoutSecs int 超时时间(秒)
createdAt / updatedAt int 创建 / 更新时间戳(ms)
version int 版本号
accountId string 所属账号
agent string 执行 Agent 名称
bindDeviceId string 绑定设备 ID(本地调度模式)
deviceName string 设备名称(本地调度模式)
schedulerMode string 调度模式:cloud / local
taskType string 任务类型
createdVia string 创建方式:manual 等
source string 来源:desktop / cloud 等
syncStatus string 同步状态
runStartTimeMs int 最近开始运行时间(ms)
template int 是否为预置模板任务:1 模板任务 / 0 普通任务
state.nextRunAtMs int 下次运行时间(ms)
state.lastRunAtMs int 上次运行时间(ms)
state.lastStatus string 上次运行状态
state.consecutiveErrors int 连续错误次数
state.retryAfterMs int 重试等待时间(ms)
state.readStatus string 阅读状态

响应示例

JSON
1{
2  "result": [
3    {
4      "id": "job_{jobId}",
5      "workspaceId": "ws_{workspaceId}",
6      "name": "每日记忆总结",
7      "enabled": false,
8      "cronExpr": "0 9 * * *",
9      "timezone": "Local",
10      "executor": {"message": "总结记忆文件,生成结构化的每日总结报告"},
11      "concurrency": "forbid",
12      "retry": {"maxRetries": 0, "maxDelayMs": 3600000},
13      "timeoutSecs": 1800,
14      "createdAt": 1784272894199,
15      "updatedAt": 1784272894199,
16      "version": 1,
17      "accountId": "{accountId}",
18      "agent": "daily-summary",
19      "schedulerMode": "local",
20      "source": "desktop",
21      "taskType": "unknown",
22      "createdVia": "manual",
23      "syncStatus": "ok",
24      "template": 0,
25      "state": {"nextRunAtMs": 0, "lastRunAtMs": 0, "lastStatus": "", "consecutiveErrors": 0, "retryAfterMs": 0, "readStatus": "read"}
26    }
27  ]
28}

9 个性化配置

9.1 首页定制 DescribeHomepageConfig

下发定制 Logo、slogan 等首页配置,用于渠道/应用首页品牌化展示。

项目 内容
请求方式 POST
请求路径 /openapi?Action=DescribeHomepageConfig
是否鉴权 是

请求体参数

参数 类型 必填 说明
version string 是 客户端版本号
clientType string 否 desktop / mobile,默认 desktop

响应参数

字段 类型 说明
query String 首页预置 query 文案
logo Object 首页 Logo 配置(静态/动画图、slogan、尺寸)
prompt String 首页引导文案
startTime String 配置生效时间
expirationTime String 配置过期时间
ext Object 扩展配置

响应示例

JSON
1{
2  "expirationTime": "2026-07-26T18:00:00+08:00",
3  "ext": {"skill": []},
4  "logo": {
5    "width": 228,
6    "height": 74,
7    "icon": "https://{cdn-host}/homepage_config/{customId}/icon.png?md5hash={md5}&timestamp={ts}",
8    "slogan": "{定制slogan占位}",
9    "primary": {"duration": 3.276, "hold": 10, "image": "https://{cdn-host}/homepage_config/1.0.44/active.png?md5hash={md5}&timestamp={ts}"},
10    "hover": {"duration": 0.1, "image": "https://{cdn-host}/homepage_config/1.0.44/hover.png?md5hash={md5}&timestamp={ts}"}
11  },
12  "prompt": "首页引导文案",
13  "query": "[\"欢迎使用搭子\"]",
14  "requestId": "{requestId}",
15  "startTime": "2026-07-01T17:45:00+08:00"
16}

10 返回码与错误处理

10.1 错误码

接口异常时(HTTP 状态码仍为 200)统一返回 code + message 字段:

code 示例 message 说明
401 PermissionDenied 鉴权失败:API Key 或 Token 无效 / 过期
400 参数错误:FieldName 请求参数错误,message 指明出错字段
400 业务异常信息 业务规则校验失败,以 message 描述

通用处理建议:

  • 所有接口先校验 requestId 是否返回;异常时读取 code / message 定位问题。
  • 收到 401:检查沙盒/线上环境是否匹配、API Key 与 Token 是否有效,必要时刷新 Token 后重试。
  • 收到 400:按 message 提示修正参数(必填缺失、格式错误、枚举越界等)。

10.2 注意事项与 FAQ

主题 说明
Token 过期时间 DescribeToken 返回的 expired_at 为 UTC 格式,需转换为本地时间判断,提前刷新
Token 过期处理 收到 401 后按 2.1 标准流程刷新 Token 并重试一次
API Key 安全 Key 仅控制台展示一次,妥善保管勿入仓库;泄露后在控制台吊销重建
环境区分 沙盒与线上使用不同的 API Key(且 Token 与 Key 环境强绑定),请勿混用;切换按 1.7 清单
接入前置条件 未申请 API Key 前无法调用任何接口,见 1.2 申请步骤
Query 参数 标注“Query 参数”的接口(如会话详情、文件详情、推荐问、预上传文件地址)需将参数拼接在 URL 上,且 path 类参数需 URL 编码
分屏规则 推荐问接口不分页返回,客户端按每 4 条切分一屏
文件大小 CreatePreSessionFile 单个文件不超过 10MB
文件生命周期 上传文件保留时长由服务端策略决定,生产环境请勿长期依赖缓存文件
文件预览 previewUrl 是前端统一消费字段(点击打开优先用它);pdfUrl 仅为 PDF 能力字段;两者语义不同
权限回复对账 POST /permission/:requestID/reply 返回 200 true 只代表调用成功;需重新 GET /permission 确认 pending 已清除
SSE 粘性路由 同一账号的 /event、权限查询与回复请求需路由到同一服务实例(通常由网关按账号粘性处理)
SSE 断线处理 按 3.3.3 自动重连,重连后用权限/消息/任务三连对账补齐状态
消息完成判定 以 SSE“会话空闲”类事件为准,兜底轮询 DescribeSessionStatus(见 3.3.3 / 1.6 Step 4)
消息 limit 历史消息接口不支持 offset 分页,limit 仅为数量截断
定时任务返回结构 DescribeSessionJobs 返回裸 Job 数组(非分页包裹层),满 size 视为可能还有下一页