# 首次接入接口字段清单 由 `node scripts/generate-onboarding-contract.mjs` 根据实际Go请求结构生成。共 31 项操作。完整响应结构见 [OpenAPI](../openapi/onboarding.yaml),流程、签名、错误恢复见 [实施说明](onboarding-implementation.md)。 ## C01 校时挑战 `POST /api/v1/device/time-challenges` 调用身份:校时请求,无请求签名;设备必须核验TIME1响应MAC | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | device_id | string | 是 | 生产编号,KP01-加12位大写MAC;不是平台UUID | | key_version | integer | 是 | 设备认证密钥版本 | | boot_id | string | 是 | 每次启动生成并保持的UUID v4 | | client_nonce | string | 是 | 设备生成的16字节随机数,Base64URL无填充 | 响应:根对象直接返回 `{payload_b64,mac_hex}`。 ## C02 首次认证和启动注册 `POST /api/v1/device/register` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | challenge_id | string | 是 | C01签名校时返回的一次性挑战 | | boot_id | string | 是 | 每次启动生成并保持的UUID v4 | | hardware_model | string | 是 | 生产登记型号,当前为KP01 | | hardware_revision | string | 是 | 硬件修订号,注册必须与库存一致 | | firmware_version | string | 是 | 固件版本,用于兼容诊断 | | sdk_version | string | 是 | SDK版本,用于兼容诊断 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `RegisterResponse.data`。 ## C03 创建临时设置会话 `POST /api/v1/device/setup-sessions` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | boot_id | string | 是 | 每次启动生成并保持的UUID v4 | | local_setup_id | string | 是 | 设备本次设置入口UUID v4;重试保持不变 | | transport_profile | string | 是 | 固定LOCAL_WEB,表示设备提供本地网页入口 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `SetupResponse.data`。 ## C04 获取一次性手机入口 `POST /api/v1/device/handoffs` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | setup_id | string | 是 | 云端15分钟临时设置会话UUID | | local_setup_id | string | 是 | 设备本次设置入口UUID v4;重试保持不变 | | code_challenge | string | 是 | SHA256(ASCII verifier)的Base64URL无填充值 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `HandoffResponse.data`。 ## C05 查询状态和命令 `POST /api/v1/device/poll` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | setup_id | string | 是 | 云端15分钟临时设置会话UUID | | boot_id | string | 是 | 每次启动生成并保持的UUID v4 | | known_revision | integer | 是 | 设备已知状态版本;允许0 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `PollResponse.data`。 ## C06 物理按键确认绑定 `POST /api/v1/device/claim-confirmations` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | claim_id | string | 是 | 待物理确认的绑定申请UUID | | challenge | string | 是 | C05给设备的短时按键挑战,手机不能获取 | | binding_digest | string | 是 | 云端生成的绑定摘要,按键回报原值 | | expected_binding_generation | integer | 是 | 提交时预期绑定代数,防止跨解绑或重新绑定重放 | | press_event_id | string | 是 | 该次真实物理按键事件UUID v4,重试保持不变 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `ConfirmationResponse.data`。 ## C07 绑定状态持久化回执 `POST /api/v1/device/state-acks` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | device_revision | integer | 是 | 云端设备状态版本号 | | binding_generation | integer | 是 | 绑定代数;解绑、重新绑定后旧代数无效 | | local_generation | integer | 是 | 本次启动的本地持久化序号,不能倒退 | | state_hash | string | 是 | STATE1规范字符串的SHA256小写十六进制摘要 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `StateAckResponse.data`。 ## C08 申请设备执行许可 `POST /api/v1/device/activation-attempts` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | activation_id | string | 是 | 该物理设备唯一的激活任务UUID | | config_version | integer | 是 | 配置版本,必须与当前云端版本一致 | | attempt_id | string | 是 | 设备生成的UUID v4,表示一次引擎初始化或首通执行 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `AttemptResponse.data`。 ## C09 回报设备执行结果 `POST /api/v1/device/activation-results` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | activation_id | string | 是 | 该物理设备唯一的激活任务UUID | | attempt_id | string | 是 | 设备生成的UUID v4,表示一次引擎初始化或首通执行 | | stage | string | 是 | SDK_REGISTER或CONVERSATION_TEST;与C08平台当前阶段一致 | | sdk_result | integer | 是 | SDK执行返回码;SUCCESS_OBSERVED时必须为0 | | outcome | string | 是 | SUCCESS_OBSERVED、DEFINITE_FAILURE或UNKNOWN;未知结果不得盲目重试 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `ResultResponse.data`。 ## C10 激活结果保存回执 `POST /api/v1/device/activation-acks` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | activation_id | string | 是 | 该物理设备唯一的激活任务UUID | | local_generation | integer | 是 | 本次启动的本地持久化序号,不能倒退 | | config_version | integer | 是 | 配置版本,必须与当前云端版本一致 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `ActivationAckResponse.data`。 ## C11 关闭临时设置入口 `POST /api/v1/device/setup-close` 调用身份:设备DEVREQ1签名 | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | setup_id | string | 是 | 云端15分钟临时设置会话UUID | | reason | string | 是 | 关闭、轮换或人工处理原因,见对应枚举 | | final_revision | integer | 是 | 设备关闭设置入口前看到的最新状态版本 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `CloseResponse.data`。 ## 手机兑换一次性入口 `POST /api/v1/web/handoffs/exchange` 调用身份:同源网页;一次性token和verifier | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | token | string | 是 | 90秒内只能兑换一次的handoff令牌 | | verifier | string | 是 | 设备交给手机的PKCE校验值;32字节随机数的Base64URL无填充字符串 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `BrowserResponse.data`。 ## 恢复手机设置会话 `GET /api/v1/web/setup/session` 调用身份:设置Cookie + 写请求CSRF 无请求正文。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `BrowserResponse.data`。 ## 关联OIDC登录 `POST /api/v1/web/setup/auth-link` 调用身份:设置Cookie + CSRF + OIDC Bearer 正文:`{}`。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `BrowserResponse.data`。 ## 发送登录短信 `POST /api/v1/web/auth/sms/send` 调用身份:设置Cookie + 写请求CSRF | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | phone_e164 | string | 是 | 含国家区号的手机号,例如+8613800000000 | | purpose | string | 是 | 固定LOGIN | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `SMSResponse.data`。 ## 验证短信并登录 `POST /api/v1/web/auth/sms/verify` 调用身份:设置Cookie + 写请求CSRF | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | sms_challenge_id | string | 是 | 发送短信得到的挑战UUID | | code | string | 是 | 6位短信验证码;5分钟有效,最多验证5次 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `BrowserResponse.data`。 ## 查询可选择的家庭使用者 `POST /api/v1/web/profiles` 调用身份:设置Cookie + 写请求CSRF 正文:`{}`。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `ProfilesResponse.data`。 ## 创建家庭或使用者 `POST /api/v1/web/profiles/create` 调用身份:设置Cookie + 写请求CSRF | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | household_id | string | 条件或可选 | 家庭公开UUID;省略时须提供新家庭名称 | | household_name | string | 条件或可选 | 新建家庭的名称 | | preferred_name | string | 是 | 使用者称呼,用于设备人设和家庭展示 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `ProfileResponse.data`。 ## 提交绑定申请 `POST /api/v1/web/claims` 调用身份:设置Cookie + 写请求CSRF | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | elder_id | string | 是 | 使用者公开UUID,复用subject_profile | | expected_binding_generation | integer | 是 | 提交时预期绑定代数,防止跨解绑或重新绑定重放 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `ClaimResponse.data`。 ## 取消自己的绑定申请 `POST /api/v1/web/claims/cancel` 调用身份:设置Cookie + 写请求CSRF | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | claim_id | string | 是 | 待物理确认的绑定申请UUID | | expected_binding_generation | integer | 是 | 提交时预期绑定代数,防止跨解绑或重新绑定重放 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `StateOnlyResponse.data`。 ## 查询手机绑定进度 `POST /api/v1/web/setup/status` 调用身份:设置Cookie + 写请求CSRF 正文:`{}`。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `WebStatusResponse.data`。 ## 网页确认收到绑定结果 `POST /api/v1/web/setup/ack` 调用身份:设置Cookie + 写请求CSRF | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | binding_id | string | 是 | 当前已生效的绑定公开UUID | | binding_generation | integer | 是 | 绑定代数;解绑、重新绑定后旧代数无效 | | received_revision | integer | 是 | 网页已收到的设备状态版本 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `AckResponse.data`。 ## 设置结束后查询我的设备 `GET /api/v1/web/onboarding/devices` 调用身份:账号Cookie;设备列表也支持OIDC Bearer 无请求正文。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `DevicesResponse.data`。 ## 恢复账号会话及CSRF `GET /api/v1/web/account/session` 调用身份:账号Cookie;设备列表也支持OIDC Bearer 无请求正文。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `AccountResponse.data`。 ## 退出本浏览器登录 `POST /api/v1/web/auth/logout` 调用身份:账号Cookie;设备列表也支持OIDC Bearer 正文:`{}`。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `LogoutResponse.data`。 ## 查询生产设备和激活状态 `GET /api/v1/ops/device-inventory` 调用身份:运维OIDC Bearer + X-Tenant-ID 无请求正文。 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `DevicesResponse.data`。 ## 登记生产设备 `POST /api/v1/ops/device-inventory` 调用身份:运维OIDC Bearer + X-Tenant-ID | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | factory_mac | string | 是 | 12位大写十六进制MAC;相同MAC不能创建第二台物理设备 | | hardware_model | string | 是 | 生产登记型号,当前为KP01 | | hardware_revision | string | 是 | 硬件修订号,注册必须与库存一致 | | batch_no | string | 是 | 生产批次,方便追溯 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `InventoryResponse.data`。 ## 向工装交付加密密钥 `POST /api/v1/ops/device-inventory/{id}/credential-deliveries` 调用身份:运维OIDC Bearer + X-Tenant-ID | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | enrollment_job_id | string | 是 | 生产登记或密钥轮换任务UUID | | receiver_public_key_pem | string | 是 | 工装RSA公钥,PKIX PEM,2048至4096位,指数65537 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `DeliveryResponse.data`。 ## 确认烧录读回并放行 `POST /api/v1/ops/device-inventory/{id}/release` 调用身份:运维OIDC Bearer + X-Tenant-ID | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | enrollment_job_id | string | 是 | 生产登记或密钥轮换任务UUID | | evidence_ref | string | 是 | 烧录读回或人工对账的证据引用,不放密钥 | | expected_key_version | integer | 是 | 交付放行目标版本;轮换时为当前生效版本 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `ReleaseResponse.data`。 ## 准备轮换凭据 `POST /api/v1/ops/device-inventory/{id}/credential-rotations` 调用身份:运维OIDC Bearer + X-Tenant-ID | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | reason | string | 是 | 关闭、轮换或人工处理原因,见对应枚举 | | expected_key_version | integer | 是 | 交付放行目标版本;轮换时为当前生效版本 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `InventoryResponse.data`。 ## 人工记录激活对账结论 `POST /api/v1/ops/onboarding-activations/{id}/reconcile` 调用身份:运维OIDC Bearer + X-Tenant-ID | 字段 | 类型 | 必填 | 用途 | |---|---|---|---| | expected_version | integer | 是 | 运维列表中的激活任务版本,防止覆盖并发处理 | | conclusion | string | 是 | OBSERVED_REGISTERED、CONFIRMED_NOT_REGISTERED或DEVICE_ATTEMPT_STOPPED | | evidence_ref | string | 是 | 烧录读回或人工对账的证据引用,不放密钥 | | reason | string | 是 | 关闭、轮换或人工处理原因,见对应枚举 | | attempt_id | string | 条件或可选 | 设备生成的UUID v4,表示一次引擎初始化或首通执行 | | device_secret | string | 条件或可选 | 已核实的供应商单设备密钥,仅人工对账写入,加密保存 | | rtc_app_id | string | 条件或可选 | 供应商RTC应用ID;不填则使用已保存值 | 响应:成功外层 `{ok,code,request_id,server_time_ms,data}`;失败 `{ok,code,request_id,message}`。data结构为 `StateOnlyResponse.data`。