401 Unauthorized,几乎总是下面几种原因之一。请按顺序逐一排查。
1. apex → www 重定向(最常见)
https://hitheo.ai 会以 307 重定向到 https://www.hitheo.ai。大多数 HTTP 客户端——包括 Node 18 内置的 fetch、未加 --location-trusted 的 curl,以及若干语言运行时——出于安全考虑会在 3xx 响应上剥离 Authorization 头。这会导致重定向后的请求变成未认证请求,服务器因此正确地返回 401 invalid_api_key。
修复方法: 直接使用规范的 www 主机。自 @hitheo/sdk@0.2.0 起,SDK 默认使用 https://www.hitheo.ai;如果你手动固定了 baseUrl,请更新它:
2. 缺失或格式错误的 API 密钥
除GET /api/v1/health 之外,每个请求都需要一个 Authorization: Bearer theo_sk_... 头。请检查:
- 头名称必须恰好是
Authorization,而不是多了一个冒号的authorization:,也不是X-API-Key。 - 令牌前缀必须是
theo_sk_(不存在theo_sk_test_这种变体——所有密钥都是生产密钥)。 - 令牌前后不能有空白字符——
.env文件末尾遗留的换行符是常见原因。 - 密钥没有被撤销。请检查 API Keys 控制台。
3. 密钥的作用域不正确
API 密钥携带作用域(completions、skills、tools、connectors、billing)。缺少 completions 作用域的密钥会返回 403 missing_scope,而不是 401。如果你看到的确实是 403:请重新签发一个具备所需作用域的密钥,或联系密钥创建者对其进行更新。
4. 密钥已过期(宽限期已结束)
当你轮换密钥时,旧密钥会进入一个宽限窗口(可配置,默认 60 分钟),随后被撤销。使用已过期密钥发出的请求会返回401 key_expired。请在控制台或通过 POST /api/v1/keys/rotate 完成轮换,并将新令牌替换到你的密钥存储中。
5. 时钟偏差导致 webhook 的 HMAC 校验失败
这与 API 密钥认证无关,但有时会被误报为「webhook 上的 401」:webhook 签名校验使用的是Theo-Signature 头,它是对请求体做 HMAC-SHA256 计算得到的。如果你的服务器时钟偏差超过 5 分钟,签名就会校验不通过。可运行 ntpdate -q pool.ntp.org 进行检查。
仍未解决?
- 运行
theo verify(或在 SDK 中调用await theo.verify()),并将输出提供给支持团队。 - 在工单中附上响应头
X-Request-Id——每个 v1 响应都会携带该头,成功响应还会在 JSON 响应体中以request_id字段暴露它。支持团队可据此在日志中查找该请求。 - 查看 status.hitheo.ai 是否有正在发生的事件。
