twp/1 认证探活 + 协议协商(CLI 登录验证即此):回 protocol/app{id,name,ownerType}/configEtag/serverTime/features;协议版本不符 400 protocol_unsupported;认证失败 401 app_key_invalid / 403 app_disabled / 403 app_ip_denied(CIDR fail-closed);请求签名三头可选(在场恒校验);configEtag 与 /t1/config 按同一 x-tansr-client-features 声明生成;owner 仅保留原音频可见性,其余扩展仍按声明投影
const url = 'https://api.tansr.com/t1/handshake';const options = { method: 'POST', headers: { 'x-tansr-key-id': '<x-tansr-key-id>', 'x-tansr-key': '<x-tansr-key>', 'Content-Type': 'application/json' }, body: '{"protocol":"example","client":{"name":"example","version":"example"}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.tansr.com/t1/handshake \ --header 'Content-Type: application/json' \ --header 'x-tansr-key: <x-tansr-key>' \ --header 'x-tansr-key-id: <x-tansr-key-id>' \ --data '{ "protocol": "example", "client": { "name": "example", "version": "example" } }'Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”客户端可理解的可选扩展词表,逗号分隔,未知词忽略。platform-audio 控制旧令牌端音频可见性;tts-input-limit-v1 声明原子输入上限;bound-device-v1 声明绑定终端段;nonchat-operations-v1 声明六个非聊天能力;adjudicator-policy-slots-v1 声明裁决主备独立策略及预算模式,未声明时 independent 配置只发有效主选并禁用备用,旧 shared 策略保持原备用。新能力对所有未声明客户端剥除,owner 仅保留原音频可见性。响应 Vary 本头,正文和规范化特性集合共同生成 ETag;config、handshake、heartbeat 必须携相同特性。
签名时间戳(unix 秒,十进制串;T-A34):与服务器时钟偏差 >300s → 401 signature_invalid
签名随机数(≥16 字符;T-A34):同 keyId 600s 窗内重现 → 401 nonce_replayed
请求签名(hex 小写;T-A34):HMAC-SHA256(K=sha256(SK 明文) 原始摘要, TWP1-HMAC-SHA256\n{METHOD}\n{path+query}\n{ts}\n{nonce}\n{sha256hex(rawBody)});三头须同现,在场恒校验;app signRequired 或 TANSR_API_TWP_REQUIRE_SIGNATURE=1 时未签名恒 401 signature_invalid
Request Bodyrequired
Section titled “Request Bodyrequired”object
期望协议;非 twp/1 → 400 protocol_unsupported
object
Examplegenerated
{ "protocol": "example", "client": { "name": "example", "version": "example" }}Responses
Section titled “Responses”握手成功
object
账套配置包当前 ETag(/t1/config 一致性事实源)
能力协商位(恒加法演进);当前词表 = TWP_FEATURES:org-governance(账套治理段下发)、usage-purpose(twp meta.purpose 计费归属可发)、usage-purpose-2(purpose 词表 v2 增量可发,TM-9:memory)、usage-purpose-3(v3 增量可发,K2:adjudication)、image-input(exchange user 消息可携 image 块,M3)、prompt-cache(exchange 可携缓存语义:system 块 cacheable 位 + cache.skipWrite/key,CW11-W1)、reasoning-off(params.reasoning 词表含 off 显式思考关断,RFC-M3 B2)、session-register(批ι 地板 wire 标记 floor-1:meta 未知键忽略 + purpose 词形受理 + 会话首见幂等登记;部署核验/诊断用,非发送门,RFC-R79-ι)。消费方按串精确匹配,未知串恒忽略
Example
{ "protocol": "twp/1", "app": { "ownerType": "user" }}Protocol_unsupported
object
object
错误码注册表单源派生(src/http/errors.ts ERROR_CODES;码稳定,消费方按码翻译)
object
Example
{ "error": { "code": "adjudicator_not_authorized" }}App_key_invalid(查无/密文不符/缺头)/ signature_invalid(T-A34:签名头不全/ts 偏差>300s/签名不匹配/强制档未签名,detail.reason)/ nonce_replayed(600s 窗内重放)
object
object
错误码注册表单源派生(src/http/errors.ts ERROR_CODES;码稳定,消费方按码翻译)
object
Example
{ "error": { "code": "adjudicator_not_authorized" }}App_disabled / app_ip_denied / forbidden(scope 不符)
object
object
错误码注册表单源派生(src/http/errors.ts ERROR_CODES;码稳定,消费方按码翻译)
object
Example
{ "error": { "code": "adjudicator_not_authorized" }}本文是否有帮助?
感谢反馈,我们会持续改进这篇文章。