APIPace 文档 API 参考

限制与错误码

一页看完所有会挡住你的东西:约定、超时、限流、以及 14 个错误码分别该怎么处理。

约定

项 约定
幂等 带 Idempotency-Key 头的请求,7 天内同键重放返回首发结果、不重复扣费;同键仍在进行中返回 REQUEST_IN_PROGRESS(409,带 Retry-After)。图片任务和 Gemini 原生接口必须带这个头
关联编号 带 X-Request-ID 头(≤ 64 字符),响应回 X-Client-Request-Id,之后可用 GET /v1/requests/by-client/{id} 找回这一笔。它只是个标签,不产生幂等
超时 单次请求总预算 300 秒,首 token 60 秒;超过返回 UPSTREAM_TIMEOUT(504)
断开 客户端中途断开会取消模型服务方那一侧的调用,已产生的用量照常结算
白名单 key 可以限定可用别名和来源 IP,越界返回 PERMISSION_DENIED(403);不在白名单里的别名在 /v1/models 里也看不到
追踪 每个响应带 X-Request-Id(同响应体 request_id)和 X-Route-Id。出问题时把这两个值一起报过来
隐私 请求与响应正文默认不留存

频率限制

每把 key 有自己的每秒请求数上限(一秒固定窗口)。平台默认每 key 30 次/秒;在控制台的 API Key 页可以给某把 key 设更严的 rps_limit(1 到平台默认之间),留空就用默认。

每一个被限流管着的响应都带用量头,不只是被拒的那个——好让你在被拒之前就慢下来:

HTTP/1.1 200 OK
X-RateLimit-Limit: 1
X-RateLimit-Remaining: 0

超了返回 429,多一个 Retry-After:

HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit: 1
X-RateLimit-Remaining: 0
{"error":{"code":"RATE_LIMITED","message":"rate limit exceeded, retry shortly","request_id":"req_01M2M96HPG0DWFMKZQ5HN9JT9P"}}

窗口就是一秒宽,所以 Retry-After 永远是 1——等一秒再发,别退避成指数,也别立刻重试。

头 含义
X-RateLimit-Limit 这把 key 当前生效的每秒上限
X-RateLimit-Remaining 这一秒还剩多少次
Retry-After 等几秒再试,恒为 1

被限流的请求根本没发出去,不扣钱。

另外两种 429 不是频率问题,重试策略不同:

服务状态

怀疑是平台的问题而不是你的代码时,先看 GET /status。免鉴权、故障时也能读:

curl https://api.apipace.com/status
{
  "window_minutes": 15,
  "updated_at": "2026-09-16T04:55:06.073713Z",
  "models": [
    {"id":"claude-sonnet-4.6","requests":128,"upstream_error_rate_bp":0,"p50_latency_ms":1840},
    {"id":"kimi-k3","requests":12,"upstream_error_rate_bp":833,"p50_latency_ms":940}
  ],
  "overall": {"requests":140,"upstream_error_rate_bp":71}
}

最近 15 分钟的对话别名健康度,30 秒更新一次(Cache-Control: public, max-age=30)。

upstream_error_rate_bp 是基点:833 = 8.33%。它只统计平台该负责的失败——模型服务方报错、超时、限流,以及平台内部错误;参数写错、鉴权失败、余额不足这类由你造成的 4xx 计进 requests 但不计进错误率,所以这个数字不会因为你自己调错而变难看。p50_latency_ms 是端到端总耗时的中位数。

错误信封

所有错误一个形状,四百到五百全都一样:

{"error":{"code":"AUTH_FAILED","message":"missing credentials: send Authorization: Bearer ak-...","request_id":"req_01M2M6Q5AE31PQTE9AJHGRJPVD"}}

message 是给人看的说明,不含服务方原文、凭据或任何供应商身份。程序请判 code,不要判 message。

14 个错误码

这 14 个码是冻结的,不会悄悄增删。

code HTTP 什么情况 怎么办
INVALID_REQUEST 400 参数或请求体不合法 改请求,重试无用
AUTH_FAILED 401 key 缺失、无效、已禁用或过期 检查 Authorization / x-api-key 是否带上、是否被截断
INSUFFICIENT_BALANCE 402 可用余额不够预占 充值,或把 max_tokens 调小
PERMISSION_DENIED 403 别名或来源 IP 不在这把 key 的白名单里 去控制台改白名单
MODEL_NOT_FOUND 404 别名不存在,或对这把 key 不可见 用 GET /v1/models 核对拼写
NOT_FOUND 404 资源不存在,包括查别人的 request_id 核对编号和账户
REQUEST_IN_PROGRESS 409 同一个 Idempotency-Key 还在进行中 按 Retry-After 等一会儿再查
CONTENT_BLOCKED 422 安全拦截 改内容,重试无用
BUDGET_EXCEEDED 429 账户日 / 月预算用完 去控制台调预算
RATE_LIMITED 429 这把 key 的每秒请求数超限 按 Retry-After 退避
MODEL_RATE_LIMITED 429 这个别名当前拿不到配额 按 Retry-After 退避,或换个别名
UPSTREAM_ERROR 502 模型服务方返回失败(已脱敏) 可重试;反复出现请带 X-Request-Id 和 X-Route-Id 找我们
UPSTREAM_TIMEOUT 504 超过 300 秒总预算或 60 秒首 token 缩短输入、或改用流式
INTERNAL_ERROR 500 平台内部错误 带上两个追踪号找我们

哪些会扣钱:402 / 403 / 404 / 429 一律不扣(请求根本没发出去);502 / 504 不扣;200 按实际用量扣。

几个容易踩的点

响应里没有钱。 对话接口的响应体只有 token,sales_amount 在 GET /v1/requests/{id} 里。这是有意的:扣费以账本为准,不以响应体为准。

model 填的是别名。 填厂商原始模型名(gpt-4o、claude-3-5-sonnet-20241022 这种)会直接 404:

{"error":{"code":"MODEL_NOT_FOUND","message":"unknown model \"gpt-4o\"","request_id":"req_01M2M6Q6N5W1R2J26QB7RGVKX3"}}

Gemini 系列别名只认原生协议。 拿 gemini-* 去打 /v1/chat/completions 会被拒。见Gemini 原生接口。

图片不是对话接口。 gpt-image-2-official 走 POST /v1/image-tasks 的异步任务,不能填进 messages 请求里。见图片生成。