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 双头径恒全量单一 etag;features 含 platform-audio 即服务端具备音频两面并受理该头
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”客户端可理解的可选扩展词表(逗号分隔,大小写不敏感,未知词忽略;与服务端 features 反向同形)。词表:platform-audio = 可理解 bundle 音频两面加法键(capabilities.platform.speechToText/textToSpeech、platformModels.speechToText/textToSpeech 与 media.asr/tts)。分档只施于 app_user 令牌径(十王修案 FX-A-05,分册 A S3:分档只保护已发布 .strict() 的旧 SDK,而 SDK 恒走令牌径):令牌径仅对声明者下发五键 / 四键 / 音频两面,缺头恒三键 / 两键,正文与 ETag 按档重算(响应 Vary 本头),同一客户端须在 /t1/config、/t1/handshake、/t1/heartbeat 同携同值,否则 configEtag/bundleEtag 与 bundle 异档、configStale 恒真;owner 径(AK/SK 双头 / 装置键 / PAT)恒全量、单一 ETag,本头为 no-op
签名时间戳(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" }}本文是否有帮助?
感谢反馈,我们会持续改进这篇文章。