JuCode 文档

认证

两种认证头、API Key 格式,以及 401 的排查路径。

所有端点都需要认证,包括 /v1/models

两种写法

网关同时接受下面两种头,在所有端点上都有效——包括 OpenAI 端点也接受 x-api-key,Anthropic 端点也接受 Authorization。这正是同一个 Key 能同时喂给两家 SDK 的原因。

# 写法一:OpenAI 惯例
curl https://api.jucode.cn/v1/models \
  -H "Authorization: Bearer sk-juc-..."

# 写法二:Anthropic 惯例
curl https://api.jucode.cn/v1/models \
  -H "x-api-key: sk-juc-..."

只有当 Authorization 头缺失或格式无效时,网关才会去读 x-api-key。两个都传时, Authorization 优先。

Bearer 前缀大小写敏感

必须是恰好 Bearer ——首字母大写,后跟一个空格

bearer sk-juc-...BEARER sk-juc-...、或用制表符分隔,都会被判定为空凭证, 返回 401 invalid_api_key 且提示 missing credentials。这个报错看起来像"没传 Key",实际是"Key 传了但前缀写错了",容易误导排查方向。

浏览器端的限制

如果你从浏览器直接调用网关,有两条限制:

必须用 Authorization,不能用 x-api-key 网关的 CORS 允许头列表里没有 x-api-key,跨域预检会失败。

读不到响应头。 网关没有设置 Access-Control-Expose-Headers,所以浏览器 JS 拿不到 X-Request-IdRetry-AfterX-RateLimit-*。排查问题时如果需要 request_id,只能从响应体的 JSON 里取——错误响应体里有这个字段。

更根本的问题:在浏览器里直接调用意味着 API Key 会暴露给终端用户。生产环境请在你 自己的后端中转,不要把 Key 下发到前端。

API Key 格式

sk-juc-<43 位 base64url 字符>

总长 50 位,正则是 ^sk-juc-[A-Za-z0-9_-]{43}$。控制台列表里显示的"前缀"是 sk-juc- 加前 8 位,用来辨认是哪一把 Key,不是完整凭证。

完整明文只在创建那一刻返回一次。丢了就只能重新创建。

OAuth 设备令牌

除 API Key 外,网关也接受 OAuth 设备访问令牌(CLI、桌面端登录后拿到的那种)。 把它当作 Bearer 凭证传即可,网关按前缀区分:sk-juc- 开头走 API Key 路径, 其余一律当 JWT 解析。

用 OAuth 令牌调用时有两点固定行为,不受控制台配置影响:

  • 总是自动路由,不受 API Key 的模型组白名单限制
  • 总是按个人额度计费,不走组织账单

另外,普通网页会话令牌不能用于调用 API——只有 oauth_access 类型的令牌有效。

401 排查

403 而非 401

下面两种情况凭证本身有效,但账号状态不允许调用,返回 403:

code含义
account_disabled账号非活跃状态
account_frozen因违规被临时冻结,过期后自动恢复

注意这两个的 error.type 仍然是 authentication_error,不是 permission_error ——所以别用 type 字段来区分该不该重试,要看 code

Anthropic 端点的 401 格式不同

/anthropic/v1/* 的认证失败返回的是 OpenAI 格式的错误体,不是 Anthropic 格式:

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "missing credentials",
    "request_id": "..."
  },
  "request_id": "..."
}

原因是认证在进入 Anthropic 处理器之前就完成了,走的是共用的中间件。

实际影响:Anthropic 官方 SDK 的错误解析可能无法识别这个响应体,你看到的可能是一个 泛化的异常而非 AuthenticationError认证配好之后就不会再遇到,但首次接入调试时 值得知道。

On this page