12 KiB
12 KiB
设备相关外部接口表
范围仅包含设备终端以 HMAC 身份直接调用的 /device/v2/* 外部接口;不包含家庭/运营 Web API、内部工具和供应商回调。基于 openapi/openapi.yaml(OpenAPI 3.1,版本 0.70.0)生成,并与 internal/httpapi/router.go 的实际路由逐项核对。当前共 16 个已注册且纳入 OpenAPI 契约的接口。
说明:* 表示必填字段;body 表示请求体;响应栏只展开成功响应。全部接口都要求设备 HMAC 请求头:X-Device-Id、X-Device-Timestamp、X-Device-Nonce、X-Device-Content-SHA256、X-Device-Signature,表内不重复。通用错误响应为 ErrorResponse。
设备端 v2
| 接口名字 | 方法与路径 | 接口描述 | 输入参数 | 输出参数 |
|---|---|---|---|---|
getDeviceBootstrap |
GET /device/v2/bootstrap |
返回可信设备状态、服务器时间、绑定和最低安全版本 | query firmware_version*: stringquery board_rev: stringquery rtc_sdk_version: stringquery codec: stringquery sample_rate: integerquery device_time*: string(date-time)query network: string |
200 DeviceBootstrapResponse{data*:DeviceBootstrapData{clock_skew_ms*:integer(int64), device*:DeviceBootstrap, server_time*:string(date-time)}, request_id*:string} — 返回可信设备状态、服务器时间、绑定和最低安全版本 |
pullDeviceCommands |
GET /device/v2/commands |
返回未过期的待执行命令并记录投递次数 | query limit: integer |
200 DeviceCommandDeliveryListResponse{data*:object{items*:array}, request_id*:string} — 返回未过期的待执行命令并记录投递次数 |
acknowledgeDeviceCommand |
POST /device/v2/commands/{id}/ack |
回执已保存 | path id*: string(uuid)body* application/json DeviceCommandAckRequest{result_summary*:object, status*:string[ACKNOWLEDGED/SUCCEEDED/FAILED]} |
200 DeviceCommandDeliveryResponse{data*:DeviceCommandDelivery{created_at*:string(date-time), delivery_attempts*:integer, expires_at*:string(date-time), id*:string(uuid), payload*:object, status*:DeviceCommandStatus, type*:string[apply_config/reboot/diagnostics/firmware_update]}, request_id*:string} — 回执已保存 |
getDeviceConfig |
GET /device/v2/config |
返回设备期望配置及当前绑定 | header If-None-Match: string |
200 DeviceConfigResponse{data*:DeviceConfiguration{binding*:DeviceBinding, desired_config*:object, device_id*:string(uuid), reported_revision:integer(int64), revision*:integer(int64)}, request_id*:string};headers{ETag:string} — 返回设备期望配置及当前绑定 304 无响应体 — 配置未变化 |
createDeviceConversation |
POST /device/v2/conversations |
分配房间和短期入房凭证;此步骤不启动语音智能体。 | header Idempotency-Key*: stringbody* application/json CreateConversationRequest{capabilities*:DeviceCapabilities{audio_tracks*:array<string[near/far]>, rtc*:boolean, rtc_credential_renewal:boolean, upload_resume*:boolean}, device_time*:string(date-time), monotonic_ms:integer(int64), network*:DeviceNetwork{rssi:integer, type*:string}, requested_goal*:string} |
201 CreateConversationResponse{data*:CreatedConversation{conversation_id*:string(uuid), privacy*:ConversationPrivacy, rtc*:RTCGrant, session*:ConversationSession, status*:string}, request_id*:string};headers{Idempotency-Replayed:string[true]} — 房间资料已分配;重复请求返回相同通话和相同确定性短期Token |
getDeviceConversationState |
GET /device/v2/conversations/{id} |
设备确认入房后读取云端权威通话状态和下一步动作;供应商永久拒绝启动或异步启动失败时返回稳定failure_code及leave_room,响应不包含供应商原始错误。 | path id*: string(uuid) |
200 DeviceConversationStateResponse{data*:DeviceConversationState{action*:string[wait/continue/leave_room], conversation_id*:string(uuid), failure_code:string, status*:ConversationStatus}, request_id*:string} — 返回当前设备所属通话的权威状态和设备动作 |
activateDeviceConversation |
POST /device/v2/conversations/{id}/activate |
设备确认已进入指定RTC房间后,投递固定供应商语音任务。 | path id*: string(uuid)header Idempotency-Key*: stringbody* application/json ActivateConversationRequest{config_revision*:integer(int64), connection_reference:string, joined_at*:string(date-time), room_id*:string, rtc_join_result*:string, rtc_user_id*:string} |
202 ActivateConversationResponse{data*:ActivatedConversation{accepted_at*:string(date-time), conversation_id*:string(uuid), status*:string[STARTING_AGENT/ACTIVE]}, request_id*:string} — 入房确认已接受;语音智能体正在启动或已经启动 |
heartbeatDeviceConversation |
POST /device/v2/conversations/{id}/heartbeat |
按严格递增序号刷新设备在线状态和通话短期租约;重复或乱序心跳不会延长租约。 | path id*: string(uuid)body* application/json HeartbeatConversationRequest{command_results*:array |
200 HeartbeatConversationResponse{data*:HeartbeatResult{actions*:array, commands*:array |
stopDeviceConversation |
POST /device/v2/conversations/{id}/stop |
记录设备挂断并可靠停止固定供应商任务;重复执行不产生第二个外部副作用。 | path id*: string(uuid)header Idempotency-Key*: stringbody* application/json StopConversationRequest{device_time*:string(date-time), last_heartbeat_sequence*:integer(int64), reason*:string, recording*:StopRecording{far_segments*:integer, near_segments*:integer}, rtc_left*:boolean} |
202 StopConversationResponse{data*:StoppedConversation{accepted_at*:string(date-time), conversation_id*:string(uuid), status*:string[STOPPING/COMPLETED/FAILED/EXPIRED]}, request_id*:string};headers{Idempotency-Replayed:string[true]} — 停止请求已接受,或通话已经处于停止中/终态 |
submitDeviceConversationTurns |
POST /device/v2/conversations/{id}/turns:batch |
当供应商最终转写缺失时由当前通话所属终端批量补传终稿;平台按turn_key和sequence_no与已有供应商终稿原子去重合并,任一内容冲突会拒绝整批请求。 | path id*: string(uuid)header Idempotency-Key*: stringbody* application/json DeviceTranscriptBatchRequest{turns*:array} |
200 DeviceTranscriptBatchResponse{data*:DeviceTranscriptBatchResult{accepted_count*:integer, conversation_id*:string(uuid), duplicate_count*:integer}, request_id*:string};headers{Idempotency-Replayed:string[true]} — 整批终稿已合并;完全相同的已有终稿计入duplicate_count而不重复保存 |
prepareMediaUploadBatch |
POST /device/v2/conversations/{id}/upload-batches |
设备提交near/far录音分片清单;业务API仅返回单对象短期PUT地址,不接收录音字节。 | path id*: string(uuid)header Idempotency-Key*: stringbody* application/json PrepareMediaUploadBatchRequest{segments*:array} |
201 MediaUploadBatchResponse{data*:MediaUploadBatch{conversation_id*:string(uuid), expected_total_size*:integer(int64), expires_at*:string(date-time), id*:string(uuid), last_error_code:string, rejected_count*:integer, segment_count*:integer, segments*:array, status*:string[PENDING/UPLOADING/VERIFYING/COMPLETED/FAILED/EXPIRED], verification_attempts*:integer, verified_count*:integer}, request_id*:string} — 返回尚未验证分片的10至20分钟单对象上传地址 |
getDeviceFirmwareDownload |
GET /device/v2/firmware-releases/{id}/download |
仅向当前灰度目标签发 5 分钟有效的私有下载地址 | path id*: string(uuid) |
200 application/json {download_url*:string(uri), download_until*:string(date-time)};header Cache-Control: no-store |
acknowledgeLocalMediaDelete |
POST /device/v2/media-segments/{id}/local-delete-ack |
设备在平台给出的local_delete_after之后删除本地密文并回报结果;该操作不删除云端已验证对象,DELETED重复回报幂等。 | path id*: string(uuid)body* application/json LocalMediaDeleteReceiptRequest{error_code:string, status*:string[DELETED/FAILED]} |
200 MediaSegmentResponse{data*:MediaSegment{codec*:string, content_type*:string, duration_ms*:integer, expected_digest*:string, expected_size*:integer(int64), id*:string(uuid), last_error_code:string, local_delete_after:string(date-time), local_delete_error_code:string, local_delete_reported_at:string(date-time), local_delete_status:string[DELETED/FAILED], sequence_no*:integer, status*:string[DECLARED/AUTHORIZED/UPLOADED/VERIFYING/VERIFIED/REJECTED/DELETED], track*:string[near/far], upload_until:string(date-time), upload_url:string(uri), verified_at:string(date-time)}, request_id*:string} — 已保存本地删除回执 |
submitDeviceTelemetry |
POST /device/v2/telemetry:batch |
当前签名设备批量上报状态、有限错误码和命令执行结果;平台以设备内event_key和sequence_no原子去重,更新设备影子、命令状态和与当前设备通话关联的异常回收信号。 | header Idempotency-Key*: stringbody* application/json DeviceTelemetryBatchRequest{events*:array} |
200 DeviceTelemetryBatchResponse{data*:DeviceTelemetryBatchResult{accepted_count*:integer, actions*:array, desired_config_revision*:integer(int64), duplicate_count*:integer}, request_id*:string};headers{Idempotency-Replayed:string[true]} — 整批遥测已接收;完全相同的已有事件计入duplicate_count |
getDeviceMediaUploadBatch |
GET /device/v2/upload-batches/{id} |
返回分片校验结果;只有VERIFIED分片才包含local_delete_after | path id*: string(uuid) |
200 MediaUploadBatchResponse{data*:MediaUploadBatch{conversation_id*:string(uuid), expected_total_size*:integer(int64), expires_at*:string(date-time), id*:string(uuid), last_error_code:string, rejected_count*:integer, segment_count*:integer, segments*:array, status*:string[PENDING/UPLOADING/VERIFYING/COMPLETED/FAILED/EXPIRED], verification_attempts*:integer, verified_count*:integer}, request_id*:string} — 返回分片校验结果;只有VERIFIED分片才包含local_delete_after |
completeMediaUploadBatch |
POST /device/v2/upload-batches/{id}/complete |
设备声明本批上传完成,平台可靠投递后台对象校验任务;重复提交不会创建重复任务。 | path id*: string(uuid) |
202 MediaUploadBatchResponse{data*:MediaUploadBatch{conversation_id*:string(uuid), expected_total_size*:integer(int64), expires_at*:string(date-time), id*:string(uuid), last_error_code:string, rejected_count*:integer, segment_count*:integer, segments*:array, status*:string[PENDING/UPLOADING/VERIFYING/COMPLETED/FAILED/EXPIRED], verification_attempts*:integer, verified_count*:integer}, request_id*:string} — 批次已进入VERIFYING或已经完成 |