API 与错误码
Anthropic 原生端点
给 Anthropic SDK 与 Claude Code 用的那套:零翻译、同一把密钥,以及三处与官方不同的行为。
除了 OpenAI 兼容那套,网关还直接提供 Anthropic 原生协议:
| 端点 | 用途 |
|---|---|
POST /v1/messages |
对话补全,请求与响应都不翻译 |
POST /v1/messages/count_tokens |
数 token,不计费 |
Anthropic 官方 SDK、Claude Code 这类工具把地址指过来就能直接用。
接入地址
这里的地址不带 /v1 —— 这两个工具自己往后拼 /v1/messages。
带上的话请求会打到 …/v1/v1/messages,返回 404。
https://router.xisu.ai
Claude Code:
export ANTHROPIC_BASE_URL="上面这个地址"
export ANTHROPIC_AUTH_TOKEN="你的密钥"
export ANTHROPIC_MODEL="你要用的模型名"
Anthropic SDK:把 base_url 设成上面这个地址,api_key 设成你的密钥。
OpenAI 兼容那套的
base_url是带/v1的另一串(见「端点与鉴权」)。 两套协议共用同一把密钥和同一个余额,只有地址形状不同。
什么时候该用它
用它,如果你要的是这些:cache_control(提示缓存)、thinking、
多模态与 document 块、tool_result —— 这些字段原样到达上游。
走 /v1/chat/completions 时它们分两种下场,而这两种差一个数量级:
- 顶层的专有参数(
thinking一类)会被当场 400 拒掉 —— 你看得见, 报错里也写了原因; - 嵌在 content / system 里的
cache_control是静默丢掉的 —— 请求照常成功、响应看起来完全正常,只是提示缓存从来没有命中过。 账单可能因此翻几倍,而不会有任何报错告诉你。
后一种正是这个端点存在的全部理由。其余场景两套没有区别,继续用你现在那套即可。
鉴权:同一把密钥
x-api-key: 你的密钥
Anthropic SDK 与 Claude Code 发的就是这个头。Authorization: Bearer 也接受;
两个都给时以 x-api-key 为准。
密钥、租户、余额、套餐、预算与 OpenAI 那套完全共用 —— 不需要另外申请, 用量也记在同一个账上。
请求与响应
标准 Anthropic Messages 形状,model / messages / max_tokens 必填
(max_tokens 在这个协议里本来就是必填的)。
响应原样返回,不会被翻译成 chat.completion。流式是原生 Anthropic 事件流
(message_start / content_block_delta / message_delta / message_stop),
没有 data: [DONE] —— 那是 OpenAI 方言,别按它写收尾判断。
⚠️ 三处与官方不同的行为
1. 余额不足报的是 429
Anthropic 协议里没有"余额不足"这个错误类型,所以余额不足、配额用尽、 密钥预算到顶,在这个端点上一律是:
{"type":"error","error":{"type":"rate_limit_error","message":"…"}}
收到 429 时先看余额,不要照着限流去重试。 message 里会写明这是账务限制、 重试没用。(SDK 通常只重试两次就把 message 抛给你,所以那句话是给你看的。)
2. 这个端点上的模型是子集
只有配了 anthropic 上游的模型能在这里调。模型名对、但这个端点没有它时,
返回 404 not_found_error,message 里会指向 /v1/chat/completions。
404 和 503 是两回事,下一步正好相反:
- 404
not_found_error—— 这个模型有上游在服务,但那些上游服务不了这个端点 (它没有配 anthropic 类上游)。这是永久的,重试没有意义:换一个模型, 或者改走/v1/chat/completions(message 里会指路)。不是你模型名写错了。 - 503
overloaded_error—— 模型是这个端点的,只是此刻一个可用上游都没有 (冷却中,或者被限流挡住)。这是暂时的,应当重试 —— 响应里带Retry-After, 按它退避即可,通常分钟级自愈。
3. 两类字段会被 400 拒掉
| 被拒的 | 为什么 |
|---|---|
server tools(web_search、code_execution 等,即 tools 里不带 input_schema 的条目) |
上游按次另外收费,不在 token 用量里,而我们的价目表只按 token 计 |
cache_control.ttl 不是 5m |
1 小时档的写入价约为 5 分钟档的两倍,而价目表只有一档 |
自定义工具(带 input_schema 的)照常放行 —— function calling 不受影响。
被拒时 message 会说明原因。
列模型
GET /v1/models 带上 anthropic-version 头时,返回 Anthropic 形状,
而且只列这个端点真能服务的那些:
{"data":[{"type":"model","id":"…"}],"has_more":false}
不带这个头时,返回原来的 OpenAI 形状与全集,一个字节都没变。
数 token
POST /v1/messages/count_tokens 返回 {"input_tokens": N}。
不计费,也不写进用量明细;但它会打到上游,所以计入你的请求频率。 拿它在循环里探测长度是可以的,别把它当成免费的无限调用。