状态码指不到真实原因
看 error.code,不要看状态码
模型名写错返回 503,缺 messages 字段返回 500。这两种都是请求本身的错,重试多少次都不会变——但 openai-python、openai-node 和 Anthropic 各家 SDK 默认都会对 408、409、429 与全部 5xx 重试两次,还带指数退避。于是一个拼写错误变成三次往返、几十秒的等待,最后才报出那个第一次就已经确定的原因。真实原因一直在响应体的 error.code 里,说谎的是状态码。
本站会返回的每一种失败,2026-09-01 打真实端点逐条测过。8 条里有 5 条的状态码指不到真实原因,其中 2 条还会被官方 SDK 默默重试,然后才轮到你的程序看见。
核实于 2026-09-01
状态码指不到真实原因
模型名写错返回 503,缺 messages 字段返回 500。这两种都是请求本身的错,重试多少次都不会变——但 openai-python、openai-node 和 Anthropic 各家 SDK 默认都会对 408、409、429 与全部 5xx 重试两次,还带指数退避。于是一个拼写错误变成三次往返、几十秒的等待,最后才报出那个第一次就已经确定的原因。真实原因一直在响应体的 error.code 里,说谎的是状态码。
对照表
按实际遇到的频率排,不按数值排。
空字符串Invalid tokenmodel_not_found状态码指不到真实原因No available channel for model gpt-4o under group y-api (distributor)insufficient_user_quota状态码指不到真实原因用户额度不足, 剩余额度: $0.00pre_consume_token_quota_failed状态码指不到真实原因token quota is not enough, token remain quota: $0.000002, need quota: $0.000074invalid_request状态码指不到真实原因field messages is requiredinvalid_request_error状态码指不到真实原因`messages` is required and must be a non-empty array.空字符串Invalid request: Invalid request: invalid JSON request body空字符串Invalid URL (POST /v1/messages/count_tokens)静默失败
有三种失败会返回 200、不抛异常、让你的程序照常往下跑。错的是内容或者账单——这也正是它们很难自己发现的原因。
上游给 5 个模型标了 image_ratio。那个标记是计价系数,不是视觉能力。5 个模型全都接受 data URL 图片、返回 200,然后一本正经地回答一张它们没看见的图——探针发的是纯绿色 PNG,没有一个说对颜色。推荐模型反而是直接返回 400 拒收,两种失败里这种更安全。
来自客户端兼容性矩阵
上限传 12,moonshotai/kimi-k2.5 实际计费 261,21.8 倍。截断本身是生效的(finish_reason=length);超出的部分是推理 token,它们计费但不进 content。任何按这个上限估算的成本都会低估同样的倍数。
来自客户端兼容性矩阵
POST /v1/messages 返回的是一串裸十六进制 id。凡是断言 msg_ 前缀、或者靠解析 id 来路由响应的代码都会对不上——尽管响应体其余部分是合规的。
来自客户端兼容性矩阵
解析
外层永远是 {"error": {...}},但字段集合并不固定:有的错误带 param,有的没有,code 经常是空字符串。解析时把每个字段都当可选的。
{"error":{"code":"","message":"Invalid token (request id: 2026090114474514374…)","type":"new_api_error"}}{"error":{"message":"Invalid URL (POST /v1/messages/count_tokens)","type":"invalid_request_error","param":"","code":""}}每条消息尾部都有一个 request id,每次请求都不一样。拿消息和本页对照之前先把它剥掉;反过来,报告问题时请带上它——它是日志里定位你那一次请求的唯一依据。
排查
按顺序来。每一步排掉一层,答案就在这个序列停下来的地方。
GET /v1/models 不花额度,用的是同一把密钥。返回 200 和一份模型清单,就证明密钥、网络、CDN 边缘三者都没问题——那么问题在请求体里,不在凭证上。
curl -s https://api.y-api.bestvirtualgoods.com/v1/models -H "Authorization: Bearer $YAPI_KEY" | head -c 200这一步把 SDK 排除掉。如果 curl 成功而你的代码失败,差别在这个库怎么拼请求,不在本站。
curl -i https://api.y-api.bestvirtualgoods.com/v1/chat/completions \
-H "Authorization: Bearer $YAPI_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek/deepseek-v4-flash","messages":[{"role":"user","content":"hi"}]}'关掉重试之后,由你自己请求引起的 500 或 503 会在第一次尝试就露出来,而不是白等两次。查完记得加回去——面对真正的临时故障,重试是有价值的。
client = OpenAI(
base_url="https://api.y-api.bestvirtualgoods.com/v1",
api_key=os.environ["YAPI_KEY"],
max_retries=0, # 仅排查时使用
)