Files
story/openapi/openapi.yaml
T

6900 lines
349 KiB
YAML
Raw Normal View History

2026-08-26 06:41:07 +08:00
openapi: 3.1.0
info:
title: 数据采集终端—云端系统 API
version: 0.73.0
2026-08-26 23:30:59 +08:00
description: 工程框架、SaaS核心业务、设备v2能力协商与智能体启动状态查询、首次通话就绪与最低固件门禁、背景资料准备失败闭环、活动通话授权撤回安全停止、语音内容闭环、终端终稿补传、批量设备遥测、录音上传队列、隐私对账、固件、双轨录音、状态事件、具体资源分享、受控运营配置、Agent组合组件引用、质量证据门禁、运营自定义版本族投放、新通话运行时冻结与供应商启动传递、带并发版本校验的配置投放暂停恢复、带严重度和验收证据门禁的联调问题闭环、含阻断告警定位、当前主机健康及生产部署标记、实际应用环境、身份服务模式、异地备份、外部告警与模拟服务强制条件的发布候选技术验收快照、绑定候选版本与构建摘要并按业务时区生成的可审计试点日/周运行证据、可审计且不生成正式告警的接收器联通测试、外部依赖预检台账、证书到期清单,以及带价格版本冻结、供应商用量去重和硬额度控制的费用治理接口。
2026-08-26 06:41:07 +08:00
servers:
- url: http://localhost:58080
description: 本地开发
paths:
2026-08-29 21:56:51 +08:00
/internal/v1/tools/memory-search:
post:
operationId: searchInCallMemory
tags: [internal-tools]
security: [{ memoryToolBearer: [] }]
description: 仅供已绑定到当前s2s_hybrid通话的语音智能体调用;租户、长者、任务和有效期来自服务端签名令牌,请求正文不能指定这些边界。
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/MemoryToolSearchRequest' } } }
responses:
'200': { description: 受控长度的已确认记忆;Embedding临时不可用时返回degraded=true和空列表, content: { application/json: { schema: { $ref: '#/components/schemas/MemoryToolSearchResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'409': { $ref: '#/components/responses/ConflictError' }
'429': { description: 单通话记忆工具调用过于频繁 }
'503': { description: 记忆检索依赖暂时不可用, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/api/v1/ops/content-quality:
get:
operationId: getOpsContentQuality
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- { name: model_ref, in: query, required: false, schema: { type: string, maxLength: 200 } }
- { name: prompt_version, in: query, required: false, schema: { type: string, maxLength: 80 } }
responses:
'200': { description: 按生成模型和提示词版本聚合的候选确认、修改、拒绝和质量问题类型, content: { application/json: { schema: { $ref: '#/components/schemas/ContentQualityListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/content-models:
get:
operationId: listContentModels
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 当前账号空间可用的总结模型;不返回密钥明文, content: { application/json: { schema: { $ref: '#/components/schemas/ContentModelListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createContentModel
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CreateContentModelRequest' } } } }
responses:
'201': { description: 模型配置和加密凭据已保存, headers: { ETag: { $ref: '#/components/headers/StrongETag' } }, content: { application/json: { schema: { $ref: '#/components/schemas/ContentModelResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/content-models/{id}/test:
post:
operationId: testContentModel
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 使用无家庭数据的固定文本完成连通性测试, headers: { ETag: { $ref: '#/components/headers/StrongETag' } }, content: { application/json: { schema: { $ref: '#/components/schemas/ContentModelResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/content-models/{id}/activate:
post:
operationId: activateContentModel
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IfMatchHeader' }]
responses:
'200': { description: 已通过测试的模型成为该账号空间唯一活动总结模型, headers: { ETag: { $ref: '#/components/headers/StrongETag' } }, content: { application/json: { schema: { $ref: '#/components/schemas/ContentModelResponse' } } } }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
/api/v1/content-models/{id}:
delete:
operationId: revokeContentModel
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IfMatchHeader' }]
responses:
'200': { description: 未激活配置已撤销且密钥材料已清除, content: { application/json: { schema: { $ref: '#/components/schemas/ContentModelResponse' } } } }
'409': { $ref: '#/components/responses/ConflictError' }
2026-08-26 06:41:07 +08:00
/api/v1/ops/config-versions:
get:
operationId: listOpsConfigVersions
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- { name: config_key, in: query, required: false, schema: { type: string, pattern: '^[a-z][a-z0-9_.-]{2,99}$' } }
responses:
'200': { description: 当前运营账号可查看的配置版本历史, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigVersionListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsConfigVersion
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateOpsConfigVersionRequest' } } }
responses:
'201': { description: 不可变配置草稿版本已创建, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigVersionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 幂等键正文冲突 }
/api/v1/ops/config-versions/{id}/submit:
patch:
operationId: submitOpsConfigVersion
tags: [operations]
description: 执行结构、必填字段、密钥引用和敏感键校验,通过后进入待审批状态。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IfMatchHeader'
responses:
'200': { description: 配置已提交审批, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigVersionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/config-versions/{id}/publish:
patch:
operationId: publishOpsConfigVersion
tags: [operations]
description: 由审批角色发布他人创建且离线评测通过的待审批版本;按租户、试验对象或设备组激活灰度范围,同一范围原版本自动结束。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IfMatchHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigTransitionRequest' } } }
responses:
'200': { description: 配置已审批并发布, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigVersionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 状态冲突或创建人尝试审批自己的变更 }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/config-versions/{id}/rollback:
post:
operationId: rollbackOpsConfigVersion
tags: [operations]
description: 以指定历史版本内容创建新的已发布版本;不修改历史版本,幂等重放返回同一新版本。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigTransitionRequest' } } }
responses:
'201': { description: 回滚产生的新发布版本, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigVersionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/config-versions/{id}/evaluations:
get:
operationId: listOpsConfigEvaluations
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
responses:
'200': { description: 指定配置版本的离线评测证据, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigEvaluationListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsConfigEvaluation
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateOpsConfigEvaluationRequest' } } }
responses:
'201': { description: 离线评测证据已登记, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigEvaluationResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/resource-references:
get:
operationId: listOpsResourceReferences
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 已登记的受控资源引用, content: { application/json: { schema: { $ref: '#/components/schemas/OpsResourceReferenceListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsResourceReference
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateOpsResourceReferenceRequest' } } }
responses:
'201': { description: 只含引用标识的资源记录已创建, content: { application/json: { schema: { $ref: '#/components/schemas/OpsResourceReferenceResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/resource-references/{id}/revoke:
patch:
operationId: revokeOpsResourceReference
tags: [operations]
description: 撤销资源引用后,后续依赖该引用的配置不能发布;已冻结的历史会话不被改写。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IfMatchHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/OpsReasonRequest' } } }
responses:
'200': { description: 资源引用已撤销, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/OpsResourceReferenceResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/integration-issues:
get:
operationId: listOpsIntegrationIssues
tags: [operations]
description: 查询当前客户组织最近100条联调问题和全量发布阻断汇总,可按闭环状态筛选;记录仅包含诊断引用,不包含字幕或录音正文。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- { name: status, in: query, required: false, schema: { $ref: '#/components/schemas/IntegrationIssueStatus' } }
responses:
'200': { description: 联调问题清单, content: { application/json: { schema: { $ref: '#/components/schemas/IntegrationIssueListResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsIntegrationIssue
tags: [operations]
description: 由运营操作角色登记带严重级别的联调问题;设备与通话编号若同时提供必须属于同一关联链。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CreateIntegrationIssueRequest' } } } }
responses:
'200': { description: 幂等重放原联调问题, headers: { ETag: { $ref: '#/components/headers/StrongETag' } }, content: { application/json: { schema: { $ref: '#/components/schemas/IntegrationIssueResponse' } } } }
'201': { description: 联调问题已登记, headers: { ETag: { $ref: '#/components/headers/StrongETag' } }, content: { application/json: { schema: { $ref: '#/components/schemas/IntegrationIssueResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/integration-issues/{id}:
patch:
operationId: updateOpsIntegrationIssue
tags: [operations]
description: 使用强ETag更新严重级别、责任方和闭环证据;已解决必须有解决结果、根因与修复版本,已验证或已关闭还必须有回归结论与脱敏回归证据。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IfMatchHeader'
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/UpdateIntegrationIssueRequest' } } } }
responses:
'200': { description: 联调问题已更新, headers: { ETag: { $ref: '#/components/headers/StrongETag' } }, content: { application/json: { schema: { $ref: '#/components/schemas/IntegrationIssueResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/diagnostics/search:
get:
operationId: searchOpsDiagnostics
tags: [operations]
description: 按脱敏设备编号、通话编号、房间编号、供应商任务编号或请求关联编号查询联调状态;不返回短期凭证、字幕或录音。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- name: field
in: query
required: true
schema: { type: string, enum: [device_id, conversation_id, room_id, provider_task_ref, request_id] }
- name: value
in: query
required: true
schema: { type: string, minLength: 3, maxLength: 200 }
responses:
'200': { description: 联调诊断结果, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticSearchResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/diagnostics/external-dependencies:
get:
operationId: listOpsExternalDependencies
tags: [operations]
description: 查询API和Worker最近一次OIDC、方舟及RTC低成本探针结果。只返回归一化错误码、时间和连续失败次数,不返回端点、凭据或原始错误正文。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 平台外部依赖预检状态, content: { application/json: { schema: { $ref: '#/components/schemas/OpsExternalDependencyListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
2026-08-26 21:15:03 +08:00
/api/v1/ops/diagnostics/platform-health:
get:
operationId: getOpsPlatformHealth
tags: [operations]
description: 查询云端主机最近一次签名健康快照;仅返回脱敏检查名、状态和短值,不返回密钥、证书正文或业务数据。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 云端主机最新健康快照, content: { application/json: { schema: { $ref: '#/components/schemas/PlatformHealthSnapshotResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
2026-08-26 06:41:07 +08:00
/api/v1/ops/diagnostics/jobs:
get:
operationId: listOpsDiagnosticJobs
tags: [operations]
description: 查询当前客户组织的死信任务摘要,不返回任务正文或业务内容。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 死信任务列表, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticJobListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/diagnostics/jobs/{id}/retry:
post:
operationId: retryOpsDiagnosticJob
tags: [operations]
description: 由有权限运营人员把指定死信任务受控重置为待执行,保留人工重试次数、操作人和审计。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticReasonRequest' } } } }
responses:
'200': { description: 任务已受控重试, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticActionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/diagnostics/bundles:
post:
operationId: exportOpsDiagnosticBundle
tags: [operations]
description: 按精确检索条件生成可下载的脱敏JSON诊断包,并记录导出原因和审计。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticBundleRequest' } } } }
responses:
'200': { description: 诊断包幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticBundleResponse' } } } }
'201': { description: 脱敏诊断包已生成, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticBundleResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/diagnostics/acceptance-snapshots:
post:
operationId: exportOpsAcceptanceSnapshot
tags: [operations]
description: 在单个数据库事务中冻结候选构建、迁移、必需外部探针、高严重度联调问题、任务积压和严重告警的脱敏技术预检状态。结果可归档,但不替代真实设备、真实供应商、灰度观察或发布审批。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsAcceptanceSnapshotRequest' } } } }
responses:
'200': { description: 验收快照幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/OpsAcceptanceSnapshotResponse' } } } }
'201': { description: 脱敏技术验收快照已生成, content: { application/json: { schema: { $ref: '#/components/schemas/OpsAcceptanceSnapshotResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/diagnostics/pilot-daily-snapshots:
post:
operationId: exportOpsPilotDailySnapshot
tags: [operations]
description: 绑定候选版本与不可变构建摘要,按指定IANA时区的自然日聚合设备、通话、供应商、上传、告警和费用状态,生成可下载且有审计记录的脱敏试点日报。活动统计采用自然日窗口,积压和在线状态采用生成时刻快照。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsPilotDailySnapshotRequest' } } } }
responses:
'200': { description: 试点日报幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/OpsPilotDailySnapshotResponse' } } } }
'201': { description: 脱敏试点日报已生成, content: { application/json: { schema: { $ref: '#/components/schemas/OpsPilotDailySnapshotResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/diagnostics/pilot-weekly-snapshots:
post:
operationId: exportOpsPilotWeeklySnapshot
tags: [operations]
description: 绑定候选版本与不可变构建摘要,按指定IANA时区、从周一开始的七个自然日聚合内容审核、记忆、隐私请求、固件分布和配置差异,生成可下载且有审计记录的脱敏试点周报。平台没有权威投诉台账,因此响应明确要求附客服或CRM外部证据。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsPilotWeeklySnapshotRequest' } } } }
responses:
'200': { description: 试点周报幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/OpsPilotWeeklySnapshotResponse' } } } }
'201': { description: 脱敏试点周报已生成, content: { application/json: { schema: { $ref: '#/components/schemas/OpsPilotWeeklySnapshotResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/diagnostics/conversations/{id}/stop:
post:
operationId: stopOpsDiagnosticConversation
tags: [operations]
description: 由有权限运营人员安全停止或收敛指定通话,重复请求不创建第二个供应商停止任务。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticReasonRequest' } } } }
responses:
'200': { description: 停止动作结果, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticActionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/diagnostics/conversations/{id}/reconcile:
post:
operationId: reconcileOpsDiagnosticConversation
tags: [operations]
description: 对启动中或停止中的供应商任务可靠排队状态对账;稳定状态返回无需排队的结果。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticReasonRequest' } } } }
responses:
'200': { description: 对账动作结果, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticActionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/diagnostics/devices/{id}/config-refresh:
post:
operationId: refreshOpsDiagnosticDeviceConfig
tags: [operations]
description: 为指定设备可靠创建一次应用当前期望配置版本的命令。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticReasonRequest' } } } }
responses:
'200': { description: 配置刷新幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticActionResponse' } } } }
'201': { description: 配置刷新命令已排队, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticActionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/diagnostics/devices/{id}/revoke:
post:
operationId: revokeOpsDiagnosticDevice
tags: [operations]
description: 由运营管理员立即吊销设备身份,后续设备签名请求均被拒绝;若设备存在未结束通话则在同一事务中过期或可靠停止。操作要求原因、幂等键和审计。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticReasonRequest' } } } }
responses:
'200': { description: 设备已吊销或幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDiagnosticActionResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/sensitive-access-requests:
get:
operationId: listOpsSensitiveAccessRequests
tags: [operations]
description: 申请人只查看自己的临时访问申请;审批和管理员角色查看当前客户组织的审批队列。读取时自动把到期申请收敛为EXPIRED。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 临时访问申请列表, content: { application/json: { schema: { $ref: '#/components/schemas/OpsSensitiveAccessRequestListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsSensitiveAccessRequest
tags: [operations]
description: 按单个通话申请字幕读取和/或录音播放能力,有效期至少5分钟且最长4小时;申请理由、操作人和范围进入审计。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CreateOpsSensitiveAccessRequest' } } } }
responses:
'200': { description: 幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/OpsSensitiveAccessRequestResponse' } } } }
'201': { description: 申请已进入待审批队列, content: { application/json: { schema: { $ref: '#/components/schemas/OpsSensitiveAccessRequestResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/sensitive-access-requests/{id}/review:
post:
operationId: reviewOpsSensitiveAccessRequest
tags: [operations]
description: 由另一名运营审批或管理员批准/拒绝申请;申请人禁止自批,决定和理由不可覆盖。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReviewOpsSensitiveAccessRequest' } } } }
responses:
'200': { description: 审批决定已记录, content: { application/json: { schema: { $ref: '#/components/schemas/OpsSensitiveAccessRequestResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/sensitive-conversations/{id}:
get:
operationId: getOpsSensitiveConversation
tags: [operations]
description: 仅向已批准申请的原申请人返回本通话最终字幕;若同一申请同时包含录音能力,则附带已验证录音分片编号。每次成功或拒绝均写访问日志和审计。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/OpsAccessGrantHeader' }]
responses:
'200': { description: 当前批准范围内的敏感通话数据, content: { application/json: { schema: { $ref: '#/components/schemas/OpsSensitiveConversationResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
/api/v1/ops/sensitive-media/{id}/play:
post:
operationId: createOpsSensitiveRecordingAccess
tags: [operations]
description: 在申请人、租户、通话、RECORDING_PLAY能力、有效期和原始录音授权全部有效时,现场签发5分钟播放地址并逐次审计。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsSensitiveRecordingAccessRequest' } } } }
responses:
'201': { description: 短期录音播放地址已签发, content: { application/json: { schema: { $ref: '#/components/schemas/OpsSensitiveRecordingAccessResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
/api/v1/ops/config-rollouts:
get:
operationId: listOpsConfigRollouts
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- { name: config_key, in: query, required: false, schema: { type: string, pattern: '^[a-z][a-z0-9_.-]{2,99}$' } }
responses:
'200': { description: 当前和历史配置投放范围, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigRolloutListResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/config-rollouts/{id}/pause:
patch:
operationId: pauseOpsConfigRollout
tags: [operations]
description: 暂停活动投放,使其不再被后续新建通话选中;已建立通话继续使用其冻结配置。仅配置审批员或平台管理员可操作。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IfMatchHeader'
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsReasonRequest' } } } }
responses:
'200': { description: 投放已暂停, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigRolloutResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/config-rollouts/{id}/resume:
patch:
operationId: resumeOpsConfigRollout
tags: [operations]
description: 恢复尚未被替代的暂停投放。目标配置必须仍为已发布状态,且同一配置键和范围不存在其他活动投放。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IfMatchHeader'
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsReasonRequest' } } } }
responses:
'200': { description: 投放已恢复, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/OpsConfigRolloutResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/device-groups:
get:
operationId: listOpsDeviceGroups
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 可用于灰度范围的设备组, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDeviceGroupListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsDeviceGroup
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateOpsDeviceGroupRequest' } } }
responses:
'201': { description: 设备组已创建, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDeviceGroupResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/price-books:
get:
operationId: listOpsPriceBooks
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 当前客户组织的价格版本历史及不可变单价, content: { application/json: { schema: { $ref: '#/components/schemas/BillingPriceBookListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsPriceBook
tags: [operations]
description: 创建供应商价格草稿;单价按百万分之一货币单位保存,历史版本不可修改。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateBillingPriceBookRequest' } } }
responses:
'201': { description: 价格草稿已创建, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/BillingPriceBookResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/price-books/{id}/publish:
patch:
operationId: publishOpsPriceBook
tags: [operations]
description: 由另一名审批人员发布价格版本;同一客户组织与供应商的旧发布版本自动退役,但历史费用不重算。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IfMatchHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/OpsReasonRequest' } } }
responses:
'200': { description: 价格版本已发布, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/BillingPriceBookResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 状态冲突或创建人尝试审批自己的价格版本 }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/quota-policies:
get:
operationId: listOpsQuotaPolicies
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 客户组织与设备维度的当前及历史额度策略, content: { application/json: { schema: { $ref: '#/components/schemas/QuotaPolicyListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsQuotaPolicy
tags: [operations]
description: 创建并激活新的额度策略版本;同一范围原策略自动退役,创建操作仅允许审批角色执行并写审计。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateQuotaPolicyRequest' } } }
responses:
'201': { description: 新额度策略版本已激活, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/QuotaPolicyResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/cost-summary:
get:
operationId: getOpsCostSummary
tags: [operations]
description: 按标准化用量类别、指标、单位和币种聚合已冻结费用,不返回供应商内部任务编号。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- { name: from, in: query, required: true, schema: { type: string, format: date-time } }
- { name: to, in: query, required: true, schema: { type: string, format: date-time } }
responses:
'200': { description: 指定时间范围的费用汇总, content: { application/json: { schema: { $ref: '#/components/schemas/CostSummaryResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
2026-08-29 21:56:51 +08:00
/api/v1/ops/usage-overview:
get:
operationId: getOpsUsageOverview
tags: [operations, billing]
description: 运营人员查看客户组织整体通话时长与已核价费用,可按家庭和设备逐级筛选;不返回转写、录音或供应商内部编号。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- { name: from, in: query, required: true, schema: { type: string, format: date-time } }
- { name: to, in: query, required: true, schema: { type: string, format: date-time } }
- { name: timezone, in: query, required: false, schema: { type: string, default: Asia/Shanghai } }
- { name: household_id, in: query, required: false, schema: { type: string, format: uuid } }
- { name: device_id, in: query, required: false, schema: { type: string, format: uuid } }
responses:
'200': { description: 指定范围的通话时长、活动日、设备拆分、最近通话和可用费用汇总, content: { application/json: { schema: { $ref: '#/components/schemas/UsageOverviewResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
2026-08-26 06:41:07 +08:00
/api/v1/ops/alert-routing-policies:
get:
operationId: listOpsAlertRoutingPolicies
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 告警分类与级别对应的当前和历史接收、响应、升级及运行手册策略, content: { application/json: { schema: { $ref: '#/components/schemas/AlertRoutingPolicyListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsAlertRoutingPolicy
tags: [operations]
description: 创建并立即激活新的告警路由版本,原同分类同级别版本退役,全程写入运营审计。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateAlertRoutingPolicyRequest' } } }
responses:
'201': { description: 告警路由版本已激活, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/AlertRoutingPolicyResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/alert-delivery-tests:
get:
operationId: listOpsAlertDeliveryTests
tags: [operations]
description: 返回最近50次告警接收器联通测试及真实Outbox投递状态,不包含接收器地址、签名密钥或发起原因。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 最近的告警接收器联通测试, content: { application/json: { schema: { $ref: '#/components/schemas/AlertDeliveryTestListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/alert-routing-policies/{id}/delivery-tests:
post:
operationId: createOpsAlertDeliveryTest
tags: [operations]
description: 针对活动路由发起受控测试通知;复用正式Webhook签名、Worker与重试链路,但不创建正式告警事件。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateAlertDeliveryTestRequest' } } }
responses:
'201': { description: 联通测试已进入可靠投递队列, content: { application/json: { schema: { $ref: '#/components/schemas/AlertDeliveryTestResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/alerts:
get:
operationId: listOpsAlerts
tags: [operations]
description: 按严重度和最后命中时间返回客户组织告警队列,不泄露其他客户组织的信号或处置记录。
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
- { name: status, in: query, required: false, schema: { $ref: '#/components/schemas/AlertStatus' } }
responses:
'200': { description: 告警队列, content: { application/json: { schema: { $ref: '#/components/schemas/AlertIncidentListResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/alerts/{id}:
get:
operationId: getOpsAlert
tags: [operations]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/ResourceID'
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
responses:
'200': { description: 告警详情及完整处置动作时间线, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/AlertIncidentResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
/api/v1/ops/alerts/{id}/acknowledge:
post:
operationId: acknowledgeOpsAlert
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IfMatchHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/AlertTransitionRequest' } } } }
responses:
'200': { description: 告警已确认并记录负责人, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/AlertIncidentResponse' } } } }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/alerts/{id}/mitigate:
post:
operationId: mitigateOpsAlert
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IfMatchHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/AlertTransitionRequest' } } } }
responses:
'200': { description: 告警已完成缓解, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/AlertIncidentResponse' } } } }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/alerts/{id}/resolve:
post:
operationId: resolveOpsAlert
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IfMatchHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/AlertTransitionRequest' } } } }
responses:
'200': { description: 告警已闭环, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/AlertIncidentResponse' } } } }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/ops/alert-silences:
get:
operationId: listOpsAlertSilences
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 当前和历史告警静默窗口, content: { application/json: { schema: { $ref: '#/components/schemas/AlertSilenceListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsAlertSilence
tags: [operations]
description: 在规则、分类或资源范围创建最长30天的有因静默;静默只抑制处置队列,不删除命中记录。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CreateAlertSilenceRequest' } } } }
responses:
'201': { description: 静默窗口已创建, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/AlertSilenceResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/ops/alert-silences/{id}/revoke:
post:
operationId: revokeOpsAlertSilence
tags: [operations]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/ResourceID' }, { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }, { $ref: '#/components/parameters/IfMatchHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OpsReasonRequest' } } } }
responses:
'200': { description: 静默窗口已撤销, headers: { ETag: { schema: { type: string } } }, content: { application/json: { schema: { $ref: '#/components/schemas/AlertSilenceResponse' } } } }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/sharing-grants:
get:
operationId: listSharingGrants
tags: [sharing]
security: [{ oidcBearer: [] }]
parameters:
- name: subject_id
in: query
required: true
schema: { type: string, format: uuid }
responses:
'200': { description: 当前长者的分享授权历史, content: { application/json: { schema: { $ref: '#/components/schemas/SharingGrantListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createSharingGrant
tags: [sharing]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateSharingGrantRequest' } } }
responses:
'201': { description: 定向分享授权已建立, content: { application/json: { schema: { $ref: '#/components/schemas/SharingGrantResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 幂等键正文冲突 }
/api/v1/public/shares/{id}:
get:
operationId: accessPublicSharedResource
tags: [sharing]
description: 使用创建匿名分享时返回的一次口令读取资源;无需登录,口令只在创建响应中出现,服务端仅保存SHA-256摘要。
parameters:
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
- { name: X-Share-Token, in: header, required: true, schema: { type: string, minLength: 32, maxLength: 256 } }
responses:
'200': { description: 按匿名分享权限返回最小资源内容, content: { application/json: { schema: { $ref: '#/components/schemas/SharedResourceResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'410': { description: 分享已撤销或过期 }
/api/v1/sharing-grants/{id}:
delete:
operationId: revokeSharingGrant
tags: [sharing]
security: [{ oidcBearer: [] }]
parameters:
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
responses:
'200': { description: 分享已撤销;重复撤销返回当前结果, content: { application/json: { schema: { $ref: '#/components/schemas/SharingGrantResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
/api/v1/sharing-grants/{id}/resource:
get:
operationId: accessSharedResource
tags: [sharing]
description: 仅授权中指定的登录用户可读取;故事和字幕返回文字,录音返回5分钟短期播放或下载地址。每次成功和拒绝均写入分享访问日志。
security: [{ oidcBearer: [] }]
parameters:
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
responses:
'200': { description: 按授权权限返回最小资源内容, content: { application/json: { schema: { $ref: '#/components/schemas/SharedResourceResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
'410': { description: 分享已撤销或过期 }
patch:
operationId: editSharedStory
tags: [sharing]
description: 仅持有有效EDIT授权的指定登录用户可修改故事;每次修改形成新修订版本并保留原来源。
security: [{ oidcBearer: [] }]
parameters:
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
- $ref: '#/components/parameters/IfMatchHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/EditSharedStoryRequest' } } }
responses:
'200': { description: 新修订版本, content: { application/json: { schema: { $ref: '#/components/schemas/SharedResourceResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'410': { description: 分享已撤销或过期 }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/events:
get:
operationId: streamWebEvents
tags: [event-stream]
description: 以SSE推送当前账号仍有家庭成员权限的资源状态;首次连接从当前游标开始,断线后通过Last-Event-ID在15分钟窗口内续传。事件不包含字幕、录音地址、凭证、提示词或密钥。
security: [{ oidcBearer: [] }]
parameters:
- name: Last-Event-ID
in: header
required: false
schema: { type: string, pattern: '^[1-9][0-9]*$' }
description: 最近成功处理的SSE事件编号。
responses:
'200':
description: 服务器状态事件流;连接约25秒后主动轮换,客户端携带最后事件编号重连。
content:
text/event-stream:
schema: { type: string }
'400': { description: 事件编号格式不正确 }
'401': { $ref: '#/components/responses/AuthenticationError' }
'410': { description: 事件编号不存在、无权访问或已经超过续传窗口,客户端应执行一次完整刷新并无游标重连 }
/health/live:
get:
operationId: getLiveness
tags: [platform]
responses:
'200':
description: 进程存活
content:
application/json:
schema:
$ref: '#/components/schemas/LivenessResponse'
/health/ready:
get:
operationId: getReadiness
tags: [platform]
responses:
'200':
description: 所有必要依赖可用
content:
application/json:
schema:
$ref: '#/components/schemas/ReadinessResponse'
'503':
description: 至少一个必要依赖不可用
content:
application/json:
schema:
$ref: '#/components/schemas/ReadinessResponse'
/api/v1/version:
get:
operationId: getVersion
tags: [platform]
responses:
'200':
description: 构建版本信息
content:
application/json:
schema:
$ref: '#/components/schemas/VersionResponse'
/api/v1/me:
get:
operationId: getCurrentUser
tags: [identity]
security:
- oidcBearer: []
responses:
'200':
description: 当前外部身份在平台中的客户组织和家庭成员关系
content:
application/json:
schema:
$ref: '#/components/schemas/CurrentUserResponse'
'401':
description: 未登录、令牌无效或令牌已过期
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: 外部身份没有有效的平台账号映射
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/v1/households:
get:
operationId: listHouseholds
tags: [household]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/TenantSelectionHeader'
responses:
'200':
description: 当前账号可访问的家庭;租户选择仍由服务端验证
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
post:
operationId: createHousehold
tags: [household]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/RequiredTenantSelectionHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateHouseholdRequest' } } }
responses:
'201':
description: 家庭及创建者所有者成员关系已在同一事务中创建
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/households/{id}:
parameters:
- $ref: '#/components/parameters/ResourceID'
get:
operationId: getHousehold
tags: [household]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 家庭详情及当前账号角色能力
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
patch:
operationId: updateHousehold
tags: [household]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/IfMatchHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/UpdateHouseholdRequest' } } }
responses:
'200':
description: 家庭已按指定版本修改
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/households/{id}/members:
parameters:
- $ref: '#/components/parameters/ResourceID'
get:
operationId: listHouseholdMembers
tags: [household-member]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 当前家庭的有效成员;成员角色不等同于高敏感资源授权
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdMemberListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/households/{id}/members/{member_id}:
parameters:
- $ref: '#/components/parameters/ResourceID'
- name: member_id
in: path
required: true
schema: { type: string, format: uuid }
patch:
operationId: updateHouseholdMemberRole
tags: [household-member]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/UpdateHouseholdMemberRequest' } } }
responses:
'200':
description: 非所有者成员角色已修改
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdMemberResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
delete:
operationId: removeHouseholdMember
tags: [household-member]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
responses:
'200':
description: 成员关系已标记为移除;所有者必须先转移所有权
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdMemberResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
2026-08-29 21:56:51 +08:00
/api/v1/households/{id}/usage-overview:
get:
operationId: getFamilyUsageOverview
tags: [household, billing]
description: 家庭成员查看自己家庭的通话时长与已核价费用,可进一步筛选该家庭设备;服务端始终按登录成员关系限定家庭范围。
security: [{ oidcBearer: [] }]
parameters:
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
- { name: from, in: query, required: true, schema: { type: string, format: date-time } }
- { name: to, in: query, required: true, schema: { type: string, format: date-time } }
- { name: timezone, in: query, required: false, schema: { type: string, default: Asia/Shanghai } }
- { name: device_id, in: query, required: false, schema: { type: string, format: uuid } }
responses:
'200': { description: 当前家庭及可选设备范围内的通话时长与可用费用汇总, content: { application/json: { schema: { $ref: '#/components/schemas/UsageOverviewResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
2026-08-26 06:41:07 +08:00
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/households/{id}/invitations:
parameters:
- $ref: '#/components/parameters/ResourceID'
get:
operationId: listMemberInvitations
tags: [household-member]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 邀请历史不包含明文邀请凭据
content: { application/json: { schema: { $ref: '#/components/schemas/MemberInvitationListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createMemberInvitation
tags: [household-member]
security: [{ oidcBearer: [] }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateMemberInvitationRequest' } } }
responses:
'201':
description: 明文token仅在本次响应中返回;服务端只保存SHA-256摘要
headers:
Cache-Control: { schema: { type: string, const: no-store } }
content: { application/json: { schema: { $ref: '#/components/schemas/MemberInvitationResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/households/{id}/invitations/{invitation_id}/revoke:
parameters:
- $ref: '#/components/parameters/ResourceID'
- name: invitation_id
in: path
required: true
schema: { type: string, format: uuid }
post:
operationId: revokeMemberInvitation
tags: [household-member]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 未使用邀请已撤销
content: { application/json: { schema: { $ref: '#/components/schemas/MemberInvitationResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { $ref: '#/components/responses/NotFoundError' }
/api/v1/member-invitations/preview:
post:
operationId: previewMemberInvitation
tags: [household-member]
security: [{ oidcBearer: [] }]
description: 使用一次性邀请凭据只读预览目标客户组织、家庭、角色和到期时间;不创建账号或成员关系,正式接受时仍会重新校验。
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/AcceptMemberInvitationRequest' } } }
responses:
'200':
description: 邀请仍有效,可供当前登录用户确认目标关系
headers:
Cache-Control: { schema: { type: string, const: no-store } }
content: { application/json: { schema: { $ref: '#/components/schemas/MemberInvitationPreviewResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/member-invitations/accept:
post:
operationId: acceptMemberInvitation
tags: [household-member]
security: [{ oidcBearer: [] }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/AcceptMemberInvitationRequest' } } }
responses:
'201':
description: 当前登录账号已加入邀请指定的客户组织和家庭
headers:
Cache-Control: { schema: { type: string, const: no-store } }
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdMemberResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
/api/v1/households/{id}/ownership:
parameters:
- $ref: '#/components/parameters/ResourceID'
post:
operationId: transferHouseholdOwnership
tags: [household-member]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/TransferHouseholdOwnershipRequest' } } }
responses:
'200':
description: 目标成员成为所有者,原所有者降为管理员
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/HouseholdResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/households/{id}/subjects:
parameters:
- $ref: '#/components/parameters/ResourceID'
get:
operationId: listSubjects
tags: [subject]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 家庭内未删除的长者档案
content: { application/json: { schema: { $ref: '#/components/schemas/SubjectListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createSubject
tags: [subject]
security: [{ oidcBearer: [] }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateSubjectRequest' } } }
responses:
'201':
description: 长者档案已创建
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/SubjectResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/subjects/{id}:
parameters:
- $ref: '#/components/parameters/ResourceID'
get:
operationId: getSubject
tags: [subject]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 长者档案详情
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/SubjectResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
patch:
operationId: updateSubject
tags: [subject]
security: [{ oidcBearer: [] }]
parameters:
- $ref: '#/components/parameters/IfMatchHeader'
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/UpdateSubjectRequest' } } }
responses:
'200':
description: 长者档案已按指定版本修改
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/SubjectResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/subjects/{id}/conversation-readiness:
parameters:
- $ref: '#/components/parameters/ResourceID'
get:
operationId: getSubjectConversationReadiness
tags: [subject, device, consent]
description: 汇总家庭可处理的首次通话准备条件;额度、生产路由及并发通话仍在设备真正创建通话时原子校验,避免把瞬时结果误报为保证。
security: [{ oidcBearer: [] }]
responses:
'200':
description: 当前长者的首次通话就绪清单
content: { application/json: { schema: { $ref: '#/components/schemas/ConversationReadinessResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/subjects/{id}/consents:
parameters:
- $ref: '#/components/parameters/ResourceID'
get:
operationId: listSubjectConsents
tags: [consent]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 授权追加历史;effective标明查询时刻是否生效
content: { application/json: { schema: { $ref: '#/components/schemas/ConsentListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: grantSubjectConsent
tags: [consent]
security: [{ oidcBearer: [] }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/GrantConsentRequest' } } }
responses:
'201':
description: 授权记录已追加,并创建新的不可变授权快照
content: { application/json: { schema: { $ref: '#/components/schemas/ConsentResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409':
description: 同类型已有有效授权,或政策版本已更新
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
/api/v1/subjects/{id}/facts:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listSubjectFacts
tags: [subject-fact]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 长者稳定事实、来源、确认状态和敏感等级
content: { application/json: { schema: { $ref: '#/components/schemas/SubjectFactListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createSubjectFact
tags: [subject-fact]
security: [{ oidcBearer: [] }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateSubjectFactRequest' } } }
responses:
'201':
description: 稳定事实或待核对候选已创建;事实正文不会进入审计详情
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/SubjectFactResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/subjects/{id}/facts/{fact_id}:
parameters:
- $ref: '#/components/parameters/ResourceID'
- name: fact_id
in: path
required: true
schema: { type: string, format: uuid }
patch:
operationId: updateSubjectFact
tags: [subject-fact]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/UpdateSubjectFactRequest' } } }
responses:
'200':
description: 事实已按指定版本修改或完成核对
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/SubjectFactResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404':
description: 事实不属于指定长者
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'409':
description: 确认事实但缺少可追溯来源
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/subjects/{id}/consents/{consent_id}/withdraw:
parameters:
- $ref: '#/components/parameters/ResourceID'
- name: consent_id
in: path
required: true
schema: { type: string, format: uuid }
post:
operationId: withdrawSubjectConsent
tags: [consent]
security: [{ oidcBearer: [] }]
description: 撤回时间首次写入后不可变;重复调用返回同一撤回结果。若活动通话冻结快照正在使用被撤回的字幕、原录音、故事整理或个性化记忆授权,同一事务把通话转为STOPPING并可靠停止Agent;尚未启动Agent的房间直接过期。设备后续心跳或遥测从权威通话状态取得stop动作。此行为不改变响应结构,对旧网页客户端向后兼容。
responses:
'200':
description: 授权已撤回或此前已经撤回;相关活动通话的停止意图已与撤回事务同时保存
content: { application/json: { schema: { $ref: '#/components/schemas/ConsentResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404':
description: 授权编号不属于该长者
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
/api/v1/device-claims:
post:
operationId: claimDevice
tags: [device-management]
security: [{ oidcBearer: [] }]
description: 使用只保存摘要的一次性短期绑定码,把未绑定设备绑定到当前账号有管理权的家庭和长者。
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/DeviceClaimRequest' } } }
responses:
'201':
description: 首次绑定或同一绑定的安全重试
headers:
Idempotency-Replayed:
schema: { type: string, enum: ['true'] }
description: 同一绑定码再次提交完全相同目标时出现。
content: { application/json: { schema: { $ref: '#/components/schemas/DeviceClaimResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409':
description: 绑定码无效、过期、撤销、用于其他目标,或设备已有有效绑定
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
2026-08-29 21:56:51 +08:00
/api/v1/ops/devices:
get:
operationId: listOpsDevices
tags: [device-management]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
description: 仅独立operator账号可读取;返回租户内全部设备及当前家庭、长者归属,不返回密钥明文。
responses:
'200': { description: 运维设备清单, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDeviceListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createOpsDevice
tags: [device-management]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
description: 自动生成设备UUID和256位随机HMAC密钥;密钥明文仅在本响应出现一次。
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CreateOpsDeviceRequest' } } } }
responses:
'201': { description: 设备及一次性密钥, content: { application/json: { schema: { $ref: '#/components/schemas/CreateOpsDeviceResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/device-assignment-options:
get:
operationId: listOpsDeviceAssignmentOptions
tags: [device-management]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/RequiredTenantSelectionHeader' }]
responses:
'200': { description: 可选家庭和长者, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDeviceAssignmentOptionListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/ops/devices/{id}:
parameters:
- { $ref: '#/components/parameters/ResourceID' }
- { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }
patch:
operationId: updateOpsDevice
tags: [device-management]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/UpdateOpsDeviceRequest' } } } }
responses:
'200': { description: 更新后的设备, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDeviceResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
delete:
operationId: deleteOpsDevice
tags: [device-management]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
description: 可审计软删除;吊销设备与凭据并关闭当前绑定,保留历史记录。
responses:
'200': { description: 已吊销设备, content: { application/json: { schema: { $ref: '#/components/schemas/OpsDeviceResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
/api/v1/ops/devices/{id}/credentials/rotate:
parameters:
- { $ref: '#/components/parameters/ResourceID' }
- { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }
post:
operationId: rotateOpsDeviceCredential
tags: [device-management]
security: [{ oidcBearer: [] }]
description: 轮换并只返回一次新密钥;旧密钥在事务提交后立即失效。
responses:
'201': { description: 一次性新密钥, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceCredentialIssueResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { description: 设备不存在, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/api/v1/ops/devices/{id}/claims:
parameters:
- { $ref: '#/components/parameters/ResourceID' }
- { $ref: '#/components/parameters/RequiredTenantSelectionHeader' }
post:
operationId: issueOpsDeviceClaim
tags: [device-management]
security: [{ oidcBearer: [] }]
description: 为已登记且尚未绑定的设备生成24小时有效的一次性绑定码;旧的未使用绑定码同时撤销,明文仅在本响应出现一次。
responses:
'201': { description: 一次性设备绑定码, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceClaimIssueResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { description: 设备不存在, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'409': { description: 设备已绑定、已隔离或已吊销, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
2026-08-26 06:41:07 +08:00
/api/v1/devices:
get:
operationId: listManagedDevices
tags: [device-management]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 当前账号家庭内具有有效绑定的设备
content: { application/json: { schema: { $ref: '#/components/schemas/ManagedDeviceListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
/api/v1/devices/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getManagedDevice
tags: [device-management]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 设备登记、当前绑定和配置版本摘要
content: { application/json: { schema: { $ref: '#/components/schemas/ManagedDeviceResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
2026-08-29 21:56:51 +08:00
/api/v1/devices/{id}/binding-impact:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getDeviceBindingImpact
tags: [device-management]
security: [{ oidcBearer: [] }]
description: 在解绑或转移前重新检查活动通话、未完成设备命令和进行中固件任务;返回当前绑定编号供正式操作做并发校验。
parameters:
- { name: action, in: query, required: true, schema: { type: string, enum: [unbind, transfer] } }
- { name: target_subject_id, in: query, required: false, schema: { type: string, format: uuid } }
responses:
'200':
description: 当前影响范围;allowed为false时不得提交绑定变更
headers: { Cache-Control: { schema: { type: string, const: no-store } } }
content: { application/json: { schema: { $ref: '#/components/schemas/DeviceBindingImpactResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/devices/{id}/binding-change:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: changeDeviceBinding
tags: [device-management]
security: [{ oidcBearer: [] }]
description: 基于影响检查返回的绑定编号执行受控解绑或转移。旧绑定保留审计历史;转移会创建新的有效绑定。
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/ChangeDeviceBindingRequest' } } }
responses:
'200':
description: 绑定关系已变更
content: { application/json: { schema: { $ref: '#/components/schemas/DeviceBindingChangeResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409':
description: 影响范围存在阻断项,或当前绑定已在检查后发生变化
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
2026-08-26 06:41:07 +08:00
/api/v1/devices/{id}/presence:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getDevicePresence
tags: [device-management]
security: [{ oidcBearer: [] }]
responses:
'200':
description: Redis实时在线状态;无热状态时返回PostgreSQL最后上报时间并标记离线
headers:
Cache-Control: { schema: { type: string, const: no-store } }
content: { application/json: { schema: { $ref: '#/components/schemas/DevicePresenceResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/devices/{id}/twin:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getDeviceTwin
tags: [device-management]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 云端期望配置、设备实际配置、版本差异和最后同步时间
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/DeviceTwinResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
patch:
operationId: updateDeviceTwin
tags: [device-management]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/UpdateDeviceTwinRequest' } } }
responses:
'200':
description: 新的期望配置版本已经保存,设备可在下次在线时应用
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/DeviceTwinResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/devices/{id}/commands:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listDeviceCommands
tags: [device-management]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 返回设备最近100条命令及执行状态, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceCommandListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createDeviceCommand
tags: [device-management]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CreateDeviceCommandRequest' } } } }
responses:
'202': { description: 命令已可靠排队等待设备拉取, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceCommandResponse' } } } }
'200': { description: 幂等重放, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceCommandResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 幂等冲突, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/api/v1/households/{id}/firmware-signing-keys:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listFirmwareSigningKeys
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 返回租户可信公钥指纹、状态和固件引用统计, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareSigningKeyListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: registerFirmwareSigningKey
tags: [firmware]
security: [{ oidcBearer: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RegisterFirmwareSigningKeyRequest' } } } }
responses:
'201': { description: Ed25519可信公钥已登记 }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 密钥编号已绑定其他公钥或已被吊销 }
/api/v1/households/{id}/firmware-signing-keys/revoke:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: revokeFirmwareSigningKey
tags: [firmware]
security: [{ oidcBearer: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RevokeFirmwareSigningKeyRequest' } } } }
responses:
'200': { description: 活动公钥已吊销且不能再用于新制品或新灰度, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareSigningKeyResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 密钥不存在,或仍被上传中版本/运行中灰度引用 }
/api/v1/households/{id}/firmware-releases:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listFirmwareReleases
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 返回当前家庭最近100个固件版本, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: prepareFirmwareRelease
tags: [firmware]
security: [{ oidcBearer: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PrepareFirmwareReleaseRequest' } } } }
responses:
'201': { description: 创建UPLOADING版本并返回15分钟私有上传地址, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/firmware-releases/{id}/finalize:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: finalizeFirmwareRelease
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 大小、SHA-256和可信Ed25519签名均通过后进入READY, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 制品或签名校验失败 }
/api/v1/firmware-releases/{id}/impact:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getFirmwareReleaseImpact
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 返回关联批次、设备阶段、命令处置和最多100条仍需观察设备, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseImpactResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/firmware-releases/{id}/upload-session:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: renewFirmwareUpload
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 为仍处于UPLOADING的版本重新签发15分钟私有上传地址, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 固件版本已经就绪、暂停或退役 }
/api/v1/firmware-releases/{id}/pause:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: pauseFirmwareRelease
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 将READY版本转为PAUSED,同时暂停关联运行批次并取消未投递命令, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 只有READY或已PAUSED版本允许执行该操作 }
/api/v1/firmware-releases/{id}/resume:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: resumeFirmwareRelease
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 在签名公钥仍活动时将PAUSED版本恢复为READY;旧批次不会自动恢复, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 版本状态不允许恢复,或签名公钥已吊销 }
/api/v1/firmware-releases/{id}/retire:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: retireFirmwareRelease
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 将版本转为RETIRED;未完成对象尝试清理,已验证对象和历史记录保留, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareReleaseResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 版本状态不允许退役,或仍有运行中灰度批次需先通过版本暂停操作处置 }
/api/v1/households/{id}/firmware-rollouts:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listFirmwareRollouts
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 返回当前家庭最近100个固件批次及结果汇总, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareRolloutListResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: startFirmwareRollout
tags: [firmware]
security: [{ oidcBearer: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/StartFirmwareRolloutRequest' } } } }
responses:
'202': { description: 兼容目标已按稳定哈希比例进入升级批次, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareRolloutResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 版本未就绪或目标不兼容 }
/api/v1/firmware-rollouts/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getFirmwareRollout
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 批次目标、成功和失败统计, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareRolloutResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/firmware-rollouts/{id}/pause:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: pauseFirmwareRollout
tags: [firmware]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 暂停批次并取消尚未投递的命令, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareRolloutResponse' } } } }
'409': { description: 批次不是RUNNING }
/api/v1/firmware-rollouts/{id}/rollback:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: rollbackFirmwareRollout
tags: [firmware]
security: [{ oidcBearer: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RollbackFirmwareRolloutRequest' } } } }
responses:
'202': { description: 原批次暂停并以已验证旧版本创建100%回滚批次, content: { application/json: { schema: { $ref: '#/components/schemas/FirmwareRolloutResponse' } } } }
'409': { description: 回滚版本不可用 }
/api/v1/subjects/{id}/conversations:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listSubjectConversations
tags: [conversation-query]
security: [{ oidcBearer: [] }]
parameters:
- name: status
in: query
schema: { $ref: '#/components/schemas/ConversationStatus' }
- name: engine_mode
in: query
schema: { type: string, enum: [s2s_pure, s2s_hybrid, cascade] }
- name: from
in: query
schema: { type: string, format: date-time }
description: 创建时间下界,包含。
- name: to
in: query
schema: { type: string, format: date-time }
description: 创建时间上界,不包含。
- name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
- name: cursor
in: query
schema: { type: string }
description: 服务端签发的HMAC游标,禁止由客户端拼接。
responses:
'200':
description: 指定长者的通话分页列表
content: { application/json: { schema: { $ref: '#/components/schemas/ConversationPageResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/conversations/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getConversationDetail
tags: [conversation-query]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 脱敏通话详情、冻结快照版本、RTC任务摘要和完整状态历史;不返回Token或供应商任务引用
content: { application/json: { schema: { $ref: '#/components/schemas/ConversationDetailResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/conversations/{id}/usage:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getConversationUsage
tags: [conversation-query, billing]
description: 返回家庭成员可查看的标准化用量与冻结费用;不返回供应商事件号、任务编号或内部价格资源编号。
security: [{ oidcBearer: [] }]
responses:
'200': { description: 当前通话的用量和费用汇总, content: { application/json: { schema: { $ref: '#/components/schemas/ConversationUsageResponse' } } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/subjects/{id}/recording-access-grants:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listRecordingAccessGrants
tags: [media]
description: 仅家庭所有者或管理员可查看当前长者最近的录音访问授权及撤销、到期状态。
security: [{ oidcBearer: [] }]
responses:
'200': { description: 最近200条录音访问授权, content: { application/json: { schema: { $ref: '#/components/schemas/RecordingAccessGrantListResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: grantRecordingAccess
tags: [media]
description: 家庭所有者或管理员执行显式授权;家庭角色本身不产生播放或下载能力。
security: [{ oidcBearer: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/GrantRecordingAccessRequest' } } } }
responses:
'201': { description: 播放或下载授权已追加保存, content: { application/json: { schema: { $ref: '#/components/schemas/RecordingAccessGrantResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/recording-access-grants/{id}/revoke:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: revokeRecordingAccess
tags: [media]
security: [{ oidcBearer: [] }]
responses:
'200': { description: 授权已撤销;重复撤销返回同一结果, content: { application/json: { schema: { $ref: '#/components/schemas/RecordingAccessGrantResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'404': { description: 授权不存在 }
/api/v1/conversations/{id}/media:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getConversationMedia
tags: [media]
description: 仅在原录音保存授权和当前账号独立播放或下载授权均有效时返回已验证分片;响应不含对象地址。
security: [{ oidcBearer: [] }]
responses:
'200': { description: 返回near/far已验证分片和当前账号的播放/下载能力, content: { application/json: { schema: { $ref: '#/components/schemas/ConversationMediaResponse' } } } }
'403': { description: 当前账号无独立录音访问授权 }
'404': { description: 通话不存在或不属于当前家庭 }
/api/v1/media-segments/{id}/access:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: createMediaAccess
tags: [media]
description: 每次访问重新核验成员关系、原录音授权和独立PLAY/DOWNLOAD授权,并记录成功或拒绝审计。
security: [{ oidcBearer: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/CreateMediaAccessRequest' } } } }
responses:
'200': { description: 返回单个对象5分钟短期地址, content: { application/json: { schema: { $ref: '#/components/schemas/MediaAccessResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'403': { description: 当前账号没有对应的播放或下载授权 }
'404': { description: 分片不存在、未验证或不属于当前租户 }
/api/v1/conversations/{id}/turns:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listConversationTurns
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters:
- name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
- name: cursor
in: query
schema: { type: string }
description: 服务端签发的话轮顺序游标。
responses:
'200':
description: 仅返回授权允许保存的最终话轮;按供应商最终序号稳定排序。
content: { application/json: { schema: { $ref: '#/components/schemas/ConversationTurnPageResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/conversations/{id}/summaries:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listConversationContentSummaries
tags: [content-review]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 返回版本化的通话摘要和开放话题,均保留源话轮编号。
content: { application/json: { schema: { $ref: '#/components/schemas/ConversationContentSummaryListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/conversations/{id}/summaries:regenerate:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: regenerateConversationSummary
tags: [content-review]
security: [{ oidcBearer: [] }]
responses:
'202': { description: 已按当前激活模型排队生成新的版本化摘要, content: { application/json: { schema: { $ref: '#/components/schemas/ConversationSummaryRegenerationResponse' } } } }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { $ref: '#/components/responses/ConflictError' }
2026-08-26 06:41:07 +08:00
/api/v1/subjects/{id}/stories:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listSubjectStories
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters:
- name: status
in: query
schema: { $ref: '#/components/schemas/StoryStatus' }
responses:
'200':
description: 指定长者的故事候选及审核状态列表;列表不展开来源和事实。
content: { application/json: { schema: { $ref: '#/components/schemas/StoryListResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/stories/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getStory
tags: [content-review]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 故事当前版本、逐条原话来源和事实候选。
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/StoryResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
patch:
operationId: reviseStory
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/ReviseStoryRequest' } } }
responses:
'200':
description: 创建新的人工修订版本,保留旧版本及来源,不覆盖历史内容。
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/StoryResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 故事审核状态不允许修订, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/stories/{id}/confirm:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: confirmStory
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/StoryDecisionRequest' } } }
responses:
'200':
description: 人工确认故事并在当前有效个性化记忆授权下创建待索引记忆。
content: { application/json: { schema: { $ref: '#/components/schemas/StoryConfirmationResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 缺少来源、缺少个性化记忆授权或审核状态冲突, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
2026-08-29 21:56:51 +08:00
/api/v1/stories/{id}/facts/{fact_id}:
parameters:
- $ref: '#/components/parameters/ResourceID'
- { name: fact_id, in: path, required: true, schema: { type: string, format: uuid } }
patch:
operationId: updateFactCandidate
tags: [content-review]
security: [{ oidcBearer: [] }]
description: 单独编辑、确认、拒绝或停用一条事实候选;来源话轮和陈述依据不可由客户端改写。
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/UpdateFactCandidateRequest' } } }
responses:
'200':
description: 返回更新后的事实候选
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/FactCandidateResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 故事或事实候选状态不允许当前操作, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
2026-08-26 06:41:07 +08:00
/api/v1/stories/{id}/reject:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: rejectStory
tags: [content-review]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/StoryDecisionRequest' } } }
responses:
'200':
description: 拒绝故事及其仍为候选状态的事实,不创建记忆。
content: { application/json: { schema: { $ref: '#/components/schemas/StoryResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 故事审核状态不允许拒绝, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/subjects/{id}/memories:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listSubjectMemories
tags: [memory]
security: [{ oidcBearer: [] }]
parameters:
- name: q
in: query
schema: { type: string, maxLength: 200 }
description: 在当前长者、当前家庭权限边界内搜索记忆正文。
responses:
'200':
description: 返回未删除的已确认记忆及索引状态。
content: { application/json: { schema: { $ref: '#/components/schemas/CuratedMemoryListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/memories/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getCuratedMemory
tags: [memory]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 返回当前记忆版本、来源、确认人及索引状态。
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/CuratedMemoryResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
patch:
operationId: updateCuratedMemory
tags: [memory]
description: 修订当前记忆正文或切换ACTIVE/DISABLED状态;PENDING_DELETE、SUPERSEDED和DELETED均为不可修改终态,不能通过本接口恢复。
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/UpdateMemoryRequest' } } }
responses:
'200':
description: 创建新的记忆版本,或停用/重新启用记忆;旧索引立即失效。
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/CuratedMemoryResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 缺少当前个性化记忆授权、资源状态无变化或记忆已进入删除流程, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
delete:
operationId: deleteCuratedMemory
tags: [memory]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IfMatchHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/StoryDecisionRequest' } } }
responses:
'202':
description: 删除请求已受理;记忆立即停止召回,后台清理索引并清除数据库正文。
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/CuratedMemoryResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'412': { $ref: '#/components/responses/VersionConflictError' }
'428': { $ref: '#/components/responses/PreconditionRequiredError' }
/api/v1/subjects/{id}/privacy-requests:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listSubjectPrivacyRequests
tags: [privacy]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 返回当前长者的隐私请求及处理结果。
content: { application/json: { schema: { $ref: '#/components/schemas/PrivacyRequestListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createSubjectPrivacyRequest
tags: [privacy]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreatePrivacyRequest' } } }
responses:
'202':
2026-08-29 21:56:51 +08:00
description: 请求已受理。ACCESS和DELETE进入后台处理;CORRECTION与CONSENT_WITHDRAWAL在受理事务中完成并返回COMPLETED。
2026-08-26 06:41:07 +08:00
content: { application/json: { schema: { $ref: '#/components/schemas/PrivacyRequestResponse' } } }
'200':
description: 幂等重放,返回原隐私请求。
content: { application/json: { schema: { $ref: '#/components/schemas/PrivacyRequestResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 幂等键已用于不同请求, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/api/v1/privacy-requests/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getPrivacyRequest
tags: [privacy]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 返回隐私请求、数据盘点结果和子任务状态;响应禁止缓存。
headers: { ETag: { $ref: '#/components/headers/StrongETag' } }
content: { application/json: { schema: { $ref: '#/components/schemas/PrivacyRequestResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
/api/v1/subjects/{id}/exports:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: listSubjectExports
tags: [privacy]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 返回当前长者的私有导出任务,不返回对象存储内部路径或长期地址。
content: { application/json: { schema: { $ref: '#/components/schemas/ExportTaskListResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
post:
operationId: createSubjectExport
tags: [privacy]
security: [{ oidcBearer: [] }]
parameters: [{ $ref: '#/components/parameters/IdempotencyKeyHeader' }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/CreateExportTask' } } }
responses:
'202':
description: 导出任务已受理,文件将由Worker生成到私有对象存储。
content: { application/json: { schema: { $ref: '#/components/schemas/ExportTaskResponse' } } }
'200':
description: 幂等重放,返回原导出任务。
content: { application/json: { schema: { $ref: '#/components/schemas/ExportTaskResponse' } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'409': { description: 幂等键已用于不同请求, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/api/v1/exports/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getExportTask
tags: [privacy]
security: [{ oidcBearer: [] }]
responses:
'200':
description: 查询导出状态;仅READY且未过期时现场签发短期下载地址。
content: { application/json: { schema: { $ref: '#/components/schemas/ExportTaskResponse' } } }
'401': { $ref: '#/components/responses/AuthenticationError' }
'403': { $ref: '#/components/responses/AccessDeniedError' }
'503': { description: 对象存储或签名服务暂时不可用, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/device/v2/bootstrap:
get:
operationId: getDeviceBootstrap
tags: [device]
security:
- deviceSignature: []
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- name: firmware_version
in: query
required: true
schema: { type: string, minLength: 1, maxLength: 80 }
- name: board_rev
in: query
schema: { type: string, maxLength: 80 }
- name: rtc_sdk_version
in: query
schema: { type: string, maxLength: 80 }
- name: codec
in: query
schema: { type: string, maxLength: 40 }
- name: sample_rate
in: query
schema: { type: integer, minimum: 1 }
- name: device_time
in: query
required: true
schema: { type: string, format: date-time }
- name: network
in: query
schema: { type: string, maxLength: 80 }
responses:
'200':
description: 返回可信设备状态、服务器时间、绑定和最低安全版本
content:
application/json:
schema: { $ref: '#/components/schemas/DeviceBootstrapResponse' }
'400':
description: 启动参数不正确
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'401':
description: 设备签名无效、过期、重放或设备已吊销
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 设备身份依赖暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
/device/v2/config:
get:
operationId: getDeviceConfig
tags: [device]
security:
- deviceSignature: []
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- name: If-None-Match
in: header
required: false
schema: { type: string }
description: 已缓存配置的强ETag;匹配时返回304。
responses:
'200':
description: 返回设备期望配置及当前绑定
headers:
ETag:
schema: { type: string }
description: 配置版本强ETag。
content:
application/json:
schema: { $ref: '#/components/schemas/DeviceConfigResponse' }
'304':
description: 配置未变化
'401':
description: 设备身份验证失败
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 配置服务暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
/device/v2/commands:
get:
operationId: pullDeviceCommands
tags: [device]
security: [{ deviceSignature: [] }]
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 20, default: 10 } }
responses:
'200': { description: 返回未过期的待执行命令并记录投递次数, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceCommandDeliveryListResponse' } } } }
'401': { description: 设备身份验证失败, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'503': { description: 命令服务暂时不可用, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/device/v2/commands/{id}/ack:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: acknowledgeDeviceCommand
tags: [device]
security: [{ deviceSignature: [] }]
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceCommandAckRequest' } } } }
responses:
'200': { description: 回执已保存, content: { application/json: { schema: { $ref: '#/components/schemas/DeviceCommandDeliveryResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { description: 设备身份验证失败, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'409': { description: 命令不存在、已过期或状态冲突, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
/device/v2/firmware-releases/{id}/download:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getDeviceFirmwareDownload
tags: [device, firmware]
security: [{ deviceSignature: [] }]
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
responses:
'200': { description: 仅向当前灰度目标签发5分钟私有下载地址 }
'401': { description: 设备身份验证失败 }
'403': { description: 设备不属于该批次或版本不可用 }
/device/v2/conversations/{id}/upload-batches:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: prepareMediaUploadBatch
tags: [device, media]
description: 设备提交near/far录音分片清单;业务API仅返回单对象短期PUT地址,不接收录音字节。
security: [{ deviceSignature: [] }]
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PrepareMediaUploadBatchRequest' } } } }
responses:
'201': { description: 返回尚未验证分片的10至20分钟单对象上传地址, content: { application/json: { schema: { $ref: '#/components/schemas/MediaUploadBatchResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { description: 设备身份验证失败 }
'403': { description: 当前归属、通话状态或原录音授权不允许上传 }
'409': { description: 幂等键或已有轨道序号对应不同文件元数据 }
/device/v2/upload-batches/{id}:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
get:
operationId: getDeviceMediaUploadBatch
tags: [device, media]
security: [{ deviceSignature: [] }]
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
responses:
'200': { description: 返回分片校验结果;只有VERIFIED分片才包含local_delete_after, content: { application/json: { schema: { $ref: '#/components/schemas/MediaUploadBatchResponse' } } } }
'401': { description: 设备身份验证失败 }
'404': { description: 批次不存在或不属于当前设备 }
/device/v2/upload-batches/{id}/complete:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: completeMediaUploadBatch
tags: [device, media]
description: 设备声明本批上传完成,平台可靠投递后台对象校验任务;重复提交不会创建重复任务。
security: [{ deviceSignature: [] }]
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
responses:
'202': { description: 批次已进入VERIFYING或已经完成, content: { application/json: { schema: { $ref: '#/components/schemas/MediaUploadBatchResponse' } } } }
'401': { description: 设备身份验证失败 }
'404': { description: 批次不存在或不属于当前设备 }
'409': { description: 批次状态冲突 }
'410': { description: 上传批次已经过期 }
/device/v2/media-segments/{id}/local-delete-ack:
parameters: [{ $ref: '#/components/parameters/ResourceID' }]
post:
operationId: acknowledgeLocalMediaDelete
tags: [device, media]
description: 设备在平台给出的local_delete_after之后删除本地密文并回报结果;该操作不删除云端已验证对象,DELETED重复回报幂等。
security: [{ deviceSignature: [] }]
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LocalMediaDeleteReceiptRequest' } } } }
responses:
'200': { description: 已保存本地删除回执, content: { application/json: { schema: { $ref: '#/components/schemas/MediaSegmentResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { description: 设备身份验证失败 }
'404': { description: 分片不存在或不属于当前设备 }
'409': { description: 分片未验证、尚未到允许删除时间或状态冲突 }
/device/v2/conversations:
post:
operationId: createDeviceConversation
tags: [device, conversation]
description: 分配房间和短期入房凭证;此步骤不启动语音智能体。
security:
- deviceSignature: []
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/CreateConversationRequest' }
responses:
'201':
description: 房间资料已分配;重复请求返回相同通话和相同确定性短期Token
headers:
Idempotency-Replayed:
schema: { type: string, enum: ['true'] }
description: 仅在返回已有幂等结果时出现。
content:
application/json:
schema: { $ref: '#/components/schemas/CreateConversationResponse' }
'400':
description: 请求或幂等键不符合契约
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'401':
description: 设备身份验证失败
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'403':
description: 缺少语音通话授权
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'409':
description: 设备已有未结束通话或幂等键冲突
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'422':
description: 背景资料准备失败;错误码为AGENT_CONTEXT_PREPARATION_FAILED,details返回已持久化的conversation_id、FAILED状态和稳定failure_code;同一幂等键重放同一结果且不会创建RTC房间
headers:
Idempotency-Replayed:
schema: { type: string, enum: ['true'] }
description: 仅在返回已有幂等失败结果时出现。
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'426':
description: 当前上报固件低于设备最低固件策略;错误码为FIRMWARE_UPDATE_REQUIRED
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'429':
description: 客户组织或设备的日/月费用额度或并发通话上限已达到;错误码为USAGE_QUOTA_EXCEEDED
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 通话创建服务暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
/device/v2/telemetry:batch:
post:
operationId: submitDeviceTelemetry
tags: [device, telemetry]
description: 当前签名设备批量上报状态、有限错误码和命令执行结果;平台以设备内event_key和sequence_no原子去重,更新设备影子、命令状态和与当前设备通话关联的异常回收信号。
security:
- deviceSignature: []
parameters:
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/DeviceTelemetryBatchRequest' }
responses:
'200':
description: 整批遥测已接收;完全相同的已有事件计入duplicate_count
headers:
Idempotency-Replayed:
schema: { type: string, enum: ['true'] }
description: 仅在返回同一幂等请求的原结果时出现。
content:
application/json:
schema: { $ref: '#/components/schemas/DeviceTelemetryBatchResponse' }
'400':
description: 请求、批量限制、事件字段或幂等键不符合契约
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'401':
description: 设备身份验证失败
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'404':
description: 事件关联的通话不存在或不属于当前设备
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'409':
description: 配置版本、命令状态、事件业务键或幂等键冲突;事件冲突详情位于error.details.conflicts
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'503':
description: 遥测服务暂时不可用
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
/device/v2/conversations/{id}:
get:
operationId: getDeviceConversationState
tags: [device, conversation]
description: 设备确认入房后读取云端权威通话状态和下一步动作;供应商永久拒绝启动或异步启动失败时返回稳定failure_code及leave_room,响应不包含供应商原始错误。
security:
- deviceSignature: []
parameters:
- name: id
in: path
required: true
schema: { type: string, format: uuid }
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
responses:
'200':
description: 返回当前设备所属通话的权威状态和设备动作
content:
application/json:
schema: { $ref: '#/components/schemas/DeviceConversationStateResponse' }
'400':
description: 通话编号不符合契约
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'401':
description: 设备身份验证失败
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'404':
description: 通话不存在或不属于当前设备
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
'503':
description: 通话状态暂时不可读取
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
/device/v2/conversations/{id}/activate:
post:
operationId: activateDeviceConversation
tags: [device, conversation]
description: 设备确认已进入指定RTC房间后,投递固定供应商语音任务。
security:
- deviceSignature: []
parameters:
- name: id
in: path
required: true
schema: { type: string, format: uuid }
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ActivateConversationRequest' }
responses:
'202':
description: 入房确认已接受;语音智能体正在启动或已经启动
content:
application/json:
schema: { $ref: '#/components/schemas/ActivateConversationResponse' }
'400':
description: 请求字段不符合契约
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'401':
description: 设备身份验证失败
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'404':
description: 通话不属于当前设备或不存在
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'409':
description: 房间、用户、配置版本、状态或幂等键冲突
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 激活服务暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
/device/v2/conversations/{id}/heartbeat:
post:
operationId: heartbeatDeviceConversation
tags: [device, conversation]
description: 按严格递增序号刷新设备在线状态和通话短期租约;重复或乱序心跳不会延长租约。
security:
- deviceSignature: []
parameters:
- name: id
in: path
required: true
schema: { type: string, format: uuid }
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/HeartbeatConversationRequest' }
responses:
'200':
description: 心跳已接受,或已按序号判定为安全重放/乱序请求
content:
application/json:
schema: { $ref: '#/components/schemas/HeartbeatConversationResponse' }
'400':
description: 心跳字段不符合契约
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'401':
description: 设备身份验证失败
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'404':
description: 通话不属于当前设备或不存在
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'409':
description: 通话状态或设备报告的配置版本冲突
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 心跳持久化服务暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
/device/v2/conversations/{id}/stop:
post:
operationId: stopDeviceConversation
tags: [device, conversation]
description: 记录设备挂断并可靠停止固定供应商任务;重复执行不产生第二个外部副作用。
security:
- deviceSignature: []
parameters:
- name: id
in: path
required: true
schema: { type: string, format: uuid }
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StopConversationRequest' }
responses:
'202':
description: 停止请求已接受,或通话已经处于停止中/终态
headers:
Idempotency-Replayed:
schema: { type: string, enum: ['true'] }
description: 仅在返回同一幂等请求的原结果时出现。
content:
application/json:
schema: { $ref: '#/components/schemas/StopConversationResponse' }
'400':
description: 请求或幂等键不符合契约
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'401':
description: 设备身份验证失败
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'404':
description: 通话不属于当前设备或不存在
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'409':
description: 当前状态或幂等键冲突
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 停止服务暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
/device/v2/conversations/{id}/turns:batch:
post:
operationId: submitDeviceConversationTurns
tags: [device, conversation, content]
description: 当供应商最终转写缺失时由当前通话所属终端批量补传终稿;平台按turn_key和sequence_no与已有供应商终稿原子去重合并,任一内容冲突会拒绝整批请求。
security:
- deviceSignature: []
parameters:
- name: id
in: path
required: true
schema: { type: string, format: uuid }
- $ref: '#/components/parameters/DeviceIdHeader'
- $ref: '#/components/parameters/DeviceTimestampHeader'
- $ref: '#/components/parameters/DeviceNonceHeader'
- $ref: '#/components/parameters/DeviceContentDigestHeader'
- $ref: '#/components/parameters/DeviceSignatureHeader'
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/DeviceTranscriptBatchRequest' }
responses:
'200':
description: 整批终稿已合并;完全相同的已有终稿计入duplicate_count而不重复保存
headers:
Idempotency-Replayed:
schema: { type: string, enum: ['true'] }
description: 仅在返回同一幂等请求的原结果时出现。
content:
application/json:
schema: { $ref: '#/components/schemas/DeviceTranscriptBatchResponse' }
'400':
description: 请求、批量限制、终稿字段或幂等键不符合契约
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'401':
description: 设备身份验证失败
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'403':
description: 当前留存策略或已撤回的文字留存授权禁止保存终稿;错误码为TRANSCRIPT_STORAGE_NOT_ALLOWED
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'404':
description: 通话不属于当前设备或不存在
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'409':
description: 通话状态、幂等键或终稿业务键内容冲突;终稿冲突详情位于error.details.conflicts
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 终稿补传服务暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
/callbacks/v1/vertc/voice-chat:
post:
operationId: receiveVoiceChatCallback
tags: [callback, conversation]
security:
- providerSignature: []
parameters:
- $ref: '#/components/parameters/ProviderTimestampHeader'
- $ref: '#/components/parameters/ProviderSignatureHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/VoiceProviderEvent' }
responses:
'200':
description: 事件已处理、忽略或判定为重复
content:
application/json:
schema: { $ref: '#/components/schemas/ProviderCallbackResponse' }
'400':
description: 回调字段不符合契约
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'401':
description: 回调签名无效或时间窗已过
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'404':
description: 固定供应商任务不存在
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'409':
description: 同一供应商事件编号对应不同正文
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
'503':
description: 回调处理暂时不可用
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
2026-08-26 21:15:03 +08:00
/callbacks/v1/platform-health:
post:
operationId: receivePlatformHealthReport
tags: [callback, operations]
description: 接收云端主机五分钟一次的脱敏健康快照;Unix时间戳和原始正文使用独立HMAC-SHA256密钥签名,完全重复的正文幂等返回原记录。
security:
- platformHealthSignature: []
parameters:
- $ref: '#/components/parameters/PlatformTimestampHeader'
- $ref: '#/components/parameters/PlatformSignatureHeader'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/PlatformHealthReport' }
responses:
'201': { description: 新健康快照已保存, content: { application/json: { schema: { $ref: '#/components/schemas/PlatformHealthReceiptResponse' } } } }
'200': { description: 完全重复的健康快照已幂等确认, content: { application/json: { schema: { $ref: '#/components/schemas/PlatformHealthReceiptResponse' } } } }
'400': { $ref: '#/components/responses/ValidationError' }
'401': { description: 签名无效或时间窗已过, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
'503': { description: 健康快照暂时无法保存, content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } } }
2026-08-26 06:41:07 +08:00
components:
securitySchemes:
oidcBearer:
type: openIdConnect
openIdConnectUrl: http://localhost:58180/realms/voice-local/.well-known/openid-configuration
2026-08-29 21:56:51 +08:00
memoryToolBearer:
type: http
scheme: bearer
bearerFormat: signed-conversation-token
description: Worker在启动s2s_hybrid任务时签发的短期令牌,固定绑定通话和供应商任务。
2026-08-26 06:41:07 +08:00
deviceSignature:
type: apiKey
in: header
name: X-Device-Signature
description: HMAC-SHA256设备签名;必须同时提交设备编号、RFC3339时间戳、随机数和正文摘要。
providerSignature:
type: apiKey
in: header
name: X-Provider-Signature
description: 供应商回调正文摘要和时间戳的HMAC-SHA256签名。
2026-08-26 21:15:03 +08:00
platformHealthSignature:
type: apiKey
in: header
name: X-Platform-Signature
description: 使用独立密钥对Unix时间戳、点号和原始健康报告正文计算的HMAC-SHA256十六进制签名,格式为sha256=摘要。
2026-08-26 06:41:07 +08:00
headers:
StrongETag:
description: 资源强版本标签,例如"v2"。
schema: { type: string, pattern: '^"v[1-9][0-9]*"$' }
responses:
ValidationError:
description: 请求字段、路径或请求头不符合契约
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
AuthenticationError:
description: 未登录、令牌无效或令牌过期
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
AccessDeniedError:
description: 当前身份在资源所属客户组织或家庭中没有所需能力
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
NotFoundError:
description: 请求的资源不存在
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
ConflictError:
description: 当前资源状态不允许执行请求
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
VersionConflictError:
description: If-Match对应的版本已不是当前版本
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
PreconditionRequiredError:
description: 修改请求缺少If-Match
content: { application/json: { schema: { $ref: '#/components/schemas/ErrorResponse' } } }
parameters:
TenantSelectionHeader:
name: X-Tenant-Id
in: header
required: false
description: 公开客户组织编号;仅用于选择范围,服务端仍验证账号映射。
schema: { type: string, format: uuid }
RequiredTenantSelectionHeader:
name: X-Tenant-Id
in: header
required: true
description: 待创建资源所属的公开客户组织编号,不能是数据库内部主键。
schema: { type: string, format: uuid }
ResourceID:
name: id
in: path
required: true
schema: { type: string, format: uuid }
IfMatchHeader:
name: If-Match
in: header
required: true
description: 最近一次读取返回的强ETag,不接受通配符或弱ETag。
schema: { type: string, pattern: '^"v[1-9][0-9]*"$' }
DeviceIdHeader:
name: X-Device-Id
in: header
required: true
schema: { type: string, format: uuid }
DeviceTimestampHeader:
name: X-Device-Timestamp
in: header
required: true
schema: { type: string, format: date-time }
DeviceNonceHeader:
name: X-Device-Nonce
in: header
required: true
schema: { type: string, minLength: 16, maxLength: 128 }
DeviceContentDigestHeader:
name: X-Device-Content-SHA256
in: header
required: true
schema: { type: string, pattern: '^[0-9a-f]{64}$' }
DeviceSignatureHeader:
name: X-Device-Signature
in: header
required: true
schema: { type: string }
IdempotencyKeyHeader:
name: Idempotency-Key
in: header
required: true
schema: { type: string, minLength: 16, maxLength: 128 }
OpsAccessGrantHeader:
name: X-Ops-Access-Grant
in: header
required: true
description: 已批准且未过期的临时敏感数据访问申请公开编号。
schema: { type: string, format: uuid }
ProviderTimestampHeader:
name: X-Provider-Timestamp
in: header
required: true
schema: { type: string, format: date-time }
ProviderSignatureHeader:
name: X-Provider-Signature
in: header
required: true
schema: { type: string }
2026-08-26 21:15:03 +08:00
PlatformTimestampHeader:
name: X-Platform-Timestamp
in: header
required: true
schema: { type: string, pattern: '^[0-9]{10}$' }
PlatformSignatureHeader:
name: X-Platform-Signature
in: header
required: true
schema: { type: string, pattern: '^sha256=[a-f0-9]{64}$' }
2026-08-26 06:41:07 +08:00
schemas:
CreateOpsConfigVersionRequest:
type: object
additionalProperties: false
required: [config_key, display_name, config_kind, payload, secret_refs, change_summary]
properties:
config_key: { type: string, pattern: '^[a-z][a-z0-9_.-]{2,99}$', description: 运营定义的稳定版本族标识;AGENT_BUNDLE和ROUTING无需使用保留键名,活动投放会按配置类型、范围优先级及激活时间参与新通话选择。 }
display_name: { type: string, minLength: 1, maxLength: 200 }
config_kind: { type: string, enum: [PERSONA, VOICE, MODEL, ROUTING, AGENT_BUNDLE] }
payload: { type: object, additionalProperties: true, description: 最大64KiB;禁止secret、password、token、private_key、api_key和credential等敏感键。AGENT_BUNDLE的四个组件字段必须是当前客户组织内相应类型且曾发布的不可变配置版本UUID。 }
secret_refs: { type: object, additionalProperties: { type: string }, description: 只保存KMS或受控配置引用,不保存明文密钥。 }
change_summary: { type: string, minLength: 1, maxLength: 500 }
OpsConfigTransitionRequest:
type: object
additionalProperties: false
required: [reason, rollout]
properties:
reason: { type: string, minLength: 1, maxLength: 255 }
rollout: { $ref: '#/components/schemas/OpsConfigRolloutRequest' }
OpsConfigRolloutRequest:
type: object
additionalProperties: false
required: [scope_type, rollout_percent, max_concurrent_calls]
properties:
scope_type: { type: string, enum: [TENANT, SUBJECT, DEVICE_GROUP] }
scope_id: { type: string, format: uuid, description: SUBJECT或DEVICE_GROUP必填;TENANT必须省略。 }
rollout_percent: { type: integer, minimum: 1, maximum: 100, description: SUBJECT固定为100。 }
max_concurrent_calls: { type: integer, minimum: 1, maximum: 100000 }
OpsReasonRequest:
type: object
additionalProperties: false
required: [reason]
properties:
reason: { type: string, minLength: 1, maxLength: 500 }
OpsConfigRollout:
type: object
additionalProperties: false
required: [id, config_version_id, config_key, scope_type, rollout_percent, max_concurrent_calls, status, reason, activated_by, activated_at, row_version]
properties:
id: { type: string, format: uuid }
config_version_id: { type: string, format: uuid }
config_key: { type: string }
scope_type: { type: string, enum: [TENANT, SUBJECT, DEVICE_GROUP] }
scope_id: { type: string, format: uuid }
rollout_percent: { type: integer, minimum: 1, maximum: 100 }
max_concurrent_calls: { type: integer, minimum: 1, maximum: 100000 }
status: { type: string, enum: [ACTIVE, PAUSED, ENDED] }
reason: { type: string }
activated_by: { type: string, format: uuid }
activated_at: { type: string, format: date-time }
paused_at: { type: string, format: date-time }
ended_at: { type: string, format: date-time }
row_version: { type: integer, format: int64, minimum: 1 }
OpsConfigRolloutListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/OpsConfigRollout' } }
OpsConfigRolloutListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsConfigRolloutListData' }
OpsConfigRolloutResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsConfigRollout' }
CreateOpsConfigEvaluationRequest:
type: object
additionalProperties: false
required: [suite_version, result, metrics, report_ref]
properties:
evidence_type: { type: string, enum: [GENERIC, AGENT_QUALITY_V1], default: GENERIC, description: AGENT_QUALITY_V1只能登记到AGENT_BUNDLE,并要求标准Agent评测指标;指标中的config_version_id和model_config_ref必须绑定目标组合及其模型组件。 }
suite_version: { type: string, minLength: 1, maxLength: 100 }
result: { type: string, enum: [PASSED, FAILED] }
metrics: { type: object, additionalProperties: true, description: 最大32KiB的离线评测指标快照。 }
report_ref: { type: string, minLength: 1, maxLength: 300 }
OpsConfigEvaluation:
type: object
additionalProperties: false
required: [id, config_version_id, evidence_type, suite_version, result, metrics, report_ref, evaluated_by, evaluated_at]
properties:
id: { type: string, format: uuid }
config_version_id: { type: string, format: uuid }
evidence_type: { type: string, enum: [GENERIC, AGENT_QUALITY_V1] }
suite_version: { type: string }
result: { type: string, enum: [PASSED, FAILED] }
metrics: { type: object, additionalProperties: true }
report_ref: { type: string }
evaluated_by: { type: string, format: uuid }
evaluated_at: { type: string, format: date-time }
OpsConfigEvaluationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsConfigEvaluation' }
OpsConfigEvaluationListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/OpsConfigEvaluation' } }
OpsConfigEvaluationListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsConfigEvaluationListData' }
CreateOpsResourceReferenceRequest:
type: object
additionalProperties: false
required: [resource_type, reference_name, display_name, verified_at]
properties:
resource_type: { type: string, enum: [PROVIDER_CREDENTIAL, VOICE_RESOURCE, MODEL_RESOURCE, CERTIFICATE] }
reference_name: { type: string, pattern: '^[A-Za-z][A-Za-z0-9_.:/-]{2,199}$' }
display_name: { type: string, minLength: 1, maxLength: 200 }
verified_at: { type: string, format: date-time }
expires_at: { type: string, format: date-time, description: CERTIFICATE类型必填且必须晚于verified_at;其他类型必须省略。 }
OpsResourceReference:
type: object
additionalProperties: false
required: [id, tenant_id, resource_type, reference_name, display_name, status, verified_at, created_by, row_version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
resource_type: { type: string, enum: [PROVIDER_CREDENTIAL, VOICE_RESOURCE, MODEL_RESOURCE, CERTIFICATE] }
reference_name: { type: string }
display_name: { type: string }
status: { type: string, enum: [ACTIVE, REVOKED] }
verified_at: { type: string, format: date-time }
last_rotated_at: { type: string, format: date-time }
expires_at: { type: string, format: date-time }
created_by: { type: string, format: uuid }
row_version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
OpsResourceReferenceResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsResourceReference' }
OpsResourceReferenceListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/OpsResourceReference' } }
OpsResourceReferenceListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsResourceReferenceListData' }
IntegrationIssueStatus:
type: string
enum: [OPEN, IN_PROGRESS, RESOLVED, VERIFIED, CLOSED]
IntegrationIssueSeverity:
type: string
enum: [LOW, MEDIUM, HIGH, CRITICAL]
CreateIntegrationIssueRequest:
type: object
additionalProperties: false
required: [phenomenon, severity, occurred_at, responsible_party]
properties:
phenomenon: { type: string, minLength: 1, maxLength: 2000 }
severity: { $ref: '#/components/schemas/IntegrationIssueSeverity' }
device_id: { type: string, format: uuid }
conversation_id: { type: string, format: uuid }
occurred_at: { type: string, format: date-time }
request_id: { type: string, minLength: 3, maxLength: 128, pattern: '^[A-Za-z0-9][A-Za-z0-9_.:/-]{2,127}$' }
responsible_party: { type: string, minLength: 1, maxLength: 120 }
UpdateIntegrationIssueRequest:
type: object
additionalProperties: false
minProperties: 1
properties:
status: { $ref: '#/components/schemas/IntegrationIssueStatus' }
severity: { $ref: '#/components/schemas/IntegrationIssueSeverity' }
responsible_party: { type: string, minLength: 1, maxLength: 120 }
resolution_result: { type: string, maxLength: 4000 }
root_cause: { type: string, maxLength: 4000, description: 根因结论,不得粘贴字幕、录音、凭据或带签名下载地址。 }
fixed_version: { type: string, maxLength: 128, description: 包含修复的候选版本或不可变构建标识。 }
regression_conclusion: { type: string, maxLength: 4000 }
regression_evidence: { type: string, maxLength: 4000, description: 请求关联号、脱敏诊断包编号和重复次数等可复核证据。 }
IntegrationIssue:
type: object
additionalProperties: false
required: [id, tenant_id, phenomenon, severity, occurred_at, responsible_party, status, created_by, updated_by, version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
phenomenon: { type: string }
severity: { $ref: '#/components/schemas/IntegrationIssueSeverity' }
device_id: { type: string, format: uuid }
conversation_id: { type: string, format: uuid }
occurred_at: { type: string, format: date-time }
request_id: { type: string }
responsible_party: { type: string }
status: { $ref: '#/components/schemas/IntegrationIssueStatus' }
resolution_result: { type: string }
root_cause: { type: string }
fixed_version: { type: string }
regression_conclusion: { type: string }
regression_evidence: { type: string }
created_by: { type: string, format: uuid }
updated_by: { type: string, format: uuid }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
IntegrationIssueResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/IntegrationIssue' }
IntegrationIssueListData:
type: object
required: [items, summary]
properties:
items: { type: array, maxItems: 100, items: { $ref: '#/components/schemas/IntegrationIssue' } }
summary: { $ref: '#/components/schemas/IntegrationIssueSummary' }
IntegrationIssueSummary:
type: object
additionalProperties: false
required: [total, open, critical_open, high_open, release_blocking, release_gate_satisfied]
properties:
total: { type: integer, format: int64, minimum: 0 }
open: { type: integer, format: int64, minimum: 0, description: 所有未关闭问题数。 }
critical_open: { type: integer, format: int64, minimum: 0 }
high_open: { type: integer, format: int64, minimum: 0 }
release_blocking: { type: integer, format: int64, minimum: 0, description: 未关闭的CRITICAL或HIGH问题数。 }
release_gate_satisfied: { type: boolean, description: 仅表示高严重度问题门禁,不替代其他生产发布门禁。 }
IntegrationIssueListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/IntegrationIssueListData' }
OpsDiagnosticReasonRequest:
type: object
additionalProperties: false
required: [reason]
properties:
reason: { type: string, minLength: 1, maxLength: 500 }
OpsDiagnosticRecord:
type: object
additionalProperties: false
required: [device_id, device_status, device_online, desired_config_revision, provider_start_attempts, provider_stop_attempts, provider_notification_count]
properties:
device_id: { type: string, format: uuid }
device_status: { type: string }
device_online: { type: boolean }
firmware_version: { type: string }
desired_config_revision: { type: integer, format: int64, minimum: 1 }
reported_config_revision: { type: integer, format: int64, minimum: 0 }
last_device_error_code: { type: string }
last_device_error_at: { type: string, format: date-time }
conversation_id: { type: string, format: uuid }
conversation_status: { type: string }
conversation_failure_code: { type: string, description: 通话稳定失败码;context_preparation_failed与设备创建通话错误details中的failure_code一致。 }
allocation_expires_at: { type: string, format: date-time }
credential_issued_at: { type: string, format: date-time, description: 短期入房凭证签发时间;不返回凭证正文 }
credential_expires_at: { type: string, format: date-time, description: 短期入房凭证过期时间 }
room_id: { type: string }
provider: { type: string }
provider_task_ref: { type: string }
provider_task_status: { type: string }
provider_start_attempts: { type: integer, minimum: 0 }
provider_stop_attempts: { type: integer, minimum: 0 }
provider_notification_count: { type: integer, format: int64, minimum: 0 }
last_provider_event: { type: string }
last_provider_event_status: { type: string }
last_provider_event_at: { type: string, format: date-time }
last_request_id: { type: string }
timings: { $ref: '#/components/schemas/OpsDiagnosticTimings' }
OpsDiagnosticTimings:
type: object
additionalProperties: false
required: [conversation_created_at]
properties:
conversation_created_at: { type: string, format: date-time }
room_issued_at: { type: string, format: date-time }
device_activated_at: { type: string, format: date-time }
agent_active_at: { type: string, format: date-time }
stop_requested_at: { type: string, format: date-time }
conversation_ended_at: { type: string, format: date-time }
room_issue_ms: { type: integer, format: int64, minimum: 0, description: 创建通话至房间资料签发耗时 }
device_join_ms: { type: integer, format: int64, minimum: 0, description: 房间资料签发至设备确认入房耗时 }
agent_start_ms: { type: integer, format: int64, minimum: 0, description: 设备确认入房至供应商智能体活动耗时 }
agent_stop_ms: { type: integer, format: int64, minimum: 0, description: 发起停止至通话终态耗时 }
total_ms: { type: integer, format: int64, minimum: 0, description: 通话创建至终态总耗时 }
OpsDiagnosticSearchData:
type: object
required: [items]
properties:
items: { type: array, maxItems: 50, items: { $ref: '#/components/schemas/OpsDiagnosticRecord' } }
OpsDiagnosticSearchResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsDiagnosticSearchData' }
OpsExternalDependency:
type: object
additionalProperties: false
required: [service_name, dependency, status, checked_at, latency_ms, probe_interval_ms, consecutive_failures]
properties:
service_name: { type: string, enum: [api, worker, callbacks] }
dependency: { type: string, enum: [oidc_jwks, ark_tls, volc_rtc_tls, content_safety_tls] }
status: { type: string, enum: [AVAILABLE, UNAVAILABLE] }
checked_at: { type: string, format: date-time }
last_success_at: { type: string, format: date-time }
last_failure_at: { type: string, format: date-time }
last_error_code: { type: string, enum: [TIMEOUT, CANCELED, NETWORK_ERROR, TLS_ERROR, JWKS_INVALID, PROBE_FAILED] }
latency_ms: { type: integer, format: int64, minimum: 0 }
probe_interval_ms: { type: integer, format: int64, minimum: 1, description: 当前进程配置的探针周期;客户端可在超过三倍周期未更新时标记结果过期。 }
consecutive_failures: { type: integer, minimum: 0 }
OpsExternalDependencyListData:
type: object
required: [items]
properties:
items: { type: array, maxItems: 6, items: { $ref: '#/components/schemas/OpsExternalDependency' } }
OpsExternalDependencyListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsExternalDependencyListData' }
2026-08-26 21:15:03 +08:00
PlatformHealthCheck:
type: object
additionalProperties: false
required: [name, status, value]
properties:
name: { type: string, pattern: '^[a-z][a-z0-9_.-]{1,79}$' }
status: { type: string, enum: [healthy, warning, critical] }
value: { type: string, maxLength: 256 }
PlatformHealthReport:
type: object
additionalProperties: false
required: [schema, status, observed_at, checks]
properties:
schema: { type: string, const: platform-server-health-v1 }
status: { type: string, enum: [healthy, warning, critical] }
observed_at: { type: string, format: date-time }
checks: { type: array, minItems: 1, maxItems: 64, items: { $ref: '#/components/schemas/PlatformHealthCheck' } }
PlatformHealthSnapshot:
type: object
additionalProperties: false
required: [id, schema, status, observed_at, received_at, checks]
properties:
id: { type: string, format: uuid }
schema: { type: string, const: platform-server-health-v1 }
status: { type: string, enum: [healthy, warning, critical] }
observed_at: { type: string, format: date-time }
received_at: { type: string, format: date-time }
checks: { type: array, minItems: 1, maxItems: 64, items: { $ref: '#/components/schemas/PlatformHealthCheck' } }
PlatformHealthSnapshotResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/PlatformHealthSnapshot' }
PlatformHealthReceipt:
type: object
additionalProperties: false
required: [id, status, duplicate]
properties:
id: { type: string, format: uuid }
status: { type: string, enum: [healthy, warning, critical] }
duplicate: { type: boolean }
PlatformHealthReceiptResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/PlatformHealthReceipt' }
2026-08-26 06:41:07 +08:00
OpsDiagnosticAction:
type: object
additionalProperties: false
required: [action, queued]
properties:
action: { type: string, enum: [stop_conversation, reconcile_conversation, refresh_config, revoke_device, retry_job] }
device_id: { type: string, format: uuid }
conversation_id: { type: string, format: uuid }
conversation_status: { type: string }
command_id: { type: string, format: uuid }
command_status: { type: string }
job_id: { type: string, format: uuid }
job_type: { type: string }
manual_retry_count: { type: integer, minimum: 0 }
queued: { type: boolean }
OpsDiagnosticActionResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsDiagnosticAction' }
OpsDiagnosticJob:
type: object
additionalProperties: false
required: [id, event_type, aggregate_type, status, attempt_count, manual_retry_count, created_at]
properties:
id: { type: string, format: uuid }
event_type: { type: string }
aggregate_type: { type: string }
status: { type: string, enum: [dead] }
attempt_count: { type: integer, minimum: 0 }
manual_retry_count: { type: integer, minimum: 0 }
last_error_code: { type: string }
last_manual_retry_at: { type: string, format: date-time }
created_at: { type: string, format: date-time }
OpsDiagnosticJobListData:
type: object
required: [items]
properties:
items: { type: array, maxItems: 100, items: { $ref: '#/components/schemas/OpsDiagnosticJob' } }
OpsDiagnosticJobListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsDiagnosticJobListData' }
OpsDiagnosticBundleRequest:
type: object
additionalProperties: false
required: [field, value, reason]
properties:
field: { type: string, enum: [device_id, conversation_id, room_id, provider_task_ref, request_id] }
value: { type: string, minLength: 3, maxLength: 200 }
reason: { type: string, minLength: 1, maxLength: 500 }
OpsDiagnosticBundle:
type: object
additionalProperties: false
required: [id, generated_at, search_field, search_value, redaction_policy, items]
properties:
id: { type: string, format: uuid }
generated_at: { type: string, format: date-time }
search_field: { type: string }
search_value: { type: string }
redaction_policy: { type: string, enum: [ops-diagnostic-minimal-v1] }
items: { type: array, maxItems: 50, items: { $ref: '#/components/schemas/OpsDiagnosticRecord' } }
OpsDiagnosticBundleResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsDiagnosticBundle' }
OpsAcceptanceSnapshotRequest:
type: object
additionalProperties: false
required: [candidate_version, build_digest, environment, run_type, scope, required_dependencies, reason]
properties:
candidate_version: { type: string, minLength: 1, maxLength: 128, pattern: '^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$' }
build_digest: { type: string, pattern: '^sha256:[a-fA-F0-9]{64}$', description: 候选容器镜像或不可变构建产物的SHA-256摘要。 }
environment: { type: string, enum: [LAB, STAGING, PRODUCTION] }
run_type: { type: string, enum: [REAL_DEVICE_PROVIDER, PILOT, PRODUCTION_RELEASE] }
scope: { type: string, minLength: 1, maxLength: 500, description: 本次验收覆盖的设备、客户组织或灰度范围,不填写敏感业务内容。 }
required_dependencies: { type: array, minItems: 1, maxItems: 4, uniqueItems: true, items: { type: string, enum: [oidc_jwks, ark_tls, volc_rtc_tls, content_safety_tls] } }
reason: { type: string, minLength: 1, maxLength: 255 }
OpsAcceptanceDatabaseState:
type: object
additionalProperties: false
required: [migration_version, dirty]
properties:
migration_version: { type: integer, format: int64, minimum: 0 }
dirty: { type: boolean }
2026-08-26 22:04:38 +08:00
OpsAcceptancePlatformHealthState:
type: object
additionalProperties: false
required: [state, check_count, warning_count, critical_count, gate_satisfied]
properties:
state: { type: string, enum: [CURRENT, STALE, MISSING] }
status: { type: string, enum: [healthy, warning, critical] }
observed_at: { type: string, format: date-time }
received_at: { type: string, format: date-time }
check_count: { type: integer, minimum: 0, maximum: 64 }
warning_count: { type: integer, minimum: 0, maximum: 64 }
critical_count: { type: integer, minimum: 0, maximum: 64 }
gate_satisfied: { type: boolean, description: 仅当快照未超过15分钟且综合状态及全部检查均为healthy时为true。 }
OpsAcceptanceProductionInfrastructureState:
type: object
additionalProperties: false
2026-08-26 23:30:59 +08:00
required: [applicable, deployment_profile, application_environment, identity_service_mode, application_runtime_ready, identity_service_ready, offsite_backup_ready, external_alert_receiver_ready, mock_services_disabled, gate_satisfied]
properties:
applicable: { type: boolean, description: 目标环境为PRODUCTION时为true。 }
deployment_profile: { type: string, enum: [MISSING, demo, production] }
2026-08-26 23:30:59 +08:00
application_environment: { type: string, enum: [MISSING, local, test, stage, prod, mixed] }
identity_service_mode: { type: string, enum: [MISSING, missing, development, hardened] }
application_runtime_ready: { type: boolean, description: API、Callbacks和Worker实际容器环境均为prod时为true。 }
identity_service_ready: { type: boolean, description: 身份服务未使用start-dev开发模式时为true。 }
offsite_backup_ready: { type: boolean, description: 最近主机报告证明异地备份已启用、已回读验证且未过期。 }
external_alert_receiver_ready: { type: boolean, description: 最近主机报告证明真实外部告警接收器已配置且密钥可读。 }
mock_services_disabled: { type: boolean, description: 最近主机报告证明模拟语音与模拟告警服务均未运行。 }
gate_satisfied: { type: boolean }
2026-08-26 06:41:07 +08:00
OpsAcceptanceDependencyState:
type: object
additionalProperties: false
required: [service_name, dependency, status, latency_ms, probe_interval_ms, consecutive_failures, fresh, gate_satisfied]
properties:
service_name: { type: string, enum: [api, worker] }
dependency: { type: string, enum: [oidc_jwks, ark_tls, volc_rtc_tls, content_safety_tls] }
status: { type: string, enum: [AVAILABLE, UNAVAILABLE, MISSING] }
checked_at: { type: string, format: date-time }
last_success_at: { type: string, format: date-time }
last_failure_at: { type: string, format: date-time }
last_error_code: { type: string, maxLength: 80 }
latency_ms: { type: integer, format: int64, minimum: 0 }
probe_interval_ms: { type: integer, format: int64, minimum: 0 }
consecutive_failures: { type: integer, minimum: 0 }
fresh: { type: boolean }
gate_satisfied: { type: boolean }
OpsAcceptanceOutboxState:
type: object
additionalProperties: false
required: [pending, processing, dead]
properties:
pending: { type: integer, format: int64, minimum: 0 }
processing: { type: integer, format: int64, minimum: 0 }
dead: { type: integer, format: int64, minimum: 0 }
OpsAcceptanceAlertState:
type: object
additionalProperties: false
required: [critical_open, high_open, blocking, blocking_items, blocking_items_truncated]
properties:
critical_open: { type: integer, format: int64, minimum: 0 }
high_open: { type: integer, format: int64, minimum: 0 }
blocking: { type: integer, format: int64, minimum: 0 }
blocking_items: { type: array, maxItems: 100, items: { $ref: '#/components/schemas/OpsAcceptanceBlockingAlert' } }
blocking_items_truncated: { type: boolean, description: true表示阻断告警超过100条,快照只携带最早的100条定位信息。 }
OpsAcceptanceBlockingAlert:
type: object
additionalProperties: false
required: [id, rule_code, severity, status, resource_state, first_detected_at, last_detected_at]
properties:
id: { type: string, format: uuid }
rule_code: { type: string }
severity: { type: string, enum: [CRITICAL, HIGH] }
status: { type: string, enum: [OPEN, ACKNOWLEDGED, MITIGATED, SILENCED] }
resource_type: { type: string }
resource_id: { type: string, format: uuid }
resource_state: { type: string, enum: [PRESENT, MISSING, AGGREGATE, UNKNOWN], description: 仅表示快照生成时关联公开资源是否存在;MISSING不能代替人工复核和关闭。 }
first_detected_at: { type: string, format: date-time }
last_detected_at: { type: string, format: date-time }
OpsAcceptanceGate:
type: object
additionalProperties: false
required: [code, satisfied, summary]
properties:
code: { type: string, enum: [candidate_build_identified, database_migration_clean, required_dependencies_available, integration_issues_clear, outbox_clear, critical_alerts_clear, platform_health_current, production_infrastructure_ready] }
2026-08-26 06:41:07 +08:00
satisfied: { type: boolean }
summary: { type: string }
OpsAcceptanceSnapshot:
type: object
additionalProperties: false
required: [id, generated_at, tenant_id, candidate_version, build_digest, environment, run_type, scope, redaction_policy, runtime_build, database, integration_issues, external_dependencies, outbox, alerts, platform_health, production_infrastructure, gates, overall_gate_satisfied, disclaimer]
2026-08-26 06:41:07 +08:00
properties:
id: { type: string, format: uuid }
generated_at: { type: string, format: date-time }
tenant_id: { type: string, format: uuid }
candidate_version: { type: string }
build_digest: { type: string }
environment: { type: string, enum: [LAB, STAGING, PRODUCTION] }
run_type: { type: string, enum: [REAL_DEVICE_PROVIDER, PILOT, PRODUCTION_RELEASE] }
scope: { type: string }
redaction_policy: { type: string, enum: [ops-acceptance-minimal-v1] }
runtime_build: { $ref: '#/components/schemas/BuildInfo' }
database: { $ref: '#/components/schemas/OpsAcceptanceDatabaseState' }
integration_issues: { $ref: '#/components/schemas/IntegrationIssueSummary' }
2026-08-26 22:04:38 +08:00
external_dependencies: { type: array, minItems: 1, maxItems: 4, items: { $ref: '#/components/schemas/OpsAcceptanceDependencyState' } }
2026-08-26 06:41:07 +08:00
outbox: { $ref: '#/components/schemas/OpsAcceptanceOutboxState' }
alerts: { $ref: '#/components/schemas/OpsAcceptanceAlertState' }
2026-08-26 22:04:38 +08:00
platform_health: { $ref: '#/components/schemas/OpsAcceptancePlatformHealthState' }
production_infrastructure: { $ref: '#/components/schemas/OpsAcceptanceProductionInfrastructureState' }
gates: { type: array, minItems: 8, maxItems: 8, items: { $ref: '#/components/schemas/OpsAcceptanceGate' } }
2026-08-26 06:41:07 +08:00
overall_gate_satisfied: { type: boolean }
disclaimer: { type: string }
OpsAcceptanceSnapshotResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsAcceptanceSnapshot' }
OpsPilotDailySnapshotRequest:
type: object
additionalProperties: false
required: [candidate_version, build_digest, local_date, timezone, reason]
properties:
candidate_version: { type: string, minLength: 1, maxLength: 128, pattern: '^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$' }
build_digest: { type: string, pattern: '^sha256:[a-fA-F0-9]{64}$' }
local_date: { type: string, format: date, description: 统计业务日期,不允许晚于指定时区的当前日期。 }
timezone: { type: string, minLength: 1, maxLength: 80, example: Asia/Shanghai, description: IANA时区名称,用于确定自然日边界和夏令时。 }
reason: { type: string, minLength: 1, maxLength: 255 }
OpsPilotDeviceState:
type: object
additionalProperties: false
required: [bound, eligible, quarantined, revoked, online, offline, reported_during_day]
properties:
bound: { type: integer, format: int64, minimum: 0 }
eligible: { type: integer, format: int64, minimum: 0, description: 当前已绑定且状态为registered的设备。 }
quarantined: { type: integer, format: int64, minimum: 0 }
revoked: { type: integer, format: int64, minimum: 0 }
online: { type: integer, format: int64, minimum: 0, description: 生成时刻可用设备中的在线数量。 }
offline: { type: integer, format: int64, minimum: 0, description: 生成时刻可用设备中的离线数量。 }
reported_during_day: { type: integer, format: int64, minimum: 0, description: 所选自然日内至少有一次最新孪生上报时间的当前可用设备数量。 }
OpsPilotCountByStatus:
type: object
additionalProperties: false
required: [status, count]
properties:
status: { type: string, enum: [PREPARING, ROOM_ISSUED, STARTING_AGENT, ACTIVE, STOPPING, COMPLETED, FAILED, EXPIRED] }
count: { type: integer, format: int64, minimum: 0 }
OpsPilotConversationState:
type: object
additionalProperties: false
required: [total, statuses]
properties:
total: { type: integer, format: int64, minimum: 0, description: 所选自然日内创建的通话数量。 }
statuses: { type: array, minItems: 8, maxItems: 8, items: { $ref: '#/components/schemas/OpsPilotCountByStatus' } }
OpsPilotProviderState:
type: object
additionalProperties: false
required: [provider, current_status, consecutive_failures, failed_events_during_day, failed_calls_during_day, notification_backlog]
properties:
provider: { type: string }
current_status: { type: string, enum: [AVAILABLE, DEGRADED, UNAVAILABLE, UNKNOWN] }
consecutive_failures: { type: integer, format: int64, minimum: 0 }
failed_events_during_day: { type: integer, format: int64, minimum: 0 }
failed_calls_during_day: { type: integer, format: int64, minimum: 0, description: 所选自然日内首次进入FAILED状态且关联该供应商的通话数。 }
notification_backlog: { type: integer, format: int64, minimum: 0, description: 生成时刻待处理或失败的供应商通知数量。 }
OpsPilotUploadState:
type: object
additionalProperties: false
required: [created_during_day, completed_during_day, failed_during_day, open_batches, pending_segments, rejected_segments]
properties:
created_during_day: { type: integer, format: int64, minimum: 0 }
completed_during_day: { type: integer, format: int64, minimum: 0 }
failed_during_day: { type: integer, format: int64, minimum: 0, description: 所选自然日内最后更新且当前为FAILED的批次数量。 }
open_batches: { type: integer, format: int64, minimum: 0 }
pending_segments: { type: integer, format: int64, minimum: 0 }
rejected_segments: { type: integer, format: int64, minimum: 0 }
OpsPilotAlertState:
type: object
additionalProperties: false
required: [opened_during_day, resolved_during_day, open, high_open, critical_open]
properties:
opened_during_day: { type: integer, format: int64, minimum: 0 }
resolved_during_day: { type: integer, format: int64, minimum: 0 }
open: { type: integer, format: int64, minimum: 0 }
high_open: { type: integer, format: int64, minimum: 0 }
critical_open: { type: integer, format: int64, minimum: 0 }
OpsPilotCostState:
type: object
additionalProperties: false
required: [currency, cost_micros, line_count]
properties:
currency: { type: string, minLength: 3, maxLength: 3 }
cost_micros: { type: integer, format: int64, minimum: 0 }
line_count: { type: integer, format: int64, minimum: 0 }
OpsPilotDailySnapshot:
type: object
additionalProperties: false
required: [id, generated_at, tenant_id, candidate_version, build_digest, local_date, timezone, window_start, window_end, redaction_policy, devices, conversations, providers, uploads, alerts, costs, disclaimer]
properties:
id: { type: string, format: uuid }
generated_at: { type: string, format: date-time }
tenant_id: { type: string, format: uuid }
candidate_version: { type: string }
build_digest: { type: string, pattern: '^sha256:[a-f0-9]{64}$' }
local_date: { type: string, format: date }
timezone: { type: string }
window_start: { type: string, format: date-time }
window_end: { type: string, format: date-time }
redaction_policy: { type: string, enum: [ops-pilot-daily-minimal-v1] }
devices: { $ref: '#/components/schemas/OpsPilotDeviceState' }
conversations: { $ref: '#/components/schemas/OpsPilotConversationState' }
providers: { type: array, items: { $ref: '#/components/schemas/OpsPilotProviderState' } }
uploads: { $ref: '#/components/schemas/OpsPilotUploadState' }
alerts: { $ref: '#/components/schemas/OpsPilotAlertState' }
costs: { type: array, items: { $ref: '#/components/schemas/OpsPilotCostState' } }
disclaimer: { type: string }
OpsPilotDailySnapshotResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsPilotDailySnapshot' }
OpsPilotWeeklySnapshotRequest:
type: object
additionalProperties: false
required: [candidate_version, build_digest, week_start, timezone, reason]
properties:
candidate_version: { type: string, minLength: 1, maxLength: 128, pattern: '^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$' }
build_digest: { type: string, pattern: '^sha256:[a-fA-F0-9]{64}$' }
week_start: { type: string, format: date, description: 周一的业务日期,不允许晚于指定时区的当前日期。 }
timezone: { type: string, minLength: 1, maxLength: 80, example: Asia/Shanghai, description: IANA时区名称,用于确定七个自然日及夏令时边界。 }
reason: { type: string, minLength: 1, maxLength: 255 }
OpsPilotWeeklyContentReview:
type: object
additionalProperties: false
required: [stories_generated, stories_review_touched, stories_manually_revised, manual_revision_rate_available, manual_revision_rate_basis_points, stories_confirmed, stories_rejected, story_confirmation_rate_available, story_confirmation_rate_basis_points, memories_created, memory_revisions, current_memory_index_pending, current_memory_index_failed]
properties:
stories_generated: { type: integer, format: int64, minimum: 0 }
stories_review_touched: { type: integer, format: int64, minimum: 0, description: 周内发生修订、确认或拒绝动作的去重故事数。 }
stories_manually_revised: { type: integer, format: int64, minimum: 0, description: 周内发生用户修订的去重故事数。 }
manual_revision_rate_available: { type: boolean, description: false表示本周没有审核触达故事,比例不可计算。 }
manual_revision_rate_basis_points: { type: integer, format: int64, minimum: 0, maximum: 10000, description: 人工修订故事数除以审核触达故事数,单位为基点;仅在available为true时使用。 }
stories_confirmed: { type: integer, format: int64, minimum: 0, description: 周内成功确认动作数。 }
stories_rejected: { type: integer, format: int64, minimum: 0, description: 周内成功拒绝动作数。 }
story_confirmation_rate_available: { type: boolean, description: false表示本周没有确认或拒绝决策,比例不可计算。 }
story_confirmation_rate_basis_points: { type: integer, format: int64, minimum: 0, maximum: 10000, description: 确认数除以确认与拒绝之和,单位为基点;仅在available为true时使用。 }
memories_created: { type: integer, format: int64, minimum: 0, description: 周内确认的首版正式记忆数。 }
memory_revisions: { type: integer, format: int64, minimum: 0, description: 周内确认的后续记忆版本数。 }
current_memory_index_pending: { type: integer, format: int64, minimum: 0 }
current_memory_index_failed: { type: integer, format: int64, minimum: 0 }
OpsPilotWeeklyCountByType:
type: object
additionalProperties: false
required: [type, count]
properties:
type: { type: string, enum: [ACCESS, CORRECTION, CONSENT_WITHDRAWAL, DELETE] }
count: { type: integer, format: int64, minimum: 0 }
OpsPilotWeeklyCountByStatus:
type: object
additionalProperties: false
required: [status, count]
properties:
status: { type: string, enum: [SUBMITTED, VERIFYING, EXECUTING, COMPLETED, PARTIAL_FAILED] }
count: { type: integer, format: int64, minimum: 0 }
OpsPilotWeeklyPrivacyState:
type: object
additionalProperties: false
required: [requests_created_during_week, by_type, by_status, current_open, current_partial_failed]
properties:
requests_created_during_week: { type: integer, format: int64, minimum: 0 }
by_type: { type: array, minItems: 4, maxItems: 4, items: { $ref: '#/components/schemas/OpsPilotWeeklyCountByType' } }
by_status: { type: array, minItems: 5, maxItems: 5, items: { $ref: '#/components/schemas/OpsPilotWeeklyCountByStatus' } }
current_open: { type: integer, format: int64, minimum: 0, description: 生成时刻所有非COMPLETED请求数,不限于所选周。 }
current_partial_failed: { type: integer, format: int64, minimum: 0 }
OpsPilotWeeklyFirmwareVersion:
type: object
additionalProperties: false
required: [model, firmware_version, device_count]
properties:
model: { type: string }
firmware_version: { type: string, description: 设备尚未上报时为UNREPORTED。 }
device_count: { type: integer, format: int64, minimum: 0 }
OpsPilotWeeklyConfigState:
type: object
additionalProperties: false
required: [eligible_devices, aligned, drifted, unreported, active_rollouts, paused_rollouts]
properties:
eligible_devices: { type: integer, format: int64, minimum: 0 }
aligned: { type: integer, format: int64, minimum: 0 }
drifted: { type: integer, format: int64, minimum: 0 }
unreported: { type: integer, format: int64, minimum: 0 }
active_rollouts: { type: integer, format: int64, minimum: 0 }
paused_rollouts: { type: integer, format: int64, minimum: 0 }
OpsPilotWeeklyExternalEvidence:
type: object
additionalProperties: false
required: [code, status, reason]
properties:
code: { type: string, enum: [complaints] }
status: { type: string, enum: [REQUIRED] }
reason: { type: string }
OpsPilotWeeklySnapshot:
type: object
additionalProperties: false
required: [id, generated_at, tenant_id, candidate_version, build_digest, week_start, timezone, window_start, window_end, is_complete, redaction_policy, content_review, privacy, firmware_versions, config, external_evidence, disclaimer]
properties:
id: { type: string, format: uuid }
generated_at: { type: string, format: date-time }
tenant_id: { type: string, format: uuid }
candidate_version: { type: string }
build_digest: { type: string, pattern: '^sha256:[a-f0-9]{64}$' }
week_start: { type: string, format: date }
timezone: { type: string }
window_start: { type: string, format: date-time }
window_end: { type: string, format: date-time }
is_complete: { type: boolean, description: false表示所选自然周尚未结束,结果只能作为周中快照。 }
redaction_policy: { type: string, enum: [ops-pilot-weekly-minimal-v1] }
content_review: { $ref: '#/components/schemas/OpsPilotWeeklyContentReview' }
privacy: { $ref: '#/components/schemas/OpsPilotWeeklyPrivacyState' }
firmware_versions: { type: array, items: { $ref: '#/components/schemas/OpsPilotWeeklyFirmwareVersion' } }
config: { $ref: '#/components/schemas/OpsPilotWeeklyConfigState' }
external_evidence: { type: array, minItems: 1, items: { $ref: '#/components/schemas/OpsPilotWeeklyExternalEvidence' } }
disclaimer: { type: string }
OpsPilotWeeklySnapshotResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsPilotWeeklySnapshot' }
OpsSensitiveAccessCapability:
type: string
enum: [TRANSCRIPT_READ, RECORDING_PLAY]
CreateOpsSensitiveAccessRequest:
type: object
additionalProperties: false
required: [conversation_id, capabilities, reason, expires_at]
properties:
conversation_id: { type: string, format: uuid }
capabilities: { type: array, minItems: 1, maxItems: 2, uniqueItems: true, items: { $ref: '#/components/schemas/OpsSensitiveAccessCapability' } }
reason: { type: string, minLength: 1, maxLength: 500 }
expires_at: { type: string, format: date-time, description: 至少晚于当前时间5分钟且不超过4小时。 }
ReviewOpsSensitiveAccessRequest:
type: object
additionalProperties: false
required: [decision, reason]
properties:
decision: { type: string, enum: [APPROVE, REJECT] }
reason: { type: string, minLength: 1, maxLength: 500 }
OpsSensitiveAccessRequest:
type: object
additionalProperties: false
required: [id, conversation_id, requester_user_id, capabilities, reason, status, requested_expires_at, version, created_at]
properties:
id: { type: string, format: uuid }
conversation_id: { type: string, format: uuid }
requester_user_id: { type: string, format: uuid }
capabilities: { type: array, minItems: 1, maxItems: 2, uniqueItems: true, items: { $ref: '#/components/schemas/OpsSensitiveAccessCapability' } }
reason: { type: string }
status: { type: string, enum: [PENDING, APPROVED, REJECTED, REVOKED, EXPIRED] }
requested_expires_at: { type: string, format: date-time }
reviewed_by: { type: string, format: uuid }
review_reason: { type: string }
reviewed_at: { type: string, format: date-time }
revoked_at: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
OpsSensitiveAccessRequestResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsSensitiveAccessRequest' }
OpsSensitiveAccessRequestListData:
type: object
required: [items]
properties: { items: { type: array, maxItems: 200, items: { $ref: '#/components/schemas/OpsSensitiveAccessRequest' } } }
OpsSensitiveAccessRequestListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsSensitiveAccessRequestListData' }
OpsSensitiveTurn:
type: object
additionalProperties: false
required: [id, sequence_no, speaker, start_at, end_at, final_text, interrupted]
properties:
id: { type: string, format: uuid }
sequence_no: { type: integer, format: int64, minimum: 1 }
speaker: { type: string, enum: [subject, agent] }
start_at: { type: string, format: date-time }
end_at: { type: string, format: date-time }
final_text: { type: string, minLength: 1, maxLength: 20000 }
interrupted: { type: boolean }
OpsSensitiveSegment:
type: object
additionalProperties: false
required: [id, track, sequence_no, content_type, duration_ms]
properties:
id: { type: string, format: uuid }
track: { type: string, enum: [near, far] }
sequence_no: { type: integer, minimum: 0 }
content_type: { type: string }
duration_ms: { type: integer, minimum: 1 }
OpsSensitiveConversation:
type: object
additionalProperties: false
required: [conversation_id, grant_id, access_until, turns, segments]
properties:
conversation_id: { type: string, format: uuid }
grant_id: { type: string, format: uuid }
access_until: { type: string, format: date-time }
turns: { type: array, items: { $ref: '#/components/schemas/OpsSensitiveTurn' } }
segments: { type: array, items: { $ref: '#/components/schemas/OpsSensitiveSegment' } }
OpsSensitiveConversationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsSensitiveConversation' }
OpsSensitiveRecordingAccessRequest:
type: object
additionalProperties: false
required: [grant_id]
properties: { grant_id: { type: string, format: uuid } }
OpsSensitiveRecordingAccess:
type: object
additionalProperties: false
required: [segment_id, access_url, access_until]
properties:
segment_id: { type: string, format: uuid }
access_url: { type: string, format: uri }
access_until: { type: string, format: date-time }
OpsSensitiveRecordingAccessResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsSensitiveRecordingAccess' }
CreateOpsDeviceGroupRequest:
type: object
additionalProperties: false
required: [name, selector, device_ids]
properties:
name: { type: string, minLength: 1, maxLength: 200 }
selector: { type: object, additionalProperties: true, description: 保存创建时的分组说明或选择条件快照。 }
device_ids: { type: array, minItems: 1, maxItems: 1000, uniqueItems: true, items: { type: string, format: uuid } }
OpsDeviceGroup:
type: object
additionalProperties: false
required: [id, tenant_id, name, selector, status, device_ids, created_by, row_version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
name: { type: string }
selector: { type: object, additionalProperties: true }
status: { type: string, enum: [ACTIVE, ARCHIVED] }
device_ids: { type: array, items: { type: string, format: uuid } }
created_by: { type: string, format: uuid }
row_version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
OpsDeviceGroupResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsDeviceGroup' }
OpsDeviceGroupListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/OpsDeviceGroup' } }
OpsDeviceGroupListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsDeviceGroupListData' }
BillingRateInput:
type: object
additionalProperties: false
required: [usage_category, metric_code, unit, unit_price_micros]
properties:
usage_category: { type: string, enum: [RTC, END_TO_END_VOICE, ASR, LLM, TTS, STORAGE, POST_PROCESSING] }
metric_code: { type: string, pattern: '^[a-z][a-z0-9_.-]{1,79}$' }
unit: { type: string, pattern: '^[a-z][a-z0-9_.-]{1,39}$' }
unit_price_micros: { type: integer, format: int64, minimum: 0, description: 每计量单位的百万分之一货币单位价格。 }
CreateBillingPriceBookRequest:
type: object
additionalProperties: false
required: [provider, currency, source_ref, change_summary, effective_from, rates]
properties:
provider: { type: string, pattern: '^[a-z][a-z0-9_.-]{1,79}$' }
currency: { type: string, pattern: '^[A-Z]{3}$', example: CNY }
source_ref: { type: string, minLength: 1, maxLength: 300, description: 受控报价单或合同引用,不保存供应商凭据。 }
change_summary: { type: string, minLength: 1, maxLength: 500 }
effective_from: { type: string, format: date-time }
rates: { type: array, minItems: 1, maxItems: 200, items: { $ref: '#/components/schemas/BillingRateInput' } }
BillingPriceRate:
allOf:
- $ref: '#/components/schemas/BillingRateInput'
- type: object
required: [id]
properties:
id: { type: string, format: uuid }
BillingPriceBook:
type: object
additionalProperties: false
required: [id, tenant_id, provider, currency, version_no, status, source_ref, change_summary, effective_from, created_by, row_version, rates, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
provider: { type: string }
currency: { type: string, pattern: '^[A-Z]{3}$' }
version_no: { type: integer, minimum: 1 }
status: { type: string, enum: [DRAFT, PUBLISHED, RETIRED] }
source_ref: { type: string }
change_summary: { type: string }
effective_from: { type: string, format: date-time }
created_by: { type: string, format: uuid }
published_by: { type: string, format: uuid }
published_at: { type: string, format: date-time }
retired_at: { type: string, format: date-time }
row_version: { type: integer, format: int64, minimum: 1 }
rates: { type: array, items: { $ref: '#/components/schemas/BillingPriceRate' } }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
BillingPriceBookResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/BillingPriceBook' }
BillingPriceBookListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/BillingPriceBook' } }
BillingPriceBookListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/BillingPriceBookListData' }
CreateQuotaPolicyRequest:
type: object
additionalProperties: false
required: [scope_type, billing_timezone, currency, daily_limit_micros, monthly_limit_micros, max_concurrent_calls, max_call_duration_sec, in_progress_action, change_summary]
properties:
scope_type: { type: string, enum: [TENANT, DEVICE] }
scope_id: { type: string, format: uuid, description: DEVICE范围必填;TENANT范围必须省略。 }
billing_timezone: { type: string, minLength: 1, maxLength: 80, example: Asia/Shanghai }
currency: { type: string, pattern: '^[A-Z]{3}$', example: CNY }
daily_limit_micros: { type: integer, format: int64, minimum: 1 }
monthly_limit_micros: { type: integer, format: int64, minimum: 1 }
max_concurrent_calls: { type: integer, minimum: 1, maximum: 100000 }
max_call_duration_sec: { type: integer, minimum: 60, maximum: 86400 }
in_progress_action: { type: string, enum: [STOP_IMMEDIATELY, COMPLETE_CURRENT_TURN] }
change_summary: { type: string, minLength: 1, maxLength: 500 }
QuotaPolicy:
type: object
additionalProperties: false
required: [id, tenant_id, scope_type, version_no, status, billing_timezone, currency, daily_limit_micros, monthly_limit_micros, max_concurrent_calls, max_call_duration_sec, in_progress_action, change_summary, created_by, row_version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
scope_type: { type: string, enum: [TENANT, DEVICE] }
scope_id: { type: string, format: uuid }
version_no: { type: integer, minimum: 1 }
status: { type: string, enum: [ACTIVE, RETIRED] }
billing_timezone: { type: string }
currency: { type: string, pattern: '^[A-Z]{3}$' }
daily_limit_micros: { type: integer, format: int64, minimum: 1 }
monthly_limit_micros: { type: integer, format: int64, minimum: 1 }
max_concurrent_calls: { type: integer, minimum: 1 }
max_call_duration_sec: { type: integer, minimum: 60 }
in_progress_action: { type: string, enum: [STOP_IMMEDIATELY, COMPLETE_CURRENT_TURN] }
change_summary: { type: string }
created_by: { type: string, format: uuid }
retired_at: { type: string, format: date-time }
row_version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
QuotaPolicyResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/QuotaPolicy' }
QuotaPolicyListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/QuotaPolicy' } }
QuotaPolicyListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/QuotaPolicyListData' }
CostSummaryLine:
type: object
additionalProperties: false
required: [usage_category, metric_code, quantity, unit, cost_micros, currency]
properties:
usage_category: { type: string, enum: [RTC, END_TO_END_VOICE, ASR, LLM, TTS, STORAGE, POST_PROCESSING] }
metric_code: { type: string }
quantity: { type: string, pattern: '^(0|[1-9][0-9]{0,17})(\.[0-9]{1,6})?$' }
unit: { type: string }
cost_micros: { type: integer, format: int64, minimum: 0 }
currency: { type: string, pattern: '^[A-Z]{3}$' }
CostSummary:
type: object
additionalProperties: false
required: [from, to, cost_micros, currency, lines]
properties:
from: { type: string, format: date-time }
to: { type: string, format: date-time }
cost_micros: { type: integer, format: int64, minimum: 0 }
currency: { type: string, description: 无费用行时为空字符串。 }
lines: { type: array, items: { $ref: '#/components/schemas/CostSummaryLine' } }
CostSummaryResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/CostSummary' }
2026-08-29 21:56:51 +08:00
UsageOverviewScope:
type: object
additionalProperties: false
required: [tenant_id, tenant_name]
properties:
tenant_id: { type: string, format: uuid }
tenant_name: { type: string }
household_id: { type: string, format: uuid }
household_name: { type: string }
device_id: { type: string, format: uuid }
device_name: { type: string }
UsageOverviewDay:
type: object
additionalProperties: false
required: [date, duration_ms, conversation_count, cost_micros]
properties:
date: { type: string, format: date }
duration_ms: { type: integer, format: int64, minimum: 0 }
conversation_count: { type: integer, minimum: 0 }
cost_micros: { type: integer, format: int64, minimum: 0 }
UsageOverviewDevice:
type: object
additionalProperties: false
required: [id, name, household_id, household_name, duration_ms, conversation_count, cost_micros]
properties:
id: { type: string, format: uuid }
name: { type: string }
household_id: { type: string, format: uuid }
household_name: { type: string }
duration_ms: { type: integer, format: int64, minimum: 0 }
conversation_count: { type: integer, minimum: 0 }
cost_micros: { type: integer, format: int64, minimum: 0 }
UsageOverviewConversation:
type: object
additionalProperties: false
required: [id, household_id, household_name, device_id, device_name, subject_name, status, started_at, duration_ms, cost_micros]
properties:
id: { type: string, format: uuid }
household_id: { type: string, format: uuid }
household_name: { type: string }
device_id: { type: string, format: uuid }
device_name: { type: string }
subject_name: { type: string }
status: { type: string }
started_at: { type: string, format: date-time }
ended_at: { type: string, format: date-time }
duration_ms: { type: integer, format: int64, minimum: 0 }
cost_micros: { type: integer, format: int64, minimum: 0 }
UsageOverview:
type: object
additionalProperties: false
required: [from, to, timezone, scope, total_duration_ms, today_duration_ms, conversation_count, average_duration_ms, active_days, current_streak_days, longest_streak_days, cost_micros, currency, cost_available, daily, devices, recent_conversations]
properties:
from: { type: string, format: date-time }
to: { type: string, format: date-time }
timezone: { type: string }
scope: { $ref: '#/components/schemas/UsageOverviewScope' }
total_duration_ms: { type: integer, format: int64, minimum: 0 }
today_duration_ms: { type: integer, format: int64, minimum: 0 }
conversation_count: { type: integer, minimum: 0 }
average_duration_ms: { type: integer, format: int64, minimum: 0 }
active_days: { type: integer, minimum: 0 }
current_streak_days: { type: integer, minimum: 0 }
longest_streak_days: { type: integer, minimum: 0 }
cost_micros: { type: integer, format: int64, minimum: 0 }
currency: { type: string, description: 没有已核价费用时为空字符串。 }
cost_available: { type: boolean }
daily: { type: array, items: { $ref: '#/components/schemas/UsageOverviewDay' } }
devices: { type: array, items: { $ref: '#/components/schemas/UsageOverviewDevice' } }
recent_conversations: { type: array, items: { $ref: '#/components/schemas/UsageOverviewConversation' } }
UsageOverviewResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/UsageOverview' }
2026-08-26 06:41:07 +08:00
AlertCategory:
type: string
enum: [BUSINESS, TECHNICAL, SECURITY, COST]
AlertSeverity:
type: string
enum: [CRITICAL, HIGH, MEDIUM, LOW]
AlertStatus:
type: string
enum: [OPEN, ACKNOWLEDGED, MITIGATED, RESOLVED, SILENCED]
CreateAlertRoutingPolicyRequest:
type: object
additionalProperties: false
required: [category, severity, receiver_group, response_minutes, escalation_after_minutes, escalation_receiver_group, runbook_ref, change_summary]
properties:
category: { $ref: '#/components/schemas/AlertCategory' }
severity: { $ref: '#/components/schemas/AlertSeverity' }
receiver_group: { type: string, minLength: 1, maxLength: 120 }
response_minutes: { type: integer, minimum: 1, maximum: 10080 }
escalation_after_minutes: { type: integer, minimum: 1, maximum: 10080, description: 不得小于响应时限。 }
escalation_receiver_group: { type: string, minLength: 1, maxLength: 120 }
runbook_ref: { type: string, minLength: 1, maxLength: 300 }
change_summary: { type: string, minLength: 1, maxLength: 500 }
AlertRoutingPolicy:
type: object
additionalProperties: false
required: [id, tenant_id, category, severity, version_no, status, receiver_group, response_minutes, escalation_after_minutes, escalation_receiver_group, runbook_ref, change_summary, created_by, row_version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
category: { $ref: '#/components/schemas/AlertCategory' }
severity: { $ref: '#/components/schemas/AlertSeverity' }
version_no: { type: integer, minimum: 1 }
status: { type: string, enum: [ACTIVE, RETIRED] }
receiver_group: { type: string }
response_minutes: { type: integer, minimum: 1 }
escalation_after_minutes: { type: integer, minimum: 1 }
escalation_receiver_group: { type: string }
runbook_ref: { type: string }
change_summary: { type: string }
created_by: { type: string, format: uuid }
retired_at: { type: string, format: date-time }
row_version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
AlertRoutingPolicyResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/AlertRoutingPolicy' }
AlertRoutingPolicyListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/AlertRoutingPolicy' } } }
CreateAlertDeliveryTestRequest:
type: object
additionalProperties: false
required: [reason]
properties:
reason: { type: string, minLength: 1, maxLength: 500, description: 仅写入运营审计,不发送给外部接收器。 }
AlertDeliveryTest:
type: object
additionalProperties: false
required: [id, test_ref, routing_policy_id, category, severity, receiver_group, runbook_ref, status, attempt_count, manual_retry_count, created_at]
properties:
id: { type: string, format: uuid, description: 投递任务公开编号;FAILED时可通过诊断任务重试接口受控重试。 }
test_ref: { type: string, format: uuid, description: 发送给接收器的联通测试关联号。 }
routing_policy_id: { type: string, format: uuid }
category: { $ref: '#/components/schemas/AlertCategory' }
severity: { $ref: '#/components/schemas/AlertSeverity' }
receiver_group: { type: string }
runbook_ref: { type: string }
status: { type: string, enum: [PENDING, PROCESSING, DELIVERED, FAILED] }
attempt_count: { type: integer, minimum: 0 }
manual_retry_count: { type: integer, minimum: 0 }
last_error_code: { type: string }
last_manual_retry_at: { type: string, format: date-time }
created_at: { type: string, format: date-time }
completed_at: { type: string, format: date-time }
dead_at: { type: string, format: date-time }
AlertDeliveryTestResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/AlertDeliveryTest' }
AlertDeliveryTestListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, maxItems: 50, items: { $ref: '#/components/schemas/AlertDeliveryTest' } } }
AlertAction:
type: object
additionalProperties: false
required: [id, action_type, actor_type, note, created_at]
properties:
id: { type: string, format: uuid }
action_type: { type: string, enum: [DETECTED, ACKNOWLEDGED, ASSIGNED, SILENCED, MITIGATED, RESOLVED, REOPENED, ESCALATED, COMMENTED] }
from_status: { $ref: '#/components/schemas/AlertStatus' }
to_status: { $ref: '#/components/schemas/AlertStatus' }
actor_type: { type: string, enum: [system, user] }
actor_user: { type: string, format: uuid }
note: { type: string }
created_at: { type: string, format: date-time }
AlertIncident:
type: object
additionalProperties: false
required: [id, rule_code, category, severity, status, fingerprint, title, summary, first_detected_at, last_detected_at, occurrence_count, row_version, actions]
properties:
id: { type: string, format: uuid }
rule_code: { type: string, pattern: '^[A-Z][A-Z0-9_]{2,99}$' }
category: { $ref: '#/components/schemas/AlertCategory' }
severity: { $ref: '#/components/schemas/AlertSeverity' }
status: { $ref: '#/components/schemas/AlertStatus' }
fingerprint: { type: string }
title: { type: string }
summary: { type: string }
resource_type: { type: string }
resource_id: { type: string, format: uuid }
request_id: { type: string }
receiver_group: { type: string }
runbook_ref: { type: string }
current_owner: { type: string, format: uuid }
first_detected_at: { type: string, format: date-time }
last_detected_at: { type: string, format: date-time }
occurrence_count: { type: integer, format: int64, minimum: 1 }
acknowledged_at: { type: string, format: date-time }
mitigated_at: { type: string, format: date-time }
resolved_at: { type: string, format: date-time }
silenced_until: { type: string, format: date-time }
escalated_at: { type: string, format: date-time }
row_version: { type: integer, format: int64, minimum: 1 }
actions: { type: array, items: { $ref: '#/components/schemas/AlertAction' } }
AlertIncidentResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/AlertIncident' }
AlertIncidentListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/AlertIncident' } } }
AlertTransitionRequest:
type: object
additionalProperties: false
required: [note]
properties: { note: { type: string, minLength: 1, maxLength: 1000 } }
CreateAlertSilenceRequest:
type: object
additionalProperties: false
required: [reason, starts_at, ends_at]
description: rule_code、category、resource_id至少填写一项。
properties:
rule_code: { type: string, pattern: '^[A-Z][A-Z0-9_]{2,99}$' }
category: { $ref: '#/components/schemas/AlertCategory' }
resource_type: { type: string, maxLength: 80 }
resource_id: { type: string, format: uuid }
matcher: { type: object, additionalProperties: true, default: {} }
reason: { type: string, minLength: 1, maxLength: 500 }
starts_at: { type: string, format: date-time }
ends_at: { type: string, format: date-time, description: 必须晚于开始时间且窗口不超过30天。 }
AlertSilence:
type: object
additionalProperties: false
required: [id, matcher, reason, starts_at, ends_at, created_by, row_version, created_at]
properties:
id: { type: string, format: uuid }
rule_code: { type: string }
category: { $ref: '#/components/schemas/AlertCategory' }
resource_type: { type: string }
resource_id: { type: string, format: uuid }
matcher: { type: object, additionalProperties: true }
reason: { type: string }
starts_at: { type: string, format: date-time }
ends_at: { type: string, format: date-time }
created_by: { type: string, format: uuid }
revoked_at: { type: string, format: date-time }
row_version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
AlertSilenceResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/AlertSilence' }
AlertSilenceListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/AlertSilence' } } }
OpsConfigVersion:
type: object
additionalProperties: false
required: [id, tenant_id, config_key, display_name, config_kind, version_no, status, payload, secret_refs, change_summary, validation_result, created_by, row_version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
config_key: { type: string }
display_name: { type: string }
config_kind: { type: string, enum: [PERSONA, VOICE, MODEL, ROUTING, AGENT_BUNDLE] }
version_no: { type: integer, minimum: 1 }
status: { type: string, enum: [DRAFT, PENDING_APPROVAL, PUBLISHED, RETIRED] }
payload: { type: object, additionalProperties: true }
secret_refs: { type: object, additionalProperties: { type: string } }
change_summary: { type: string }
validation_result: { type: object, additionalProperties: true }
created_by: { type: string, format: uuid }
submitted_by: { type: string, format: uuid }
submitted_at: { type: string, format: date-time }
approved_by: { type: string, format: uuid }
approved_at: { type: string, format: date-time }
published_by: { type: string, format: uuid }
published_at: { type: string, format: date-time }
retired_at: { type: string, format: date-time }
supersedes_id: { type: string, format: uuid }
rollback_of_id: { type: string, format: uuid }
row_version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
OpsConfigVersionResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsConfigVersion' }
OpsConfigVersionListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/OpsConfigVersion' } }
OpsConfigVersionListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsConfigVersionListData' }
CreateSharingGrantRequest:
type: object
additionalProperties: false
required: [resource_type, resource_id, grantee_user_id, permission, purpose, expires_at, login_required]
properties:
resource_type: { type: string, enum: [STORY, TRANSCRIPT, RECORDING] }
resource_id: { type: string, format: uuid }
grantee_user_id: { type: string, format: uuid, description: 同一客户组织内的活动用户公开编号。 }
permission: { type: string, enum: [VIEW_TEXT, LISTEN, DOWNLOAD, EDIT] }
purpose: { type: string, minLength: 1, maxLength: 500 }
expires_at: { type: string, format: date-time }
login_required: { type: boolean, description: false时创建匿名口令;EDIT权限必须为true。 }
EditSharedStoryRequest:
type: object
additionalProperties: false
required: [content, reason]
properties:
content: { type: string, minLength: 1, maxLength: 50000 }
reason: { type: string, minLength: 1, maxLength: 500 }
SharingGrant:
type: object
additionalProperties: false
required: [id, subject_id, resource_type, resource_id, grantee_user_id, permission, purpose, login_required, granted_by, granted_at, expires_at, version]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
resource_type: { type: string, enum: [STORY, TRANSCRIPT, RECORDING] }
resource_id: { type: string, format: uuid }
grantee_user_id: { type: string, format: uuid }
permission: { type: string, enum: [VIEW_TEXT, LISTEN, DOWNLOAD, EDIT] }
purpose: { type: string }
login_required: { type: boolean }
granted_by: { type: string, format: uuid }
granted_at: { type: string, format: date-time }
expires_at: { type: string, format: date-time }
revoked_at: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
access_token: { type: string, minLength: 32, description: 仅匿名分享的创建或幂等重放响应返回;列表接口不返回。 }
SharedTurn:
type: object
additionalProperties: false
required: [sequence_no, speaker, start_at, text, interrupted]
properties:
sequence_no: { type: integer, format: int64 }
speaker: { type: string, enum: [subject, agent] }
start_at: { type: string, format: date-time }
end_at: { type: string, format: date-time }
text: { type: string }
interrupted: { type: boolean }
SharedResource:
type: object
additionalProperties: false
required: [grant_id, resource_type, resource_id, permission]
properties:
grant_id: { type: string, format: uuid }
resource_type: { type: string, enum: [STORY, TRANSCRIPT, RECORDING] }
resource_id: { type: string, format: uuid }
permission: { type: string, enum: [VIEW_TEXT, LISTEN, DOWNLOAD, EDIT] }
title: { type: string }
text: { type: string }
turns: { type: array, maxItems: 1000, items: { $ref: '#/components/schemas/SharedTurn' } }
access_url: { type: string, format: uri }
access_until: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
revision_no: { type: integer, format: int64, minimum: 1 }
SharingGrantResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/SharingGrant' }
SharingGrantListData:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/SharingGrant' } }
SharingGrantListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/SharingGrantListData' }
SharedResourceResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/SharedResource' }
WebEvent:
type: object
additionalProperties: false
required: [id, type, household_id, resource_type, resource_id, status, occurred_at]
2026-08-26 06:41:07 +08:00
properties:
id: { type: integer, format: int64 }
type: { type: string, enum: [device.presence.changed, conversation.started, conversation.completed, conversation.failed, story.created, story.revised, media.upload.completed, export.ready, privacy_request.updated, device.command.updated] }
household_id: { type: string, format: uuid }
2026-08-26 06:41:07 +08:00
resource_type: { type: string }
resource_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
status: { type: string }
occurred_at: { type: string, format: date-time }
Liveness:
type: object
required: [status, service]
properties:
status:
type: string
const: alive
service:
type: string
Readiness:
type: object
required: [status, checks]
properties:
status:
type: string
enum: [ready, not_ready]
checks:
type: object
additionalProperties:
type: string
enum: [up, down]
BuildInfo:
type: object
required: [version, commit, build_time]
properties:
version: { type: string }
commit: { type: string }
build_time: { type: string }
Principal:
type: object
required: [issuer, subject]
properties:
issuer: { type: string, format: uri }
subject: { type: string }
display_name: { type: string }
preferred_username: { type: string }
HouseholdMembership:
type: object
required: [household_id, household_name, role, capabilities]
properties:
household_id: { type: string, format: uuid }
household_name: { type: string }
role:
type: string
enum: [owner, admin, editor, viewer]
capabilities:
type: array
items: { type: string }
Account:
type: object
2026-08-29 21:56:51 +08:00
required: [user_id, tenant_id, tenant_name, policy_version, platform_role, account_kind, display_name, household_memberships]
2026-08-26 06:41:07 +08:00
properties:
user_id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
tenant_name: { type: string }
policy_version: { type: string }
platform_role: { type: string, enum: [customer, ops_viewer, ops_operator, ops_approver, ops_admin] }
2026-08-29 21:56:51 +08:00
account_kind: { type: string, enum: [customer, operator], description: 家庭账号和运维账号的强制身份边界。 }
2026-08-26 06:41:07 +08:00
display_name: { type: string }
household_memberships:
type: array
items: { $ref: '#/components/schemas/HouseholdMembership' }
CurrentUser:
type: object
required: [identity, accounts]
properties:
identity: { $ref: '#/components/schemas/Principal' }
accounts:
type: array
items: { $ref: '#/components/schemas/Account' }
Household:
type: object
additionalProperties: false
required: [id, tenant_id, name, status, role, capabilities, version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid, description: 公开客户组织编号 }
name: { type: string, minLength: 1, maxLength: 200 }
status: { type: string, enum: [active, archived] }
role: { type: string, enum: [owner, admin, editor, viewer] }
capabilities:
type: array
items: { type: string }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
CreateHouseholdRequest:
type: object
additionalProperties: false
required: [name]
properties:
name: { type: string, minLength: 1, maxLength: 200 }
UpdateHouseholdRequest:
$ref: '#/components/schemas/CreateHouseholdRequest'
HouseholdMember:
type: object
additionalProperties: false
required: [id, user_id, display_name, role, status, joined_at, version, is_owner]
properties:
id: { type: string, format: uuid }
user_id: { type: string, format: uuid }
display_name: { type: string }
role: { type: string, enum: [owner, admin, editor, viewer] }
status: { type: string, enum: [active, removed] }
joined_at: { type: string, format: date-time }
removed_at: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
is_owner: { type: boolean }
UpdateHouseholdMemberRequest:
type: object
additionalProperties: false
required: [role]
properties:
role: { type: string, enum: [admin, editor, viewer] }
TransferHouseholdOwnershipRequest:
type: object
additionalProperties: false
required: [member_id]
properties:
member_id: { type: string, format: uuid }
MemberInvitation:
type: object
additionalProperties: false
required: [id, household_id, role, expires_at, created_at, status]
properties:
id: { type: string, format: uuid }
household_id: { type: string, format: uuid }
invitee_hint: { type: string, maxLength: 255 }
role: { type: string, enum: [admin, editor, viewer] }
expires_at: { type: string, format: date-time }
used_at: { type: string, format: date-time }
revoked_at: { type: string, format: date-time }
created_at: { type: string, format: date-time }
status: { type: string, enum: [pending, used, revoked, expired] }
token:
type: string
minLength: 32
maxLength: 128
writeOnly: true
description: 仅创建邀请时返回一次,列表接口不返回。
CreateMemberInvitationRequest:
type: object
additionalProperties: false
required: [role]
properties:
invitee_hint: { type: string, maxLength: 255 }
role: { type: string, enum: [admin, editor, viewer] }
expires_in_hours: { type: integer, minimum: 1, maximum: 720, default: 168 }
AcceptMemberInvitationRequest:
type: object
additionalProperties: false
required: [token]
properties:
token: { type: string, minLength: 32, maxLength: 128, writeOnly: true }
MemberInvitationPreview:
type: object
additionalProperties: false
required: [tenant_id, tenant_name, household_id, household_name, role, expires_at]
properties:
tenant_id: { type: string, format: uuid }
tenant_name: { type: string }
household_id: { type: string, format: uuid }
household_name: { type: string }
invitee_hint: { type: string, maxLength: 255 }
role: { type: string, enum: [admin, editor, viewer] }
expires_at: { type: string, format: date-time }
Subject:
type: object
additionalProperties: false
required: [id, household_id, preferred_name, language, timezone, profile_data, conversation_preferences, status, version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
household_id: { type: string, format: uuid }
preferred_name: { type: string, minLength: 1, maxLength: 120 }
language: { type: string, minLength: 1, maxLength: 32, pattern: '^[A-Za-z0-9-]+$' }
timezone: { type: string, minLength: 1, maxLength: 64, description: IANA时区名称 }
profile_data: { $ref: '#/components/schemas/SubjectProfileData' }
conversation_preferences: { $ref: '#/components/schemas/SubjectConversationPreferences' }
status: { type: string, enum: [active, suspended, deleting] }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
CreateSubjectRequest:
type: object
additionalProperties: false
required: [preferred_name, language, timezone, profile_data, conversation_preferences]
properties:
preferred_name: { type: string, minLength: 1, maxLength: 120 }
language: { type: string, minLength: 1, maxLength: 32, pattern: '^[A-Za-z0-9-]+$' }
timezone: { type: string, minLength: 1, maxLength: 64 }
profile_data: { $ref: '#/components/schemas/SubjectProfileData' }
conversation_preferences: { $ref: '#/components/schemas/SubjectConversationPreferences' }
UpdateSubjectRequest:
type: object
additionalProperties: false
minProperties: 1
properties:
preferred_name: { type: string, minLength: 1, maxLength: 120 }
language: { type: string, minLength: 1, maxLength: 32, pattern: '^[A-Za-z0-9-]+$' }
timezone: { type: string, minLength: 1, maxLength: 64 }
profile_data: { $ref: '#/components/schemas/SubjectProfileData' }
conversation_preferences: { $ref: '#/components/schemas/SubjectConversationPreferences' }
status: { type: string, enum: [active, suspended] }
SubjectProfileData:
type: object
additionalProperties: true
description: 档案可扩展对象;只有下列白名单字段会按档案版本冻结并进入新通话的供应商上下文,其他字段仅保存在SaaS业务域。
properties:
background: { type: string, maxLength: 500, description: 经家庭确认、允许用于陪伴交流的简要背景。 }
interests:
type: array
maxItems: 8
items: { type: string, minLength: 1, maxLength: 50 }
SubjectConversationPreferences:
type: object
additionalProperties: true
description: 交流偏好可扩展对象;下列白名单字段会从下一次新通话起生效,进行中的通话继续使用原冻结版本。
properties:
conversation_goal: { type: string, maxLength: 200 }
pace: { type: string, enum: [slow, normal, lively] }
preferred_topics:
type: array
maxItems: 8
items: { type: string, minLength: 1, maxLength: 50 }
2026-08-29 21:56:51 +08:00
avoided_topics:
type: array
maxItems: 8
description: 不希望智能体主动提及的话题;长者主动提及时先简短共情并自然转向,紧急安全响应不受此限制。
items: { type: string, minLength: 1, maxLength: 50 }
2026-08-26 06:41:07 +08:00
ConversationReadinessCheck:
type: object
additionalProperties: false
required: [code, status, blocking, title, detail]
properties:
code: { type: string, enum: [SUBJECT_ACTIVE, PROFILE_BACKGROUND, CONVERSATION_GOAL, VOICE_CONSENT, DEVICE_BOUND, DEVICE_RUNTIME, FIRMWARE_POLICY, CONFIG_SYNC, RECENT_CONTACT] }
status: { type: string, enum: [ready, blocked, attention] }
blocking: { type: boolean }
title: { type: string }
detail: { type: string }
action: { type: string, enum: [EDIT_PROFILE, MANAGE_CONSENTS, BIND_DEVICE, OPEN_DEVICES] }
ConversationReadinessDevice:
type: object
additionalProperties: false
required: [id, model, status, desired_revision]
properties:
id: { type: string, format: uuid }
model: { type: string }
status: { type: string, enum: [registered, quarantined, revoked] }
firmware_version: { type: string }
minimum_firmware_version: { type: string, description: SemVer可按顺序比较;不符合SemVer的厂商版本只允许与最低版本精确相等。 }
desired_revision: { type: integer, format: int64, minimum: 1 }
reported_revision: { type: integer, format: int64, minimum: 1 }
last_reported_at: { type: string, format: date-time }
ConversationReadiness:
type: object
additionalProperties: false
required: [subject_id, ready, evaluated_at, checks, devices, start_time_checks]
properties:
subject_id: { type: string, format: uuid }
ready: { type: boolean, description: 家庭可处理的阻断项是否均已完成;不替代创建通话时的瞬时门禁。 }
evaluated_at: { type: string, format: date-time }
checks: { type: array, items: { $ref: '#/components/schemas/ConversationReadinessCheck' } }
devices: { type: array, items: { $ref: '#/components/schemas/ConversationReadinessDevice' } }
start_time_checks:
type: array
items: { type: string, enum: [usage_quota, runtime_routing, no_active_conversation] }
SubjectFact:
type: object
additionalProperties: false
required: [id, subject_id, fact_type, content, source_type, confirmation_status, sensitivity, version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
fact_type: { type: string, minLength: 1, maxLength: 64 }
content: { type: string, minLength: 1, maxLength: 4000 }
source_type: { type: string, enum: [subject_statement, family_entry, model_candidate, imported] }
source_ref: { type: string, maxLength: 300 }
confirmation_status: { type: string, enum: [pending, confirmed, rejected, superseded] }
sensitivity: { type: string, enum: [normal, sensitive, high] }
valid_from: { type: string, format: date-time }
valid_to: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
CreateSubjectFactRequest:
type: object
additionalProperties: false
required: [fact_type, content, source_type, confirmation_status, sensitivity]
properties:
fact_type: { type: string, minLength: 1, maxLength: 64 }
content: { type: string, minLength: 1, maxLength: 4000 }
source_type: { type: string, enum: [subject_statement, family_entry, model_candidate, imported] }
source_ref: { type: string, maxLength: 300 }
confirmation_status: { type: string, enum: [pending, confirmed, rejected, superseded] }
sensitivity: { type: string, enum: [normal, sensitive, high] }
valid_from: { type: string, format: date-time }
valid_to: { type: string, format: date-time }
UpdateSubjectFactRequest:
type: object
additionalProperties: false
minProperties: 1
properties:
fact_type: { type: string, minLength: 1, maxLength: 64 }
content: { type: string, minLength: 1, maxLength: 4000 }
source_ref: { type: string, maxLength: 300 }
confirmation_status: { type: string, enum: [pending, confirmed, rejected, superseded] }
sensitivity: { type: string, enum: [normal, sensitive, high] }
valid_from: { type: string, format: date-time }
valid_to: { type: string, format: date-time }
ConsentType:
type: string
enum: [transcript_storage, raw_audio_storage, story_extraction, personalized_memory, family_sharing]
Consent:
type: object
additionalProperties: false
required: [id, subject_id, type, scope, policy_version, notice_digest, actor_user_id, granted_at, effective, version]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
type: { $ref: '#/components/schemas/ConsentType' }
scope: { type: object, additionalProperties: true }
policy_version: { type: string, minLength: 1, maxLength: 64 }
notice_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
actor_user_id: { type: string, format: uuid }
evidence_ref: { type: string, maxLength: 300 }
granted_at: { type: string, format: date-time }
expires_at: { type: string, format: date-time }
withdrawn_at: { type: string, format: date-time }
effective: { type: boolean }
version: { type: integer, format: int64, minimum: 1 }
GrantConsentRequest:
type: object
additionalProperties: false
required: [type, scope, policy_version, notice_digest]
properties:
type: { $ref: '#/components/schemas/ConsentType' }
scope: { type: object, additionalProperties: true }
policy_version: { type: string, minLength: 1, maxLength: 64 }
notice_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
evidence_ref: { type: string, maxLength: 300 }
expires_at: { type: string, format: date-time }
ManagedDevice:
type: object
additionalProperties: false
2026-08-29 21:56:51 +08:00
required: [id, binding_id, household_id, subject_id, subject_name, model, status, desired_revision, bound_at, registered_at, version]
2026-08-26 06:41:07 +08:00
properties:
id: { type: string, format: uuid }
2026-08-29 21:56:51 +08:00
binding_id: { type: string, format: uuid, description: 当前有效绑定编号;解绑或转移时用于并发校验。 }
2026-08-26 06:41:07 +08:00
household_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
subject_name: { type: string }
model: { type: string }
hardware_revision: { type: string }
status: { type: string, enum: [registered, quarantined, revoked] }
minimum_security_version: { type: string }
minimum_firmware_version: { type: string, description: 独立于安全基线标识的新通话最低固件版本。 }
firmware_version: { type: string }
desired_revision: { type: integer, format: int64, minimum: 1 }
reported_revision: { type: integer, format: int64, minimum: 1 }
last_reported_at: { type: string, format: date-time }
bound_at: { type: string, format: date-time }
registered_at: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
2026-08-29 21:56:51 +08:00
OpsDevice:
type: object
additionalProperties: false
required: [id, tenant_id, model, status, credential_status, key_version, registered_at, updated_at, version]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
model: { type: string, minLength: 1, maxLength: 120 }
hardware_revision: { type: string, maxLength: 80 }
status: { type: string, enum: [registered, quarantined, revoked] }
minimum_security_version: { type: string, maxLength: 80 }
minimum_firmware_version: { type: string, maxLength: 80 }
household_id: { type: string, format: uuid }
household_name: { type: string }
subject_id: { type: string, format: uuid }
subject_name: { type: string }
credential_status: { type: string, enum: [active, revoked, missing] }
key_version: { type: integer, format: int64, minimum: 0 }
last_reported_at: { type: string, format: date-time }
registered_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
OpsDeviceAssignmentOption:
type: object
additionalProperties: false
required: [household_id, household_name, subject_id, subject_name]
properties:
household_id: { type: string, format: uuid }
household_name: { type: string }
subject_id: { type: string, format: uuid }
subject_name: { type: string }
CreateOpsDeviceRequest:
type: object
additionalProperties: false
required: [model]
properties:
model: { type: string, minLength: 1, maxLength: 120 }
hardware_revision: { type: string, maxLength: 80 }
minimum_security_version: { type: string, maxLength: 80 }
minimum_firmware_version: { type: string, maxLength: 80 }
household_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
UpdateOpsDeviceRequest:
type: object
additionalProperties: false
minProperties: 1
properties:
model: { type: string, minLength: 1, maxLength: 120 }
hardware_revision: { type: string, maxLength: 80 }
minimum_security_version: { type: string, maxLength: 80 }
minimum_firmware_version: { type: string, maxLength: 80 }
status: { type: string, enum: [registered, quarantined] }
household_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
DeviceCredentialIssue:
type: object
additionalProperties: false
required: [device_id, secret, key_version, issued_at]
properties:
device_id: { type: string, format: uuid }
secret: { type: string, pattern: '^[0-9a-f]{64}$', description: 仅本响应返回一次。 }
key_version: { type: integer, format: int64, minimum: 1 }
issued_at: { type: string, format: date-time }
DeviceClaimIssue:
type: object
additionalProperties: false
required: [device_id, claim_code, issued_at, expires_at]
properties:
device_id: { type: string, format: uuid }
claim_code: { type: string, minLength: 16, maxLength: 128, writeOnly: true, description: 仅本响应返回一次。 }
issued_at: { type: string, format: date-time }
expires_at: { type: string, format: date-time }
OpsDeviceResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/OpsDevice' }
OpsDeviceListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { type: object, required: [items], properties: { items: { type: array, items: { $ref: '#/components/schemas/OpsDevice' } } } }
OpsDeviceAssignmentOptionListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { type: object, required: [items], properties: { items: { type: array, items: { $ref: '#/components/schemas/OpsDeviceAssignmentOption' } } } }
CreateOpsDeviceResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { type: object, required: [device, credential], properties: { device: { $ref: '#/components/schemas/OpsDevice' }, credential: { $ref: '#/components/schemas/DeviceCredentialIssue' }, claim: { $ref: '#/components/schemas/DeviceClaimIssue' } } }
DeviceCredentialIssueResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceCredentialIssue' }
DeviceClaimIssueResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceClaimIssue' }
DeviceBindingImpact:
type: object
additionalProperties: false
required: [device_id, binding_id, action, source_household_id, source_subject_id, source_subject_name, pending_command_count, active_firmware_task_count, allowed, blockers, evaluated_at]
properties:
device_id: { type: string, format: uuid }
binding_id: { type: string, format: uuid }
action: { type: string, enum: [unbind, transfer] }
source_household_id: { type: string, format: uuid }
source_subject_id: { type: string, format: uuid }
source_subject_name: { type: string }
target_household_id: { type: string, format: uuid }
target_subject_id: { type: string, format: uuid }
target_subject_name: { type: string }
active_conversation_id: { type: string, format: uuid }
pending_command_count: { type: integer, minimum: 0 }
active_firmware_task_count: { type: integer, minimum: 0 }
allowed: { type: boolean }
blockers:
type: array
items: { type: string, enum: [target_subject_required, active_conversation, pending_device_commands, active_firmware_task] }
evaluated_at: { type: string, format: date-time }
ChangeDeviceBindingRequest:
type: object
additionalProperties: false
required: [action, expected_binding_id, reason, acknowledged]
properties:
action: { type: string, enum: [unbind, transfer] }
expected_binding_id: { type: string, format: uuid }
target_subject_id: { type: string, format: uuid, description: action为transfer时必填。 }
reason: { type: string, minLength: 3, maxLength: 300 }
acknowledged: { type: boolean, const: true }
DeviceBindingChangeResult:
type: object
additionalProperties: false
required: [device_id, action, previous_binding_id, changed_at]
properties:
device_id: { type: string, format: uuid }
action: { type: string, enum: [unbind, transfer] }
previous_binding_id: { type: string, format: uuid }
binding_id: { type: string, format: uuid }
household_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
changed_at: { type: string, format: date-time }
2026-08-26 06:41:07 +08:00
DevicePresence:
type: object
additionalProperties: false
required: [device_id, online, status, source]
properties:
device_id: { type: string, format: uuid }
online: { type: boolean }
status: { type: string }
conversation_id: { type: string, format: uuid }
sequence_no: { type: integer, format: int64, minimum: 1 }
last_seen_at: { type: string, format: date-time }
firmware_version: { type: string }
source: { type: string, enum: [redis, database] }
DeviceTwin:
type: object
additionalProperties: false
required: [device_id, desired_revision, desired_config, reported_config, capabilities, sync_state, updated_at]
properties:
device_id: { type: string, format: uuid }
desired_revision: { type: integer, format: int64, minimum: 1 }
desired_config: { type: object, additionalProperties: true }
reported_revision: { type: integer, format: int64, minimum: 1 }
reported_config: { type: object, additionalProperties: true }
firmware_version: { type: string }
board_revision: { type: string }
rtc_sdk_version: { type: string }
capabilities: { type: object, additionalProperties: true }
last_reported_at: { type: string, format: date-time }
last_error_code: { type: string, maxLength: 80, description: 终端最近一次脱敏错误码 }
last_error_severity: { type: string, enum: [info, warning, error, critical] }
last_error_at: { type: string, format: date-time }
sync_state: { type: string, enum: [never_reported, pending, applied] }
updated_at: { type: string, format: date-time }
UpdateDeviceTwinRequest:
type: object
description: 下发非敏感设备配置增量;服务端按顶层白名单分类合并并保留未提交的既有配置。扬声器音量必须为0至100的整数,修改需携带当前设备影子ETag。
additionalProperties: false
required: [desired_config]
properties:
desired_config:
type: object
additionalProperties: false
properties:
volume:
type: object
additionalProperties: true
properties:
speaker: { type: integer, minimum: 0, maximum: 100, description: 扬声器音量百分比 }
interaction: { type: object, additionalProperties: true }
upload: { type: object, additionalProperties: true }
rtc: { type: object, additionalProperties: true }
policy_refs: { type: object, additionalProperties: true }
DeviceCommandStatus:
type: string
enum: [QUEUED, DELIVERED, ACKNOWLEDGED, SUCCEEDED, FAILED, EXPIRED, CANCELLED]
DeviceCommand:
type: object
additionalProperties: false
required: [id, device_id, type, payload, status, result_summary, expires_at, delivery_attempts, version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
device_id: { type: string, format: uuid }
type: { type: string, enum: [apply_config, reboot, diagnostics, firmware_update] }
payload: { type: object, additionalProperties: true }
status: { $ref: '#/components/schemas/DeviceCommandStatus' }
result_summary: { type: object, additionalProperties: true }
expires_at: { type: string, format: date-time }
delivery_attempts: { type: integer, minimum: 0 }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
DeviceCommandDelivery:
type: object
additionalProperties: false
required: [id, type, payload, status, expires_at, delivery_attempts, created_at]
properties:
id: { type: string, format: uuid }
type: { type: string, enum: [apply_config, reboot, diagnostics, firmware_update] }
payload: { type: object, additionalProperties: true }
status: { $ref: '#/components/schemas/DeviceCommandStatus' }
expires_at: { type: string, format: date-time }
delivery_attempts: { type: integer, minimum: 0 }
created_at: { type: string, format: date-time }
CreateDeviceCommandRequest:
type: object
additionalProperties: false
required: [type, payload, expires_in_sec]
properties:
type: { type: string, enum: [apply_config, reboot, diagnostics, firmware_update] }
payload: { type: object, additionalProperties: true }
expires_in_sec: { type: integer, minimum: 30, maximum: 86400 }
DeviceCommandAckRequest:
type: object
additionalProperties: false
required: [status, result_summary]
properties:
status: { type: string, enum: [ACKNOWLEDGED, SUCCEEDED, FAILED] }
result_summary:
type: object
additionalProperties: true
description: 固件命令可在ACKNOWLEDGED时上报phase=downloading、installing、staging、reboot_pending或boot_verifying及progress_percent;A/B设备可附active_slot、target_slot、boot_attempt_id和boot_health_deadline。成功时上报installed_version;启动健康失败并已自动回退时以FAILED上报phase=rolled_back、rollback_applied=true和rollback_version。
PrepareMediaUploadBatchRequest:
type: object
additionalProperties: false
required: [segments]
properties:
segments:
type: array
minItems: 1
maxItems: 1000
items: { $ref: '#/components/schemas/MediaSegmentDeclaration' }
MediaSegmentDeclaration:
type: object
additionalProperties: false
required: [track, sequence_no, codec, content_type, duration_ms, expected_size, expected_digest]
properties:
track: { type: string, enum: [near, far] }
sequence_no: { type: integer, minimum: 0 }
codec: { type: string, enum: [wav_pcm_s16le], description: 当前基线仅在可解析WAV PCM16时进入VERIFIED;待硬件团队冻结编码后再增加Opus解析器。 }
content_type: { type: string, enum: [audio/wav] }
duration_ms: { type: integer, minimum: 1, maximum: 600000 }
expected_size: { type: integer, format: int64, minimum: 1, maximum: 67108864 }
expected_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
MediaSegment:
type: object
additionalProperties: false
required: [id, track, sequence_no, codec, content_type, duration_ms, expected_size, expected_digest, status]
properties:
id: { type: string, format: uuid }
track: { type: string, enum: [near, far] }
sequence_no: { type: integer, minimum: 0 }
codec: { type: string }
content_type: { type: string }
duration_ms: { type: integer, minimum: 1 }
expected_size: { type: integer, format: int64, minimum: 1 }
expected_digest: { type: string }
status: { type: string, enum: [DECLARED, AUTHORIZED, UPLOADED, VERIFYING, VERIFIED, REJECTED, DELETED] }
last_error_code: { type: string }
upload_url: { type: string, format: uri, description: 仅创建批次响应返回的单对象短期PUT地址 }
upload_until: { type: string, format: date-time }
verified_at: { type: string, format: date-time }
local_delete_after: { type: string, format: date-time, description: 仅VERIFIED分片返回;设备应延迟到该时间后删除本地密文 }
local_delete_status: { type: string, enum: [DELETED, FAILED], description: 设备最近一次本地密文删除回执;缺省表示尚未回报 }
local_delete_reported_at: { type: string, format: date-time }
local_delete_error_code: { type: string, description: FAILED时由设备上报的稳定错误码 }
MediaUploadBatch:
type: object
additionalProperties: false
required: [id, conversation_id, status, segment_count, expected_total_size, verified_count, rejected_count, verification_attempts, expires_at, segments]
properties:
id: { type: string, format: uuid }
conversation_id: { type: string, format: uuid }
status: { type: string, enum: [PENDING, UPLOADING, VERIFYING, COMPLETED, FAILED, EXPIRED] }
segment_count: { type: integer, minimum: 1 }
expected_total_size: { type: integer, format: int64, minimum: 1 }
verified_count: { type: integer, minimum: 0 }
rejected_count: { type: integer, minimum: 0 }
verification_attempts: { type: integer, minimum: 0 }
last_error_code: { type: string }
expires_at: { type: string, format: date-time }
segments: { type: array, items: { $ref: '#/components/schemas/MediaSegment' } }
GrantRecordingAccessRequest:
type: object
additionalProperties: false
required: [grantee_user_id, permission, purpose, expires_at]
properties:
grantee_user_id: { type: string, format: uuid }
permission: { type: string, enum: [PLAY, DOWNLOAD] }
purpose: { type: string, minLength: 1, maxLength: 120 }
expires_at: { type: string, format: date-time }
RecordingAccessGrant:
type: object
additionalProperties: false
required: [id, subject_id, grantee_user_id, permission, purpose, granted_by, granted_at, expires_at]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
grantee_user_id: { type: string, format: uuid }
permission: { type: string, enum: [PLAY, DOWNLOAD] }
purpose: { type: string }
granted_by: { type: string, format: uuid }
granted_at: { type: string, format: date-time }
expires_at: { type: string, format: date-time }
revoked_at: { type: string, format: date-time }
ConversationMedia:
type: object
additionalProperties: false
required: [conversation_id, can_play, can_download, segments]
properties:
conversation_id: { type: string, format: uuid }
can_play: { type: boolean }
can_download: { type: boolean }
segments: { type: array, items: { $ref: '#/components/schemas/MediaSegment' } }
CreateMediaAccessRequest:
type: object
additionalProperties: false
required: [action, purpose]
properties:
action: { type: string, enum: [PLAY, DOWNLOAD] }
purpose: { type: string, minLength: 1, maxLength: 120 }
LocalMediaDeleteReceiptRequest:
type: object
additionalProperties: false
required: [status]
properties:
status: { type: string, enum: [DELETED, FAILED] }
error_code: { type: string, minLength: 1, maxLength: 80, pattern: '^[A-Za-z0-9_.-]+$', description: FAILED时必填,DELETED时不得传入 }
MediaAccess:
type: object
additionalProperties: false
required: [segment_id, action, access_url, access_until]
properties:
segment_id: { type: string, format: uuid }
action: { type: string, enum: [PLAY, DOWNLOAD] }
access_url: { type: string, format: uri }
access_until: { type: string, format: date-time }
RegisterFirmwareSigningKeyRequest:
type: object
additionalProperties: false
required: [key_id, public_key_base64]
properties:
key_id: { type: string, minLength: 1, maxLength: 120 }
public_key_base64: { type: string, description: Base64编码的32字节Ed25519公钥 }
RevokeFirmwareSigningKeyRequest:
type: object
additionalProperties: false
required: [key_id]
properties:
key_id: { type: string, minLength: 1, maxLength: 120 }
FirmwareSigningKey:
type: object
additionalProperties: false
required: [key_id, fingerprint_sha256, status, created_by, created_at, uploading_releases, ready_releases, running_rollouts]
properties:
key_id: { type: string }
fingerprint_sha256: { type: string, pattern: '^[0-9a-f]{64}$' }
status: { type: string, enum: [ACTIVE, REVOKED] }
created_by: { type: string, format: uuid }
created_at: { type: string, format: date-time }
revoked_at: { type: string, format: date-time }
uploading_releases: { type: integer, minimum: 0 }
ready_releases: { type: integer, minimum: 0 }
running_rollouts: { type: integer, minimum: 0 }
PrepareFirmwareReleaseRequest:
type: object
additionalProperties: false
required: [model, version, expected_size, expected_digest, signature, signing_key_id]
properties:
model: { type: string, minLength: 1, maxLength: 120 }
hardware_revision: { type: string, maxLength: 80 }
version: { type: string, minLength: 1, maxLength: 80 }
expected_size: { type: integer, format: int64, minimum: 1, maximum: 268435456 }
expected_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
signature: { type: string, description: 对firmware-manifest-v1规范文本的Ed25519签名Base64 }
signing_key_id: { type: string, minLength: 1, maxLength: 120 }
minimum_security_version: { type: string, maxLength: 80 }
release_notes: { type: string, maxLength: 2000 }
FirmwareRelease:
type: object
additionalProperties: false
required: [id, model, version, expected_size, expected_digest, signature_algorithm, signature, signing_key_id, status, created_at, updated_at]
properties:
id: { type: string, format: uuid }
model: { type: string }
hardware_revision: { type: string }
version: { type: string }
expected_size: { type: integer, format: int64 }
expected_digest: { type: string }
signature_algorithm: { type: string, const: ed25519 }
signature: { type: string }
signing_key_id: { type: string }
minimum_security_version: { type: string }
release_notes: { type: string }
status: { type: string, enum: [UPLOADING, READY, PAUSED, RETIRED] }
verified_at: { type: string, format: date-time }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
upload_url: { type: string, format: uri, description: 仅创建响应返回的短期私有PUT地址 }
upload_until: { type: string, format: date-time }
FirmwareReleaseImpact:
type: object
additionalProperties: false
required: [release_id, release_status, rollouts, devices, commands, observation_devices, observation_devices_truncated, calculated_at]
properties:
release_id: { type: string, format: uuid }
release_status: { type: string, enum: [UPLOADING, READY, PAUSED, RETIRED] }
rollouts: { $ref: '#/components/schemas/FirmwareImpactRolloutCount' }
devices: { $ref: '#/components/schemas/FirmwareImpactDeviceCount' }
commands: { $ref: '#/components/schemas/FirmwareImpactCommandCount' }
observation_devices: { type: array, maxItems: 100, items: { $ref: '#/components/schemas/FirmwareImpactDevice' } }
observation_devices_truncated: { type: boolean }
calculated_at: { type: string, format: date-time }
FirmwareImpactRolloutCount:
type: object
additionalProperties: false
required: [total, running, paused, completed, rolled_back]
properties:
total: { type: integer, minimum: 0 }
running: { type: integer, minimum: 0 }
paused: { type: integer, minimum: 0 }
completed: { type: integer, minimum: 0 }
rolled_back: { type: integer, minimum: 0 }
FirmwareImpactDeviceCount:
type: object
additionalProperties: false
required: [total, assigned, downloading, installing, confirmed, failed, rolled_back, observing]
properties:
total: { type: integer, minimum: 0 }
assigned: { type: integer, minimum: 0 }
downloading: { type: integer, minimum: 0 }
installing: { type: integer, minimum: 0 }
confirmed: { type: integer, minimum: 0 }
failed: { type: integer, minimum: 0 }
rolled_back: { type: integer, minimum: 0 }
observing: { type: integer, minimum: 0 }
FirmwareImpactCommandCount:
type: object
additionalProperties: false
required: [total, queued, delivered, acknowledged, succeeded, failed, expired, cancelled_before_delivery]
properties:
total: { type: integer, minimum: 0 }
queued: { type: integer, minimum: 0 }
delivered: { type: integer, minimum: 0 }
acknowledged: { type: integer, minimum: 0 }
succeeded: { type: integer, minimum: 0 }
failed: { type: integer, minimum: 0 }
expired: { type: integer, minimum: 0 }
cancelled_before_delivery: { type: integer, minimum: 0 }
FirmwareImpactDevice:
type: object
additionalProperties: false
required: [device_id, device_model, rollout_id, rollout_name, rollout_status, assignment_status, command_status, observation_reason, updated_at]
properties:
device_id: { type: string, format: uuid }
device_model: { type: string }
rollout_id: { type: string, format: uuid }
rollout_name: { type: string }
rollout_status: { type: string, enum: [DRAFT, RUNNING, PAUSED, COMPLETED, ROLLED_BACK] }
assignment_status: { type: string, enum: [ASSIGNED, DOWNLOADING, INSTALLING, CONFIRMED, FAILED, ROLLED_BACK] }
progress_percent: { type: integer, minimum: 0, maximum: 100 }
command_status: { type: string, enum: [QUEUED, DELIVERED, ACKNOWLEDGED, SUCCEEDED, FAILED, EXPIRED, CANCELLED, UNKNOWN] }
observation_reason: { type: string, enum: [INSTALLATION_IN_PROGRESS, DOWNLOAD_IN_PROGRESS, COMMAND_DELIVERED, COMMAND_ACKNOWLEDGED, RESULT_RECONCILIATION_REQUIRED] }
last_reported_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
StartFirmwareRolloutRequest:
type: object
additionalProperties: false
required: [release_id, name, target_percentage, device_ids]
properties:
release_id: { type: string, format: uuid }
name: { type: string, minLength: 1, maxLength: 160 }
target_percentage: { type: integer, minimum: 1, maximum: 100 }
device_ids: { type: array, minItems: 1, uniqueItems: true, items: { type: string, format: uuid } }
RollbackFirmwareRolloutRequest:
type: object
additionalProperties: false
required: [rollback_release_id]
properties: { rollback_release_id: { type: string, format: uuid } }
FirmwareRollout:
type: object
additionalProperties: false
required: [id, release_id, household_id, name, status, target_percentage, targeted, succeeded, failed, created_at, updated_at]
properties:
id: { type: string, format: uuid }
release_id: { type: string, format: uuid }
household_id: { type: string, format: uuid }
name: { type: string }
status: { type: string, enum: [DRAFT, RUNNING, PAUSED, COMPLETED, ROLLED_BACK] }
target_percentage: { type: integer, minimum: 1, maximum: 100 }
targeted: { type: integer, minimum: 0 }
succeeded: { type: integer, minimum: 0 }
failed: { type: integer, minimum: 0 }
assignments: { type: array, items: { $ref: '#/components/schemas/FirmwareAssignment' } }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
FirmwareAssignment:
type: object
additionalProperties: false
required: [device_id, device_model, status, last_result, updated_at]
properties:
device_id: { type: string, format: uuid }
device_model: { type: string }
previous_version: { type: string }
status: { type: string, enum: [ASSIGNED, DOWNLOADING, INSTALLING, CONFIRMED, FAILED, ROLLED_BACK] }
progress_percent: { type: integer, minimum: 0, maximum: 100 }
last_result: { type: object, additionalProperties: true }
events: { type: array, description: 去重后的设备固件阶段回执时间线,按云端接收时间升序排列, items: { $ref: '#/components/schemas/FirmwareAssignmentEvent' } }
last_reported_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
FirmwareAssignmentEvent:
type: object
additionalProperties: false
required: [id, command_id, command_status, assignment_status, result_digest, reported_at]
properties:
id: { type: string, format: uuid }
command_id: { type: string, format: uuid }
command_status: { type: string, enum: [ACKNOWLEDGED, SUCCEEDED, FAILED] }
assignment_status: { type: string, enum: [DOWNLOADING, INSTALLING, CONFIRMED, FAILED] }
phase: { type: string }
progress_percent: { type: integer, minimum: 0, maximum: 100 }
result_code: { type: string }
active_slot: { type: string }
target_slot: { type: string }
previous_slot: { type: string }
failed_slot: { type: string }
boot_attempt_id: { type: string }
boot_health_deadline: { type: string }
rollback_applied: { type: boolean }
rollback_version: { type: string }
installed_version: { type: string }
verified_sha256: { type: string, pattern: '^[0-9a-f]{64}$' }
verified_signing_key_id: { type: string }
result_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
reported_at: { type: string, format: date-time }
DeviceClaimRequest:
type: object
additionalProperties: false
required: [claim_code, household_id, subject_id]
properties:
2026-08-29 21:56:51 +08:00
claim_code: { type: string, minLength: 16, maxLength: 128, writeOnly: true, description: 设备屏幕显示或维护端生成的一次性绑定码;不能填写设备公开UUID。 }
2026-08-26 06:41:07 +08:00
household_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
DeviceClaimResult:
type: object
additionalProperties: false
required: [binding_id, device_id, household_id, subject_id, bound_at]
properties:
binding_id: { type: string, format: uuid }
device_id: { type: string, format: uuid }
household_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
bound_at: { type: string, format: date-time }
ConversationStatus:
type: string
enum: [PREPARING, ROOM_ISSUED, STARTING_AGENT, ACTIVE, STOPPING, COMPLETED, FAILED, EXPIRED]
ConversationSummary:
type: object
additionalProperties: false
required: [id, subject_id, device_id, status, engine_mode, retention_mode, audio_retention_enabled, created_at, updated_at]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
device_id: { type: string, format: uuid }
status: { $ref: '#/components/schemas/ConversationStatus' }
engine_mode: { type: string, enum: [s2s_pure, s2s_hybrid, cascade] }
retention_mode: { type: string, enum: [none, transcript_only, transcript_and_audio] }
audio_retention_enabled:
type: boolean
description: 只表示通话冻结策略允许保存原录音,不代表媒体已经上传或可播放。
started_at: { type: string, format: date-time }
ended_at: { type: string, format: date-time }
duration_ms: { type: integer, format: int64, minimum: 0 }
stop_reason: { type: string }
failure_code: { type: string }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
ConversationStateEntry:
type: object
additionalProperties: false
required: [to_status, source, occurred_at]
properties:
from_status: { $ref: '#/components/schemas/ConversationStatus' }
to_status: { $ref: '#/components/schemas/ConversationStatus' }
reason: { type: string }
source: { type: string, enum: [device, platform, provider, worker, operator] }
occurred_at: { type: string, format: date-time }
ConversationSnapshotSummary:
type: object
additionalProperties: false
required: [consent_snapshot_id, consent_snapshot_version, context_snapshot_id, profile_version, prompt_bundle_version, context_preparation_status]
properties:
consent_snapshot_id: { type: string, format: uuid }
consent_snapshot_version: { type: integer, format: int64, minimum: 1 }
context_snapshot_id: { type: string, format: uuid }
profile_version: { type: integer, format: int64, minimum: 1 }
prompt_bundle_version: { type: string }
context_preparation_status: { type: string, enum: [READY, FAILED] }
context_preparation_failure_code: { type: string, description: 背景资料准备失败时的稳定脱敏错误码。 }
RTCTaskSummary:
type: object
additionalProperties: false
required: [provider, status, start_attempts, stop_attempts]
properties:
provider: { type: string }
status: { type: string, enum: [ALLOCATED, STARTING, ACTIVE, STOPPING, COMPLETED, FAILED, UNKNOWN] }
lease_expires_at: { type: string, format: date-time }
start_attempts: { type: integer, minimum: 0 }
stop_attempts: { type: integer, minimum: 0 }
last_checked_at: { type: string, format: date-time }
ConversationDetail:
allOf:
- $ref: '#/components/schemas/ConversationSummary'
- type: object
required: [household_id, snapshots, history]
properties:
household_id: { type: string, format: uuid }
snapshots: { $ref: '#/components/schemas/ConversationSnapshotSummary' }
rtc: { $ref: '#/components/schemas/RTCTaskSummary', description: 背景资料准备失败且未创建房间时省略。 }
history:
type: array
items: { $ref: '#/components/schemas/ConversationStateEntry' }
ConversationUsage:
type: object
additionalProperties: false
required: [conversation_id, cost_micros, currency, lines]
properties:
conversation_id: { type: string, format: uuid }
cost_micros: { type: integer, format: int64, minimum: 0 }
currency: { type: string, description: 尚无已核价用量时为空字符串。 }
lines: { type: array, items: { $ref: '#/components/schemas/CostSummaryLine' } }
ConversationTurn:
type: object
additionalProperties: false
required: [id, sequence_no, speaker, start_at, end_at, final_text, interrupted, source_type]
properties:
id: { type: string, format: uuid }
sequence_no: { type: integer, format: int64, minimum: 1 }
speaker: { type: string, enum: [subject, agent] }
start_at: { type: string, format: date-time }
end_at: { type: string, format: date-time }
final_text: { type: string, minLength: 1, maxLength: 20000 }
interrupted:
type: boolean
description: 为true时表示该话轮在交互中被打断;被打断的智能体话轮不得作为长者已经听到的事实来源。
source_type: { type: string, enum: [provider, device] }
ConversationContentSummary:
type: object
additionalProperties: false
required: [id, type, content, source_turn_ids, model_ref, prompt_version, generation_version, status, created_at]
properties:
id: { type: string, format: uuid }
type: { type: string, enum: [conversation_summary, open_topic] }
content: { type: string, minLength: 1, maxLength: 20000 }
source_turn_ids: { type: array, minItems: 1, items: { type: string, format: uuid } }
model_ref: { type: string }
prompt_version: { type: string }
generation_version: { type: integer, format: int64, minimum: 1 }
status: { type: string, enum: [PROCESSING, READY, FAILED, SUPERSEDED] }
created_at: { type: string, format: date-time }
ContentModel:
type: object
additionalProperties: false
required: [id, tenant_id, display_name, provider, base_url, model_id, credential_hint, temperature, max_tokens, status, test_status, version, created_at, updated_at]
properties:
id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
display_name: { type: string, minLength: 1, maxLength: 120 }
2026-08-30 19:55:17 +08:00
provider: { $ref: '#/components/schemas/ContentModelProvider' }
base_url: { type: string, format: uri }
model_id: { type: string, minLength: 1, maxLength: 200 }
credential_hint: { type: string, description: 仅包含掩码和密钥末四位。 }
temperature: { type: number, minimum: 0, maximum: 2 }
max_tokens: { type: integer, minimum: 256, maximum: 8192 }
status: { type: string, enum: [inactive, active, revoked] }
test_status: { type: string, enum: [untested, passed, failed] }
last_tested_at: { type: string, format: date-time }
last_error_code: { type: string }
activated_at: { type: string, format: date-time }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
CreateContentModelRequest:
type: object
additionalProperties: false
required: [display_name, provider, base_url, model_id, api_key, temperature, max_tokens]
properties:
display_name: { type: string, minLength: 1, maxLength: 120 }
2026-08-30 19:55:17 +08:00
provider: { $ref: '#/components/schemas/ContentModelProvider' }
base_url: { type: string, format: uri, maxLength: 500 }
model_id: { type: string, minLength: 1, maxLength: 200 }
api_key: { type: string, minLength: 8, maxLength: 1000, writeOnly: true }
temperature: { type: number, minimum: 0, maximum: 2 }
max_tokens: { type: integer, minimum: 256, maximum: 8192 }
2026-08-30 19:55:17 +08:00
ContentModelProvider:
type: string
description: 模型厂商分类;所有类型均通过 OpenAI Chat Completions 兼容协议调用。
enum: [ark, dashscope, deepseek, moonshot, zhipu, qianfan, hunyuan, minimax, baichuan, siliconflow, ollama, openai_compatible]
2026-08-26 06:41:07 +08:00
StoryStatus:
type: string
enum: [CANDIDATE, IN_REVIEW, CONFIRMED, REJECTED, SUPERSEDED]
StorySource:
type: object
additionalProperties: false
required: [turn_id, sequence_no, speaker, text]
properties:
turn_id: { type: string, format: uuid }
sequence_no: { type: integer, format: int64, minimum: 1 }
speaker: { type: string, enum: [subject, agent] }
text: { type: string }
start_offset: { type: integer, minimum: 0 }
end_offset: { type: integer, minimum: 0 }
FactCandidate:
type: object
additionalProperties: false
required: [id, fact_type, content, statement_basis, sensitivity, source_turn_ids, status, version]
properties:
id: { type: string, format: uuid }
fact_type: { type: string }
content: { type: string }
statement_basis: { type: string, enum: [subject_statement, model_inference] }
confidence: { type: number, minimum: 0, maximum: 1 }
sensitivity: { type: string, enum: [normal, sensitive, high] }
source_turn_ids: { type: array, minItems: 1, items: { type: string, format: uuid } }
status: { type: string, enum: [CANDIDATE, CONFIRMED, REJECTED, SUPERSEDED] }
version: { type: integer, format: int64, minimum: 1 }
2026-08-29 21:56:51 +08:00
UpdateFactCandidateRequest:
type: object
additionalProperties: false
minProperties: 2
required: [reason]
properties:
fact_type: { type: string, minLength: 1, maxLength: 64 }
content: { type: string, minLength: 1, maxLength: 4000 }
sensitivity: { type: string, enum: [normal, sensitive, high] }
status: { type: string, enum: [CANDIDATE, CONFIRMED, REJECTED, SUPERSEDED] }
error_type: { $ref: '#/components/schemas/ContentErrorType' }
reason: { type: string, minLength: 1, maxLength: 500 }
2026-08-26 06:41:07 +08:00
Story:
type: object
additionalProperties: false
required: [id, subject_id, conversation_id, title, content, status, sensitivity, generation_version, revision_no, author_type, version, created_at, updated_at, sources, facts]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
conversation_id: { type: string, format: uuid }
title: { type: string, minLength: 1, maxLength: 300 }
content: { type: string, minLength: 1, maxLength: 50000 }
status: { $ref: '#/components/schemas/StoryStatus' }
confidence: { type: number, minimum: 0, maximum: 1 }
sensitivity: { type: string, enum: [normal, sensitive, high] }
generation_version: { type: integer, format: int64, minimum: 1 }
revision_no: { type: integer, format: int64, minimum: 1 }
author_type: { type: string, enum: [model, user] }
review_reason: { type: string, maxLength: 500 }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
sources: { type: array, items: { $ref: '#/components/schemas/StorySource' } }
facts: { type: array, items: { $ref: '#/components/schemas/FactCandidate' } }
CuratedMemory:
type: object
additionalProperties: false
2026-08-29 21:56:51 +08:00
required: [id, subject_id, content, source_refs, status, sensitivity, version_no, version, confirmed_by, confirmed_at, index_status, provider_index_status, created_at, updated_at]
2026-08-26 06:41:07 +08:00
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
content: { type: string, minLength: 1, maxLength: 50000 }
source_refs: { type: array, minItems: 1, items: { type: object, additionalProperties: true } }
status: { type: string, enum: [ACTIVE, DISABLED, SUPERSEDED, PENDING_DELETE, DELETED] }
sensitivity: { type: string, enum: [normal, sensitive, high] }
version_no: { type: integer, format: int64, minimum: 1 }
version: { type: integer, format: int64, minimum: 1 }
confirmed_by: { type: string, format: uuid }
confirmed_at: { type: string, format: date-time }
change_reason: { type: string, maxLength: 500 }
index_status: { type: string, enum: [PENDING, ACTIVE, STALE, FAILED, DELETED] }
last_index_error: { type: string }
2026-08-29 21:56:51 +08:00
provider_index_status: { type: string, enum: [DISABLED, PENDING, ACTIVE, STALE, FAILED, DELETED] }
provider_index_error: { type: string }
2026-08-26 06:41:07 +08:00
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
ReviseStoryRequest:
type: object
additionalProperties: false
required: [content, reason]
properties:
content: { type: string, minLength: 1, maxLength: 50000 }
2026-08-29 21:56:51 +08:00
error_type: { $ref: '#/components/schemas/ContentErrorType' }
2026-08-26 06:41:07 +08:00
reason: { type: string, minLength: 1, maxLength: 500 }
StoryDecisionRequest:
type: object
additionalProperties: false
required: [reason]
properties:
2026-08-29 21:56:51 +08:00
error_type: { $ref: '#/components/schemas/ContentErrorType' }
2026-08-26 06:41:07 +08:00
reason: { type: string, minLength: 1, maxLength: 500 }
UpdateMemoryRequest:
type: object
additionalProperties: false
required: [reason]
properties:
content: { type: string, minLength: 1, maxLength: 50000 }
status: { type: string, enum: [ACTIVE, DISABLED] }
2026-08-29 21:56:51 +08:00
error_type: { $ref: '#/components/schemas/ContentErrorType' }
2026-08-26 06:41:07 +08:00
reason: { type: string, minLength: 1, maxLength: 500 }
anyOf:
- required: [content]
- required: [status]
2026-08-29 21:56:51 +08:00
ContentErrorType:
type: string
enum: [PERSON_ERROR, TIME_ERROR, PLACE_ERROR, RELATION_ERROR, OVER_INFERENCE, KEY_POINT_OMISSION, DUPLICATE_CONTENT, UNNATURAL_EXPRESSION, SENSITIVE_INFORMATION]
ContentQualitySummary:
type: object
additionalProperties: false
required: [model_ref, prompt_version, story_candidates, fact_candidates, confirmed, edited, rejected, disabled, error_types]
properties:
model_ref: { type: string }
prompt_version: { type: string }
story_candidates: { type: integer, format: int64, minimum: 0 }
fact_candidates: { type: integer, format: int64, minimum: 0 }
confirmed: { type: integer, format: int64, minimum: 0 }
edited: { type: integer, format: int64, minimum: 0 }
rejected: { type: integer, format: int64, minimum: 0 }
disabled: { type: integer, format: int64, minimum: 0 }
error_types: { type: object, additionalProperties: { type: integer, format: int64, minimum: 0 } }
ContentQualityListData:
type: object
additionalProperties: false
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/ContentQualitySummary' } } }
ContentQualityListResponse:
type: object
additionalProperties: false
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ContentQualityListData' }
MemoryToolSearchRequest:
type: object
additionalProperties: false
required: [query]
properties:
query: { type: string, minLength: 1, maxLength: 500 }
limit: { type: integer, minimum: 1, maximum: 5, default: 3 }
MemoryToolResult:
type: object
additionalProperties: false
required: [memory_id, memory_version_id, version_no, content, source_refs, relevance]
properties:
memory_id: { type: string, format: uuid }
memory_version_id: { type: string, format: uuid }
version_no: { type: integer, format: int64, minimum: 1 }
content: { type: string, maxLength: 241 }
source_refs: { type: array, items: { type: object, additionalProperties: true } }
relevance: { type: number }
MemoryToolSearchData:
type: object
additionalProperties: false
required: [items, degraded]
properties:
items: { type: array, maxItems: 5, items: { $ref: '#/components/schemas/MemoryToolResult' } }
degraded: { type: boolean }
MemoryToolSearchResponse:
type: object
additionalProperties: false
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/MemoryToolSearchData' }
2026-08-26 06:41:07 +08:00
PrivacyCategory:
type: string
enum: [profile, consents, device_bindings, conversations, transcripts, summaries, stories, memories]
CreatePrivacyRequest:
type: object
additionalProperties: false
required: [request_type, scope]
properties:
2026-08-29 21:56:51 +08:00
request_type: { type: string, enum: [ACCESS, CORRECTION, CONSENT_WITHDRAWAL, DELETE] }
2026-08-26 06:41:07 +08:00
scope:
type: object
additionalProperties: false
properties:
categories:
type: array
uniqueItems: true
items: { $ref: '#/components/schemas/PrivacyCategory' }
2026-08-29 21:56:51 +08:00
consent_types:
type: array
minItems: 1
uniqueItems: true
items: { $ref: '#/components/schemas/ConsentType' }
corrections:
type: object
additionalProperties: false
minProperties: 1
properties:
preferred_name: { type: string, minLength: 1, maxLength: 120 }
language: { type: string, minLength: 2, maxLength: 20 }
timezone: { type: string, minLength: 1, maxLength: 100 }
profile_data: { type: object, additionalProperties: true }
conversation_preferences: { type: object, additionalProperties: true }
2026-08-26 06:41:07 +08:00
reason: { type: string, minLength: 1, maxLength: 500, description: DELETE申请必填;正文不会持久化,仅保存摘要。 }
confirmation: { type: string, minLength: 1, maxLength: 120, description: DELETE申请必填,必须与当前主体称呼完全一致且不会持久化。 }
allOf:
2026-08-29 21:56:51 +08:00
- if:
properties: { request_type: { const: CORRECTION } }
then:
properties:
scope: { required: [corrections] }
- if:
properties: { request_type: { const: CONSENT_WITHDRAWAL } }
then:
properties:
scope: { required: [consent_types] }
2026-08-26 06:41:07 +08:00
- if:
properties: { request_type: { const: DELETE } }
then:
required: [reason, confirmation]
PrivacySubtask:
type: object
additionalProperties: false
required: [id, subsystem, target_type, target_ref, status, attempts]
properties:
id: { type: string, format: uuid }
subsystem: { type: string, enum: [postgresql, redis, object_storage, pgvector, provider_index, export_files] }
target_type: { type: string }
target_ref: { type: string }
status: { type: string, enum: [PENDING, RUNNING, COMPLETED, FAILED, SKIPPED] }
attempts: { type: integer, minimum: 0 }
next_attempt_at: { type: string, format: date-time }
last_error: { type: string }
completed_at: { type: string, format: date-time }
PrivacyRequest:
type: object
additionalProperties: false
required: [id, subject_id, request_type, scope, status, legal_hold, result_summary, version, created_at, updated_at, subtasks]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
request_type: { type: string, enum: [ACCESS, CORRECTION, CONSENT_WITHDRAWAL, DELETE] }
scope: { type: object, additionalProperties: true }
status: { type: string, enum: [SUBMITTED, VERIFYING, EXECUTING, COMPLETED, PARTIAL_FAILED] }
deadline_at: { type: string, format: date-time }
legal_hold: { type: boolean }
result_summary: { type: object, additionalProperties: true }
version: { type: integer, format: int64, minimum: 1 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
completed_at: { type: string, format: date-time }
subtasks: { type: array, items: { $ref: '#/components/schemas/PrivacySubtask' } }
CreateExportTask:
type: object
additionalProperties: false
required: [scope]
properties:
scope:
type: object
additionalProperties: false
properties:
categories:
type: array
uniqueItems: true
items: { $ref: '#/components/schemas/PrivacyCategory' }
ExportTask:
type: object
additionalProperties: false
required: [id, subject_id, scope, status, attempts, created_at, updated_at]
properties:
id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
scope: { type: object, additionalProperties: true }
status: { type: string, enum: [QUEUED, RUNNING, READY, FAILED, EXPIRED] }
object_size: { type: integer, format: int64, minimum: 0 }
content_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
expires_at: { type: string, format: date-time }
attempts: { type: integer, minimum: 0 }
last_error: { type: string, maxLength: 500 }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
completed_at: { type: string, format: date-time }
download_url: { type: string, format: uri }
download_until: { type: string, format: date-time }
DeviceBinding:
type: object
required: [bound]
properties:
bound: { type: boolean }
household_id: { type: string, format: uuid }
subject_id: { type: string, format: uuid }
subject_name: { type: string }
DeviceBootstrap:
type: object
required: [device_id, status, model, firmware_compatible, config_revision, binding]
properties:
device_id: { type: string, format: uuid }
status: { type: string, enum: [registered, quarantined, revoked] }
model: { type: string }
hardware_revision: { type: string }
minimum_security_version: { type: string }
minimum_firmware_version: { type: string }
firmware_compatible: { type: boolean, description: 本次上报固件是否满足最低固件策略;false时不得创建新通话。 }
config_revision: { type: integer, format: int64, minimum: 1 }
binding: { $ref: '#/components/schemas/DeviceBinding' }
DeviceBootstrapData:
type: object
required: [server_time, clock_skew_ms, device]
properties:
server_time: { type: string, format: date-time }
clock_skew_ms: { type: integer, format: int64 }
device: { $ref: '#/components/schemas/DeviceBootstrap' }
DeviceConfiguration:
type: object
required: [device_id, revision, desired_config, binding]
properties:
device_id: { type: string, format: uuid }
revision: { type: integer, format: int64, minimum: 1 }
desired_config: { type: object, additionalProperties: true }
reported_revision: { type: integer, format: int64, minimum: 1 }
binding: { $ref: '#/components/schemas/DeviceBinding' }
DeviceCapabilities:
type: object
required: [rtc, audio_tracks, upload_resume]
properties:
rtc: { type: boolean, const: true }
audio_tracks:
type: array
minItems: 1
uniqueItems: true
items: { type: string, enum: [near, far] }
upload_resume: { type: boolean }
rtc_credential_renewal:
type: boolean
description: 可选能力协商位。仅明确为true时心跳才可能返回renew_rtc_credential;省略时保持旧版v2终端行为。
DeviceNetwork:
type: object
required: [type]
properties:
type: { type: string, minLength: 1, maxLength: 40 }
rssi: { type: integer }
CreateConversationRequest:
type: object
additionalProperties: false
required: [device_time, capabilities, network, requested_goal]
properties:
device_time: { type: string, format: date-time }
monotonic_ms: { type: integer, format: int64, minimum: 0 }
capabilities: { $ref: '#/components/schemas/DeviceCapabilities' }
network: { $ref: '#/components/schemas/DeviceNetwork' }
requested_goal: { type: string, const: open_conversation }
RTCGrant:
type: object
required: [app_id, room_id, user_id, agent_user_id, token, expires_at]
properties:
app_id: { type: string }
room_id: { type: string }
user_id: { type: string }
agent_user_id: { type: string }
token:
type: string
description: 绑定房间和设备用户的短期凭证;只允许保存在设备运行内存。
expires_at: { type: string, format: date-time }
ConversationPrivacy:
type: object
required: [retention_mode, record_near, record_far, upload_allowed]
properties:
retention_mode: { type: string, enum: [none, transcript_only, transcript_and_audio] }
record_near: { type: boolean }
record_far: { type: boolean }
upload_allowed: { type: boolean }
ConversationSession:
type: object
required: [engine_mode, heartbeat_interval_sec, allocation_expires_at]
properties:
engine_mode:
type: string
enum: [s2s_pure, s2s_hybrid, cascade]
description: 仅用于云端诊断、成本和通话记录;设备不得据此改变采集、编码、发布、订阅或播放逻辑。
heartbeat_interval_sec: { type: integer, minimum: 1 }
allocation_expires_at: { type: string, format: date-time }
CreatedConversation:
type: object
required: [conversation_id, status, rtc, privacy, session]
properties:
conversation_id: { type: string, format: uuid }
status: { type: string, const: ROOM_ISSUED }
rtc: { $ref: '#/components/schemas/RTCGrant' }
privacy: { $ref: '#/components/schemas/ConversationPrivacy' }
session: { $ref: '#/components/schemas/ConversationSession' }
ActivateConversationRequest:
type: object
additionalProperties: false
required: [joined_at, room_id, rtc_user_id, rtc_join_result, config_revision]
properties:
joined_at: { type: string, format: date-time }
room_id: { type: string, minLength: 1, maxLength: 200 }
rtc_user_id: { type: string, minLength: 1, maxLength: 200 }
rtc_join_result: { type: string, const: success }
config_revision: { type: integer, format: int64, minimum: 1 }
connection_reference: { type: string, maxLength: 255 }
ActivatedConversation:
type: object
required: [conversation_id, status, accepted_at]
properties:
conversation_id: { type: string, format: uuid }
status: { type: string, enum: [STARTING_AGENT, ACTIVE] }
accepted_at: { type: string, format: date-time }
DeviceConversationState:
type: object
additionalProperties: false
required: [conversation_id, status, action]
properties:
conversation_id: { type: string, format: uuid }
status: { $ref: '#/components/schemas/ConversationStatus' }
action:
type: string
enum: [wait, continue, leave_room]
description: wait表示继续等待智能体启动,continue表示进入正常通话,leave_room表示立即退出RTC房间。
failure_code:
type: string
description: FAILED状态下返回稳定脱敏失败码,例如provider_start_rejected或provider_start_failed;不得展示供应商原始错误。
RTCHeartbeat:
type: object
additionalProperties: false
required: [joined, uplink, downlink]
properties:
joined: { type: boolean }
uplink: { type: boolean }
downlink: { type: boolean }
RecordingQueue:
type: object
additionalProperties: false
required: [pending_segments, failed_segments]
properties:
pending_segments: { type: integer, minimum: 0 }
failed_segments: { type: integer, minimum: 0 }
last_failure_code: { type: string, maxLength: 80, description: 最近一次录音上传失败的稳定脱敏错误码 }
last_failure_at: { type: string, format: date-time }
HeartbeatConversationRequest:
type: object
additionalProperties: false
required: [sequence_no, device_time, monotonic_ms, conversation_status, rtc, network, firmware_version, reported_config_revision, recording_queue, command_results]
properties:
sequence_no: { type: integer, format: int64, minimum: 1 }
device_time: { type: string, format: date-time }
monotonic_ms: { type: integer, format: int64, minimum: 0 }
conversation_status:
type: string
enum: [PREPARING, ROOM_ISSUED, STARTING_AGENT, ACTIVE, STOPPING, COMPLETED, FAILED, EXPIRED]
rtc: { $ref: '#/components/schemas/RTCHeartbeat' }
network: { $ref: '#/components/schemas/DeviceNetwork' }
firmware_version: { type: string, minLength: 1, maxLength: 80 }
reported_config_revision: { type: integer, format: int64, minimum: 1 }
recording_queue: { $ref: '#/components/schemas/RecordingQueue' }
rtc_credential_expires_at: { type: string, format: date-time, description: 设备当前使用的短期入房凭证过期时间;用于可靠续签与响应重放 }
last_error: { type: string, maxLength: 80, pattern: '^[A-Za-z0-9_.:-]*$' }
command_results:
type: array
maxItems: 20
items: { type: object, additionalProperties: true }
DeviceTelemetryStatus:
type: object
additionalProperties: false
required: [firmware_version, reported_config_revision, network, rtc, recording_queue]
properties:
firmware_version: { type: string, minLength: 1, maxLength: 80 }
reported_config_revision: { type: integer, format: int64, minimum: 1 }
network: { $ref: '#/components/schemas/DeviceNetwork' }
rtc: { $ref: '#/components/schemas/RTCHeartbeat' }
recording_queue: { $ref: '#/components/schemas/RecordingQueue' }
conversation_status:
type: string
enum: [PREPARING, ROOM_ISSUED, STARTING_AGENT, ACTIVE, STOPPING, COMPLETED, FAILED, EXPIRED]
DeviceTelemetryError:
type: object
additionalProperties: false
required: [code, severity]
properties:
code: { type: string, minLength: 1, maxLength: 80, pattern: '^[A-Za-z0-9_.:-]+$' }
severity: { type: string, enum: [warning, error, critical] }
DeviceTelemetryCommandResult:
type: object
additionalProperties: false
required: [command_id, status, result_summary]
properties:
command_id: { type: string, format: uuid }
status: { type: string, enum: [ACKNOWLEDGED, SUCCEEDED, FAILED] }
result_summary:
type: object
additionalProperties: true
description: 只允许有限诊断结果,不得包含secret、token、password、credential、private_key或api_key字段。
DeviceTelemetryEvent:
type: object
additionalProperties: false
required: [event_key, sequence_no, occurred_at, event_type]
properties:
event_key: { type: string, minLength: 1, maxLength: 255, pattern: '^[A-Za-z0-9_.:-]+$' }
sequence_no: { type: integer, format: int64, minimum: 1 }
occurred_at: { type: string, format: date-time }
event_type: { type: string, enum: [status, error, command_result] }
conversation_id: { type: string, format: uuid }
status: { $ref: '#/components/schemas/DeviceTelemetryStatus' }
error: { $ref: '#/components/schemas/DeviceTelemetryError' }
command_result: { $ref: '#/components/schemas/DeviceTelemetryCommandResult' }
description: event_type对应的同名对象必须存在,另外两个对象必须省略。
DeviceTelemetryBatchRequest:
type: object
additionalProperties: false
required: [events]
properties:
events:
type: array
minItems: 1
maxItems: 500
description: 同一请求内event_key和sequence_no分别唯一。
items: { $ref: '#/components/schemas/DeviceTelemetryEvent' }
DeviceTelemetryAction:
type: object
additionalProperties: false
required: [type]
properties:
type: { type: string, enum: [refresh_config, pull_commands, stop_conversation] }
conversation_id: { type: string, format: uuid }
DeviceTelemetryBatchResult:
type: object
required: [accepted_count, duplicate_count, desired_config_revision, actions]
properties:
accepted_count: { type: integer, minimum: 0 }
duplicate_count: { type: integer, minimum: 0 }
desired_config_revision: { type: integer, format: int64, minimum: 1 }
actions:
type: array
items: { $ref: '#/components/schemas/DeviceTelemetryAction' }
HeartbeatAction:
type: object
additionalProperties: false
required: [type]
properties:
type: { type: string, enum: [continue, stop, stop_after_turn, renew_rtc_credential] }
rtc:
allOf:
- { $ref: '#/components/schemas/RTCGrant' }
description: 仅renew_rtc_credential动作返回;凭证只保存在设备运行内存。
HeartbeatResult:
type: object
required: [actions, desired_config_revision, commands]
properties:
lease_expires_at: { type: string, format: date-time }
actions:
type: array
minItems: 1
items: { $ref: '#/components/schemas/HeartbeatAction' }
desired_config_revision: { type: integer, format: int64, minimum: 1 }
commands:
type: array
items: { type: object, additionalProperties: true }
StopRecording:
type: object
additionalProperties: false
required: [near_segments, far_segments]
properties:
near_segments: { type: integer, minimum: 0 }
far_segments: { type: integer, minimum: 0 }
StopConversationRequest:
type: object
additionalProperties: false
required: [reason, device_time, last_heartbeat_sequence, rtc_left, recording]
properties:
reason: { type: string, minLength: 1, maxLength: 64, pattern: '^[A-Za-z0-9_.:-]+$' }
device_time: { type: string, format: date-time }
last_heartbeat_sequence: { type: integer, format: int64, minimum: 0 }
rtc_left: { type: boolean }
recording: { $ref: '#/components/schemas/StopRecording' }
StoppedConversation:
type: object
required: [conversation_id, status, accepted_at]
properties:
conversation_id: { type: string, format: uuid }
status: { type: string, enum: [STOPPING, COMPLETED, FAILED, EXPIRED] }
accepted_at: { type: string, format: date-time }
VoiceProviderEvent:
type: object
additionalProperties: false
required: [provider, event_id, task_ref, conversation_id, event_type, status, occurred_at]
properties:
provider: { type: string, enum: [mock, vertc] }
event_id: { type: string, minLength: 1, maxLength: 255 }
task_ref: { type: string, minLength: 1, maxLength: 200 }
conversation_id: { type: string, format: uuid }
event_type: { type: string, enum: [voice_chat.started, voice_chat.transcript.final, voice_chat.usage, voice_chat.stopped, voice_chat.failed] }
status: { type: string, enum: [ACTIVE, FINAL, COMPLETED, FAILED] }
occurred_at: { type: string, format: date-time }
turns:
type: array
maxItems: 500
description: 仅voice_chat.transcript.final事件允许携带最终话轮;状态事件必须为空。
items: { $ref: '#/components/schemas/ProviderFinalTurn' }
usage:
type: array
maxItems: 100
description: 仅voice_chat.usage最终事件允许携带;同一供应商事件键重复投递只计一次费用。
items: { $ref: '#/components/schemas/ProviderUsageMetric' }
ProviderUsageMetric:
type: object
additionalProperties: false
required: [usage_category, metric_code, quantity, unit]
properties:
usage_category: { type: string, enum: [RTC, END_TO_END_VOICE, ASR, LLM, TTS, STORAGE, POST_PROCESSING] }
metric_code: { type: string, pattern: '^[a-z][a-z0-9_.-]{1,79}$' }
quantity: { type: string, pattern: '^(0|[1-9][0-9]{0,17})(\.[0-9]{1,6})?$' }
unit: { type: string, pattern: '^[a-z][a-z0-9_.-]{1,39}$' }
ProviderFinalTurn:
type: object
additionalProperties: false
required: [turn_key, sequence_no, speaker, start_at, end_at, final_text, interrupted]
properties:
turn_key: { type: string, minLength: 1, maxLength: 255 }
sequence_no: { type: integer, format: int64, minimum: 1 }
speaker: { type: string, enum: [subject, agent] }
start_at: { type: string, format: date-time }
end_at: { type: string, format: date-time }
final_text: { type: string, minLength: 1, maxLength: 20000 }
interrupted: { type: boolean }
provider_ref: { type: string, maxLength: 255 }
DeviceFinalTurn:
type: object
additionalProperties: false
required: [turn_key, sequence_no, speaker, start_at, end_at, final_text, interrupted]
properties:
turn_key: { type: string, minLength: 1, maxLength: 255 }
sequence_no: { type: integer, format: int64, minimum: 1 }
speaker: { type: string, enum: [subject, agent] }
start_at: { type: string, format: date-time }
end_at: { type: string, format: date-time, description: 必须不早于start_at。 }
final_text: { type: string, minLength: 1, maxLength: 20000 }
interrupted: { type: boolean }
DeviceTranscriptBatchRequest:
type: object
additionalProperties: false
required: [turns]
properties:
turns:
type: array
minItems: 1
maxItems: 500
description: 同一请求内turn_key和sequence_no分别唯一。
items: { $ref: '#/components/schemas/DeviceFinalTurn' }
DeviceTranscriptBatchResult:
type: object
required: [conversation_id, accepted_count, duplicate_count]
properties:
conversation_id: { type: string, format: uuid }
accepted_count: { type: integer, minimum: 0 }
duplicate_count: { type: integer, minimum: 0 }
ProviderCallbackResult:
type: object
required: [conversation_id, status, duplicate, ignored]
properties:
conversation_id: { type: string, format: uuid }
status: { type: string, enum: [PREPARING, ROOM_ISSUED, STARTING_AGENT, ACTIVE, STOPPING, COMPLETED, FAILED, EXPIRED] }
duplicate: { type: boolean }
ignored: { type: boolean }
turns_accepted: { type: integer, minimum: 0 }
usage_accepted: { type: integer, minimum: 0 }
APIError:
type: object
required: [code, message, retryable, field_errors, details]
properties:
code: { type: string }
message: { type: string }
retryable: { type: boolean }
field_errors:
type: array
items:
type: object
required: [field, message]
properties:
field: { type: string }
message: { type: string }
details: { type: object, additionalProperties: true }
LivenessResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/Liveness' }
ReadinessResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/Readiness' }
VersionResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/BuildInfo' }
CurrentUserResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/CurrentUser' }
HouseholdResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/Household' }
HouseholdListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/Household' } }
HouseholdMemberResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/HouseholdMember' }
HouseholdMemberListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/HouseholdMember' } }
MemberInvitationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/MemberInvitation' }
MemberInvitationListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/MemberInvitation' } }
MemberInvitationPreviewResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/MemberInvitationPreview' }
SubjectResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/Subject' }
ConversationReadinessResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ConversationReadiness' }
SubjectListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/Subject' } }
SubjectFactResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/SubjectFact' }
SubjectFactListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/SubjectFact' } }
ConsentResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/Consent' }
ConsentListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/Consent' } }
ManagedDeviceResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ManagedDevice' }
2026-08-29 21:56:51 +08:00
DeviceBindingImpactResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceBindingImpact' }
DeviceBindingChangeResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceBindingChangeResult' }
2026-08-26 06:41:07 +08:00
DeviceClaimResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceClaimResult' }
ManagedDeviceListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/ManagedDevice' } }
DevicePresenceResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DevicePresence' }
DeviceTwinResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceTwin' }
DeviceCommandResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceCommand' }
DeviceCommandListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/DeviceCommand' } } }
DeviceCommandDeliveryResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceCommandDelivery' }
DeviceCommandDeliveryListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/DeviceCommandDelivery' } } }
MediaUploadBatchResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/MediaUploadBatch' }
RecordingAccessGrantResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/RecordingAccessGrant' }
RecordingAccessGrantListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/RecordingAccessGrant' } } }
MediaSegmentResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/MediaSegment' }
ConversationMediaResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ConversationMedia' }
MediaAccessResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/MediaAccess' }
FirmwareReleaseResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/FirmwareRelease' }
FirmwareReleaseImpactResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/FirmwareReleaseImpact' }
FirmwareSigningKeyResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/FirmwareSigningKey' }
FirmwareSigningKeyListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/FirmwareSigningKey' } } }
FirmwareReleaseListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/FirmwareRelease' } } }
FirmwareRolloutResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/FirmwareRollout' }
FirmwareRolloutListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties: { items: { type: array, items: { $ref: '#/components/schemas/FirmwareRollout' } } }
ConversationPageResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/ConversationSummary' } }
next_cursor: { type: string }
ConversationDetailResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ConversationDetail' }
ConversationUsageResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ConversationUsage' }
ConversationTurnPageResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/ConversationTurn' } }
next_cursor: { type: string }
ConversationContentSummaryListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/ConversationContentSummary' } }
ConversationSummaryRegenerationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [generation_version, status]
properties:
generation_version: { type: integer, format: int64, minimum: 1 }
status: { type: string, enum: [queued] }
ContentModelResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ContentModel' }
ContentModelListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/ContentModel' } }
2026-08-26 06:41:07 +08:00
StoryResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/Story' }
2026-08-29 21:56:51 +08:00
FactCandidateResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/FactCandidate' }
2026-08-26 06:41:07 +08:00
StoryListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/Story' } }
StoryConfirmationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [story, memory]
properties:
story: { $ref: '#/components/schemas/Story' }
memory: { $ref: '#/components/schemas/CuratedMemory' }
CuratedMemoryResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/CuratedMemory' }
CuratedMemoryListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/CuratedMemory' } }
PrivacyRequestResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/PrivacyRequest' }
PrivacyRequestListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/PrivacyRequest' } }
ExportTaskResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ExportTask' }
ExportTaskListResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data:
type: object
required: [items]
properties:
items: { type: array, items: { $ref: '#/components/schemas/ExportTask' } }
DeviceBootstrapResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceBootstrapData' }
DeviceConfigResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceConfiguration' }
CreateConversationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/CreatedConversation' }
ActivateConversationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ActivatedConversation' }
DeviceConversationStateResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceConversationState' }
HeartbeatConversationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/HeartbeatResult' }
StopConversationResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/StoppedConversation' }
DeviceTranscriptBatchResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceTranscriptBatchResult' }
DeviceTelemetryBatchResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/DeviceTelemetryBatchResult' }
ProviderCallbackResponse:
type: object
required: [request_id, data]
properties:
request_id: { type: string }
data: { $ref: '#/components/schemas/ProviderCallbackResult' }
ErrorResponse:
type: object
required: [request_id, error]
properties:
request_id: { type: string }
error: { $ref: '#/components/schemas/APIError' }