6900 lines
349 KiB
YAML
6900 lines
349 KiB
YAML
openapi: 3.1.0
|
||
info:
|
||
title: 数据采集终端—云端系统 API
|
||
version: 0.73.0
|
||
description: 工程框架、SaaS核心业务、设备v2能力协商与智能体启动状态查询、首次通话就绪与最低固件门禁、背景资料准备失败闭环、活动通话授权撤回安全停止、语音内容闭环、终端终稿补传、批量设备遥测、录音上传队列、隐私对账、固件、双轨录音、状态事件、具体资源分享、受控运营配置、Agent组合组件引用、质量证据门禁、运营自定义版本族投放、新通话运行时冻结与供应商启动传递、带并发版本校验的配置投放暂停恢复、带严重度和验收证据门禁的联调问题闭环、含阻断告警定位、当前主机健康及生产部署标记、实际应用环境、身份服务模式、异地备份、外部告警与模拟服务强制条件的发布候选技术验收快照、绑定候选版本与构建摘要并按业务时区生成的可审计试点日/周运行证据、可审计且不生成正式告警的接收器联通测试、外部依赖预检台账、证书到期清单,以及带价格版本冻结、供应商用量去重和硬额度控制的费用治理接口。
|
||
servers:
|
||
- url: http://localhost:58080
|
||
description: 本地开发
|
||
paths:
|
||
/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' }
|
||
/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' }
|
||
/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' }
|
||
/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' }
|
||
/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' }
|
||
/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' }
|
||
/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' }
|
||
'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' } } }
|
||
/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' } } } }
|
||
/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' }
|
||
/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' } } }
|
||
/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' }
|
||
/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' }
|
||
/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' }
|
||
/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':
|
||
description: 请求已受理。ACCESS和DELETE进入后台处理;CORRECTION与CONSENT_WITHDRAWAL在受理事务中完成并返回COMPLETED。
|
||
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' }
|
||
/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' } } } }
|
||
components:
|
||
securitySchemes:
|
||
oidcBearer:
|
||
type: openIdConnect
|
||
openIdConnectUrl: http://localhost:58180/realms/voice-local/.well-known/openid-configuration
|
||
memoryToolBearer:
|
||
type: http
|
||
scheme: bearer
|
||
bearerFormat: signed-conversation-token
|
||
description: Worker在启动s2s_hybrid任务时签发的短期令牌,固定绑定通话和供应商任务。
|
||
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签名。
|
||
platformHealthSignature:
|
||
type: apiKey
|
||
in: header
|
||
name: X-Platform-Signature
|
||
description: 使用独立密钥对Unix时间戳、点号和原始健康报告正文计算的HMAC-SHA256十六进制签名,格式为sha256=摘要。
|
||
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 }
|
||
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}$' }
|
||
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' }
|
||
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' }
|
||
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 }
|
||
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
|
||
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] }
|
||
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 }
|
||
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] }
|
||
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]
|
||
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' }
|
||
external_dependencies: { type: array, minItems: 1, maxItems: 4, items: { $ref: '#/components/schemas/OpsAcceptanceDependencyState' } }
|
||
outbox: { $ref: '#/components/schemas/OpsAcceptanceOutboxState' }
|
||
alerts: { $ref: '#/components/schemas/OpsAcceptanceAlertState' }
|
||
platform_health: { $ref: '#/components/schemas/OpsAcceptancePlatformHealthState' }
|
||
production_infrastructure: { $ref: '#/components/schemas/OpsAcceptanceProductionInfrastructureState' }
|
||
gates: { type: array, minItems: 8, maxItems: 8, items: { $ref: '#/components/schemas/OpsAcceptanceGate' } }
|
||
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' }
|
||
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' }
|
||
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]
|
||
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 }
|
||
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
|
||
required: [user_id, tenant_id, tenant_name, policy_version, platform_role, account_kind, display_name, household_memberships]
|
||
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] }
|
||
account_kind: { type: string, enum: [customer, operator], description: 家庭账号和运维账号的强制身份边界。 }
|
||
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 }
|
||
avoided_topics:
|
||
type: array
|
||
maxItems: 8
|
||
description: 不希望智能体主动提及的话题;长者主动提及时先简短共情并自然转向,紧急安全响应不受此限制。
|
||
items: { type: string, minLength: 1, maxLength: 50 }
|
||
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
|
||
required: [id, binding_id, household_id, subject_id, subject_name, model, status, desired_revision, bound_at, registered_at, version]
|
||
properties:
|
||
id: { type: string, format: uuid }
|
||
binding_id: { type: string, format: uuid, description: 当前有效绑定编号;解绑或转移时用于并发校验。 }
|
||
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 }
|
||
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 }
|
||
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:
|
||
claim_code: { type: string, minLength: 16, maxLength: 128, writeOnly: true, description: 设备屏幕显示或维护端生成的一次性绑定码;不能填写设备公开UUID。 }
|
||
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 }
|
||
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 }
|
||
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 }
|
||
ContentModelProvider:
|
||
type: string
|
||
description: 模型厂商分类;所有类型均通过 OpenAI Chat Completions 兼容协议调用。
|
||
enum: [ark, dashscope, deepseek, moonshot, zhipu, qianfan, hunyuan, minimax, baichuan, siliconflow, ollama, openai_compatible]
|
||
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 }
|
||
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 }
|
||
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
|
||
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]
|
||
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 }
|
||
provider_index_status: { type: string, enum: [DISABLED, PENDING, ACTIVE, STALE, FAILED, DELETED] }
|
||
provider_index_error: { type: string }
|
||
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 }
|
||
error_type: { $ref: '#/components/schemas/ContentErrorType' }
|
||
reason: { type: string, minLength: 1, maxLength: 500 }
|
||
StoryDecisionRequest:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [reason]
|
||
properties:
|
||
error_type: { $ref: '#/components/schemas/ContentErrorType' }
|
||
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] }
|
||
error_type: { $ref: '#/components/schemas/ContentErrorType' }
|
||
reason: { type: string, minLength: 1, maxLength: 500 }
|
||
anyOf:
|
||
- required: [content]
|
||
- required: [status]
|
||
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' }
|
||
PrivacyCategory:
|
||
type: string
|
||
enum: [profile, consents, device_bindings, conversations, transcripts, summaries, stories, memories]
|
||
CreatePrivacyRequest:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [request_type, scope]
|
||
properties:
|
||
request_type: { type: string, enum: [ACCESS, CORRECTION, CONSENT_WITHDRAWAL, DELETE] }
|
||
scope:
|
||
type: object
|
||
additionalProperties: false
|
||
properties:
|
||
categories:
|
||
type: array
|
||
uniqueItems: true
|
||
items: { $ref: '#/components/schemas/PrivacyCategory' }
|
||
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 }
|
||
reason: { type: string, minLength: 1, maxLength: 500, description: DELETE申请必填;正文不会持久化,仅保存摘要。 }
|
||
confirmation: { type: string, minLength: 1, maxLength: 120, description: DELETE申请必填,必须与当前主体称呼完全一致且不会持久化。 }
|
||
allOf:
|
||
- if:
|
||
properties: { request_type: { const: CORRECTION } }
|
||
then:
|
||
properties:
|
||
scope: { required: [corrections] }
|
||
- if:
|
||
properties: { request_type: { const: CONSENT_WITHDRAWAL } }
|
||
then:
|
||
properties:
|
||
scope: { required: [consent_types] }
|
||
- 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' }
|
||
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' }
|
||
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' } }
|
||
StoryResponse:
|
||
type: object
|
||
required: [request_id, data]
|
||
properties:
|
||
request_id: { type: string }
|
||
data: { $ref: '#/components/schemas/Story' }
|
||
FactCandidateResponse:
|
||
type: object
|
||
required: [request_id, data]
|
||
properties:
|
||
request_id: { type: string }
|
||
data: { $ref: '#/components/schemas/FactCandidate' }
|
||
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' }
|