Appearance
认证与签名
所有接口均需通过 API Key + 请求签名 进行认证。
请求头说明
| 请求头 | 必填 | 说明 |
|---|---|---|
Authorization | ✅ | 格式:Bearer <apiKey> |
X-Timestamp | ✅ | Unix 时间戳(秒),与服务器时差不超过 5 分钟 |
X-Signature | ✅ | 请求签名,见下方签名算法 |
X-Request-ID | ✅ | 请求唯一标识,建议使用 32 位随机字符串 |
X-User-ID | ✅ | 当前用户标识 |
Content-Type | ✅ | application/json |
签名算法
签名用于防止请求篡改和重放攻击,算法为 SHA-256。
步骤:
- 取请求体中所有字段(排除
null、空字符串、纯空白值) - 对字段名按**字典序(ASCII 升序)**排序
- 拼接为
key1=value1&key2=value2&...格式 - 末尾拼接
apiSecret - 对整体字符串做 SHA-256 哈希,取小写十六进制结果
示例:
待签名字符串 = "agentId=agent-uuid&conversationId=conv-uuid&language=zh&text=你好" + apiSecret
X-Signature = sha256(待签名字符串)注意事项
- 字符串值去掉首尾空白后再参与签名
metadata若为非空对象,取 JSON 字符串参与签名multipart/form-data上传接口无 JSON body,签名为sha256("" + apiSecret)
JavaScript 签名工具函数
javascript
async function buildAuthHeaders(apiKey, apiSecret, userId, body = {}) {
const timestamp = Math.floor(Date.now() / 1000).toString()
const requestId = crypto.randomUUID().replace(/-/g, '')
const sortedParams = Object.keys(body)
.filter(k => body[k] != null && String(body[k]).trim() !== '')
.sort()
.map(k => `${k}=${String(body[k]).trim()}`)
.join('&')
const signStr = sortedParams + apiSecret
const hashBuffer = await crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode(signStr)
)
const signature = Array.from(new Uint8Array(hashBuffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('')
return {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
'X-Timestamp': timestamp,
'X-Signature': signature,
'X-Request-ID': requestId,
'X-User-ID': userId,
}
}限流规则
每个 API Key 独立计算:
- 频率限制(Rate Limit):单位时间内最大请求次数,超出返回
Too many requests错误 - 总量限制(Max Usage):累计调用总次数上限,超出返回
API key usage limit reached错误
具体限制值由平台管理员在创建 API Key 时配置。
常见认证错误
| HTTP 状态码 | 原因 |
|---|---|
401 | 缺少 Authorization / X-Timestamp / X-Signature 等必要请求头 |
401 | 时间戳与服务器时差超过 5 分钟(防重放) |
401 | API Key 无效或已禁用 |
401 | 签名验证失败(参数顺序或 secret 错误) |
