Skip to content

Client Data(客户端数据)

Client Data 给应用和插件提供一块独立的结构化数据存储。

如果这些数据不适合放进会话主数据模型,也不适合放进 Session State,这组接口就是它们的落点。

这组接口主要面向插件开发和平台集成。如果你只需要普通聊天能力,不需要优先接入。

什么时候需要看这页

  • 你要保存插件偏好设置。
  • 你要保存前端自己的同步状态或缓存。
  • 你要保存不属于聊天主数据模型、但又需要后端持久化的结构化数据。

一个简单例子

假设有一个插件叫 chat-annotator,它要保存侧边栏是否展开:

  1. 先创建一个数据域,例如 owner_type=pluginowner_id=chat-annotatordomain_name=preferences
  2. 在这个域里创建一个集合,例如 ui
  3. 在集合里写入一个条目,例如 item_key=sidebar,值为 { "collapsed": false }

这样,这个插件就有了一块独立、可治理、可授权的数据空间。

先理解几个词

这里的意思
Domain(数据域)顶层隔离单元,先按拥有者,再按域名区分
Collection(集合)数据域下面的分类容器
Item(条目)集合里的单条键值数据
Grant(授权)允许其他应用或插件访问这个数据域的权限记录
managed domain已被其他受治理功能占用的数据域,不能再直接走原始 /client-data 路径

数据层级

层级说明唯一定位
Domain数据域,顶层隔离单元account_id + owner_type + owner_id + domain_name
Collection域内集合domain_id + collection_name
Item集合内键值条目collection_id + item_key

此外还有两类管理资源:

  • Grant:授权记录,允许非拥有者的应用或插件访问某个域
  • Audit Log:治理动作审计记录,记录域的创建、删除、恢复、授权变更等操作

请求头

认证头遵循全局认证规则。

如果需要启用拥有者级别的隔离,应额外传入以下请求头:

Header说明
X-Client-Owner-Typeapplication / plugin拥有者类型
X-Client-Owner-Idstring拥有者标识,如 chat-annotator

说明:

  • 不传这两个头时,服务端按 account_id + domain_id 控制访问
  • 只传其中一个、或值不合法时,返回 400 client_data_caller_owner_invalid
  • 如果拥有者不是数据域的创建者,需要通过 Grant 授权才能访问
  • 官方 SDK 已支持为 domain-scoped clientData 资源显式传入 callerOwner

managed domain 说明

如果某个底层 domain 已被后端标记为 managed domain:

  • 普通 GET /client-data/domains 默认不会列出它
  • 所有带 :domainId 的 raw domain-scoped 路径都会在进入业务逻辑之前返回 403 client_data_managed_domain_raw_access_forbidden。这一限制同时覆盖读、写和管理操作,包括:
    • GET / PATCH / DELETE /client-data/domains/:domainId
    • POST /client-data/domains/:domainId/restore
    • GET / POST / PATCH / DELETE /client-data/domains/:domainId/collections(/...)
    • GET / PUT / POST / DELETE /client-data/domains/:domainId/items(/...)
    • GET / POST /client-data/domains/:domainId/import
    • GET /client-data/domains/:domainId/export
    • GET / POST / PATCH / DELETE /client-data/domains/:domainId/grants(/...)
    • GET /client-data/domains/:domainId/audit-logs
  • DELETE /client-data/owners/:ownerType/:ownerId/domains 在该 owner 下包含任何 managed domain 时,同样返回 403 client_data_managed_domain_raw_access_forbidden
  • 这类 domain 必须通过对应的受治理服务访问,而不是继续走 raw client-data 路径

Domain 对象

字段类型说明
idstring数据域 ID
owner_typestringapplication / plugin
owner_idstring拥有者标识
domain_namestring数据域名称
display_namestring | null展示名称
descriptionstring | null描述
statusstringactive / suspended / deleted
versioninteger元数据版本号,用于乐观锁
quota_max_entriesinteger域级最大条目数
quota_max_bytesinteger域级最大字节数
current_entry_countinteger当前条目数
current_byte_countinteger当前字节数
created_atinteger创建时间
updated_atinteger更新时间
deleted_atinteger | null删除时间

Collection 对象

字段类型说明
idstring集合 ID
domain_idstring所属数据域
collection_namestring集合名称
descriptionstring | null描述
default_expires_ttl_msinteger | null默认过期 TTL(毫秒)
max_item_size_bytesinteger | null单条数据大小上限
versioninteger元数据版本号
metadata_jsonany集合自定义元数据
item_countinteger当前条目数
byte_countinteger当前字节数
created_atinteger创建时间
updated_atinteger更新时间

Item 对象

字段类型说明
idstring条目 ID
domain_idstring所属数据域
collection_idstring所属集合
item_keystring条目键
value_jsonany条目值(任意 JSON)
byte_sizeinteger存储字节数
versioninteger条目版本号
expires_atinteger | null过期时间
created_atinteger创建时间
updated_atinteger更新时间

Grant 对象

字段类型说明
idstring授权记录 ID
domain_idstring所属数据域
grantee_owner_typestring被授权方类型:application / plugin
grantee_owner_idstring被授权方标识
can_readboolean读取权限
can_writeboolean写入权限
can_deleteboolean删除权限
can_listboolean列出权限
expires_atinteger | null授权过期时间
created_atinteger创建时间
updated_atinteger更新时间

创建数据域

http
POST /client-data/domains

请求体

字段类型必填说明
owner_typestringapplication / plugin
owner_idstring拥有者标识
domain_namestring数据域名称
display_namestring展示名称
descriptionstring描述

请求示例

json
{
  "owner_type": "application",
  "owner_id": "my-app",
  "domain_name": "preferences",
  "display_name": "Preferences",
  "description": "Client preferences"
}

响应 201

返回 { "data": Domain }

错误

状态码code说明
400validation_error请求体校验失败
409client_data_domain_name_conflict同 owner 下 domain_name 重复

列出数据域

http
GET /client-data/domains

查询参数

参数类型说明
owner_typestring按拥有者类型过滤
owner_idstring按拥有者标识过滤
statusstring按状态过滤:active / suspended / deleted
sort_bystringupdated_at(默认)/ created_at / domain_name
sort_orderstringasc / desc
limitinteger每页条数
offsetinteger偏移量

响应 200

普通列表默认不返回 managed domain。

json
{
  "data": [ ],
  "meta": {
    "total": 3,
    "limit": 50,
    "offset": 0,
    "has_more": false,
    "sort_by": "updated_at",
    "sort_order": "desc"
  }
}

获取数据域详情

http
GET /client-data/domains/:domainId

返回 Domain 对象,额外包含以下字段:

字段类型说明
quota_usageobject包含 entry_countbyte_count
restorable_untilinteger | null删除后可恢复的截止时间

错误

状态码code说明
404not_found数据域不存在
410client_data_domain_deleted数据域已删除

更新数据域元数据

http
PATCH /client-data/domains/:domainId

至少提供一个可修改字段。支持乐观锁。

请求体

字段类型必填说明
display_namestring展示名称
descriptionstring描述
if_versioninteger乐观锁:当前期望版本号

请求示例

json
{
  "display_name": "Preferences Updated",
  "if_version": 2
}

响应 200

返回 { "data": Domain }

错误

状态码code说明
400validation_error请求体为空或校验失败
404not_found数据域不存在
409client_data_version_conflict版本号不匹配
410client_data_domain_deleted数据域已删除

更新数据域配额

http
PATCH /client-data/domains/:domainId/quota

请求体

字段类型必填说明
quota_max_entriesinteger最大条目数
quota_max_bytesinteger最大字节数

请求示例

json
{
  "quota_max_entries": 20000,
  "quota_max_bytes": 20971520
}

响应 200

返回 { "data": Domain }

错误

状态码code说明
400validation_error校验失败
403forbidden权限不足
404not_found数据域不存在
409client_data_domain_quota_below_usage新配额低于当前使用量

删除数据域

http
DELETE /client-data/domains/:domainId

软删除。删除后在宽限期内可通过 restore 接口恢复。

响应 200

json
{
  "data": {
    "id": "domain_abc123",
    "deleted": true
  }
}

错误

状态码code说明
404not_found数据域不存在

恢复数据域

http
POST /client-data/domains/:domainId/restore

恢复已删除的数据域。仅在宽限期内有效。

响应 200

返回 { "data": Domain }

错误

状态码code说明
404not_found数据域不存在
409client_data_domain_restore_invalid_state数据域状态不允许恢复
409client_data_domain_restore_expired宽限期已过
409client_data_domain_restore_conflict恢复时 owner/name 冲突

按拥有者批量删除数据域

http
DELETE /client-data/owners/:ownerType/:ownerId/domains

路径参数

参数类型说明
ownerTypestringapplication / plugin
ownerIdstring拥有者标识

响应 200

返回被删除的数据域 ID 列表。

错误

状态码code说明
400validation_error路径参数不合法

导出数据域

http
GET /client-data/domains/:domainId/export

导出整个数据域的完整快照,包含域信息、所有集合及其条目。

这组导出 / 导入接口的定位是:

  • 备份
  • 迁移
  • merge 工具输入输出

它不是 turn 级、floor 级的精确保真 snapshot restore 语义,也不用于替代受治理状态层的历史恢复。

响应 200

json
{
  "data": {
    "domain": {
      "id": "domain_abc123",
      "owner_type": "application",
      "owner_id": "my-app",
      "domain_name": "preferences"
    },
    "collections": [
      {
        "collection_name": "settings",
        "items": [
          {
            "item_key": "theme.dark",
            "value_json": true,
            "version": 1
          }
        ]
      }
    ],
    "exported_at": 1735689600000
  }
}

错误

状态码code说明
404not_found数据域不存在
410client_data_domain_deleted数据域已删除

导入为新数据域

http
POST /client-data/domains/import

以导出格式创建一个新的数据域。

这组导入接口适合:

  • 备份导回
  • 环境迁移
  • merge 补齐

不适合把它当作历史楼层快照、分支状态回滚或 turn 级精确恢复接口。

请求体

字段类型必填说明
conflict_policystring冲突策略:fail / overwrite / skip
payloadobject导出格式的完整快照

请求示例

json
{
  "conflict_policy": "fail",
  "payload": {
    "domain": {
      "owner_type": "application",
      "owner_id": "my-app",
      "domain_name": "preferences"
    },
    "collections": []
  }
}

响应 201

返回创建的域、集合列表和导入统计摘要。

错误

状态码code说明
400validation_errorpayload 校验失败
400client_data_import_item_limit_exceeded导入条目数超过上限
400client_data_import_payload_too_largepayload 过大
409client_data_import_conflictfail 策略下检测到冲突

导入到现有数据域

http
POST /client-data/domains/:domainId/import

将导出数据合并到一个已存在的数据域。冲突策略决定键名重复时的处理方式。

请求体

与「导入为新数据域」相同。

错误

状态码code说明
400validation_error / client_data_import_item_limit_exceeded / client_data_import_payload_too_large校验或大小超限
404not_found目标数据域不存在
409client_data_import_domain_mismatchpayload 中的域信息与目标域不一致
409client_data_import_conflictfail 策略下检测到冲突
410client_data_domain_deleted目标数据域已删除

创建集合

http
POST /client-data/domains/:domainId/collections

请求体

字段类型必填说明
collection_namestring集合名称
descriptionstring描述
default_expires_ttl_msinteger默认过期 TTL(毫秒)
max_item_size_bytesinteger单条数据大小上限
metadata_jsonany集合自定义元数据

响应 201

返回 { "data": Collection }

错误

状态码code说明
400validation_error校验失败
404not_found数据域不存在
409client_data_collection_name_conflict同域内 collection_name 重复

列出集合

http
GET /client-data/domains/:domainId/collections

响应 200

返回 { "data": Collection[] }

错误

状态码code说明
404not_found数据域不存在
410client_data_domain_deleted数据域已删除

获取集合详情

http
GET /client-data/domains/:domainId/collections/:collectionId

响应 200

返回 { "data": Collection }

错误

状态码code说明
404not_found数据域或集合不存在
410client_data_domain_deleted数据域已删除

更新集合

http
PATCH /client-data/domains/:domainId/collections/:collectionId

至少提供一个可修改字段。支持乐观锁。

请求体

字段类型必填说明
descriptionstring描述
default_expires_ttl_msinteger默认过期 TTL
max_item_size_bytesinteger单条大小上限
metadata_jsonany集合自定义元数据
if_versioninteger乐观锁:当前期望版本号

响应 200

返回 { "data": Collection }

错误

状态码code说明
400validation_error请求体为空或校验失败
404not_found数据域或集合不存在
409client_data_version_conflict版本号不匹配
410client_data_domain_deleted数据域已删除

删除集合

http
DELETE /client-data/domains/:domainId/collections/:collectionId

删除集合及其下所有条目。

响应 200

json
{
  "data": {
    "id": "coll_abc123",
    "deleted": true
  }
}

错误

状态码code说明
404not_found数据域或集合不存在

列出条目

http
GET /client-data/domains/:domainId/items

查询参数

参数类型说明
collection_idstring按集合过滤
item_key_prefixstring按键名前缀过滤
updated_afterinteger更新时间下限
updated_beforeinteger更新时间上限
expires_afterinteger过期时间下限
expires_beforeinteger过期时间上限
expiredbooleantrue 只返回已过期,false 只返回未过期
sort_bystringupdated_at(默认)/ created_at / item_key
sort_orderstringasc / desc
limitinteger每页条数
offsetinteger偏移量

响应 200

返回 { "data": Item[], "meta": ListMeta }

错误

状态码code说明
400validation_error查询参数不合法
403client_data_domain_forbidden拥有者没有对应权限
404not_found数据域不存在
410client_data_domain_deleted数据域已删除

按键名直接读取条目

http
GET /client-data/domains/:domainId/items/by-key?collection_name=settings&item_key=theme.dark

通过集合名称和键名直接定位条目,不需要先查 collection_id

查询参数

参数类型必填说明
collection_namestring集合名称
item_keystring条目键名

响应 200

返回 { "data": Item }

错误

状态码code说明
400validation_error参数缺失或不合法
403client_data_domain_forbidden拥有者没有对应权限
404not_found数据域、集合或条目不存在
410client_data_domain_deleted数据域已删除

获取条目详情

http
GET /client-data/domains/:domainId/items/:itemId

响应 200

返回 { "data": Item }

错误

状态码code说明
403client_data_domain_forbidden拥有者没有对应权限
404not_found数据域或条目不存在
410client_data_domain_deleted数据域已删除

单条 Upsert

http
PUT /client-data/domains/:domainId/items

如果相同 collection_name + item_key 的条目已存在则更新,否则创建。集合不存在时自动创建。

请求体

字段类型必填说明
collection_namestring集合名称
item_keystring条目键
value_jsonany条目值(任意 JSON)
expires_atinteger过期时间
if_versioninteger乐观锁:当前期望版本号

响应 200

json
{
  "data": {
    "action": "created",
    "collection": { },
    "item": { }
  }
}

actioncreatedupdated

错误

状态码code说明
400validation_error校验失败
403client_data_domain_forbidden拥有者没有对应权限
404not_found数据域不存在
409client_data_version_conflict版本号不匹配
410client_data_domain_deleted数据域已删除

批量 Upsert

http
PUT /client-data/domains/:domainId/items/batch

请求体

字段类型必填说明
itemsarrayUpsert 条目数组,每个元素结构同单条 upsert 的请求体

响应 200

json
{
  "data": {
    "results": [
      { "action": "created", "collection": { }, "item": { } },
      { "action": "updated", "collection": { }, "item": { } }
    ]
  }
}

错误

状态码code说明
400validation_error校验失败
403client_data_domain_forbidden拥有者没有对应权限
404not_found数据域不存在
409client_data_version_conflict某条数据版本号不匹配
410client_data_domain_deleted数据域已删除

删除单条

http
DELETE /client-data/domains/:domainId/items/:itemId

响应 200

json
{
  "data": {
    "id": "item_abc123",
    "deleted": true
  }
}

错误

状态码code说明
403client_data_domain_forbidden拥有者没有对应权限
404not_found数据域或条目不存在

批量删除

http
POST /client-data/domains/:domainId/items/delete-batch

按条目 ID 列表或集合 ID 删除,两者至少提供一个。

请求体

字段类型必填说明
item_idsstring[]条件必填要删除的条目 ID 列表
collection_idstring条件必填要清空的集合 ID

响应 200

返回被删除的条目列表,每条包含 idcollection_iditem_key

错误

状态码code说明
400validation_error两个字段都没有提供,或校验失败
403client_data_domain_forbidden拥有者没有对应权限
404not_found数据域不存在

列出授权

http
GET /client-data/domains/:domainId/grants

仅数据域拥有者可操作。

响应 200

返回 { "data": Grant[] }

错误

状态码code说明
403client_data_domain_grant_manage_forbidden非拥有者不能管理授权
404not_found数据域不存在

创建授权

http
POST /client-data/domains/:domainId/grants

仅数据域拥有者可操作。

请求体

字段类型必填说明
grantee_owner_typestring被授权方类型:application / plugin
grantee_owner_idstring被授权方标识
can_readboolean读取权限,默认 false
can_writeboolean写入权限,默认 false
can_deleteboolean删除权限,默认 false
can_listboolean列出权限,默认 false
expires_atinteger授权过期时间

请求示例

json
{
  "grantee_owner_type": "plugin",
  "grantee_owner_id": "chat-annotator",
  "can_read": true,
  "can_write": false,
  "can_delete": false,
  "can_list": true,
  "expires_at": null
}

响应 201

返回 { "data": Grant }

错误

状态码code说明
400validation_error校验失败
403client_data_domain_grant_manage_forbidden非拥有者不能管理授权
404not_found数据域不存在
409client_data_domain_grant_conflict同一被授权方已有授权记录

更新授权

http
PATCH /client-data/domains/:domainId/grants/:grantId

仅数据域拥有者可操作。至少提供一个可修改字段。

请求体

字段类型必填说明
can_readboolean读取权限
can_writeboolean写入权限
can_deleteboolean删除权限
can_listboolean列出权限
expires_atinteger | null授权过期时间

响应 200

返回 { "data": Grant }

错误

状态码code说明
400validation_error请求体为空或校验失败
403client_data_domain_grant_manage_forbidden非拥有者不能管理授权
404not_found数据域或授权记录不存在

删除授权

http
DELETE /client-data/domains/:domainId/grants/:grantId

仅数据域拥有者可操作。

响应 200

json
{
  "data": {
    "id": "grant_abc123",
    "deleted": true
  }
}

错误

状态码code说明
403client_data_domain_grant_manage_forbidden非拥有者不能管理授权
404not_found数据域或授权记录不存在

列出审计日志

http
GET /client-data/domains/:domainId/audit-logs

仅数据域拥有者可查看。

查询参数

参数类型说明
actor_typestring按操作者类型过滤
actionstring按动作过滤
sort_bystringcreated_at(默认)
sort_orderstringasc / desc
limitinteger每页条数
offsetinteger偏移量

响应 200

返回 { "data": AuditLog[], "meta": ListMeta }

错误

状态码code说明
403client_data_domain_grant_manage_forbidden非拥有者不能查看审计日志
404not_found数据域不存在

错误码汇总

HTTPerror.code说明
400client_data_caller_owner_invalid拥有者请求头不合法
400client_data_import_item_limit_exceeded导入条目数超过上限
400client_data_import_payload_too_large导入数据过大
403client_data_managed_domain_raw_access_forbiddenmanaged domain 不能走 raw /client-data 路径
403client_data_domain_forbidden拥有者没有对应权限
403client_data_domain_grant_manage_forbidden非拥有者不能管理授权或审计
404not_found资源不存在
409client_data_domain_name_conflict同 owner 下 domain 名冲突
409client_data_collection_name_conflict同域内 collection 名冲突
409client_data_domain_grant_conflict同一被授权方已有 grant
409client_data_version_conflict元数据或条目乐观锁冲突
409client_data_domain_quota_below_usage新配额低于当前使用量
409client_data_domain_restore_invalid_state数据域状态不允许恢复
409client_data_domain_restore_expired恢复宽限期已过
409client_data_domain_restore_conflict恢复时 owner/name 冲突
409client_data_import_domain_mismatch导入目标与数据不一致
409client_data_import_conflictfail 策略下检测到冲突
410client_data_domain_deleted数据域已删除