错误和限制
GetVibe API 错误代码:401(密钥)、402(余额)、403(IP)、429(速率限制)。了解如何处理错误,以及如何使用指数退避重试。
GetVibe 在/v1/*上产生的错误包含一个 JSON 信封,其中有error.message、error.type和error.code。不要依赖消息文本或第三方服务标头作为契约。
错误格式
{
"error": {
"message": "insufficient balance",
"type": "insufficient_quota",
"code": 402,
"request_id": "8d4b6b3a-..."
}
}响应代码
| 参数 | 类型 | 描述 |
|---|---|---|
401 | authentication_error / 401 | 缺少密钥、密钥格式错误或密钥已被禁用。在修复凭据之前不要重试。 |
402 | insufficient_quota / 402 | 没有可用余额或额度,等待不会解决问题。402 响应绝不会携带 Retry-After,也不应重试:请充值,或等待订阅窗口重置。 |
403 | permission_error or policy type / 403 | IP、模型或策略不允许该请求。请勿在不更改请求或设置的情况下重试。 |
429 | rate_limit_exceeded, inflight_client_cap or rate_limit_error / 429 | 可能是您的速率限制、并发限制、由您自己的并发请求短暂持有的余额预留(原因是 reserved_in_flight),或供应商限制。仅在 Retry-After 之后重试;429 从不表示您的余额已耗尽。 |
410 | media_endpoint_retired / media_endpoint_retired | 仅适用于 /v1/images/edits、/v1/video/generations 和 /v1/videos(已停用)。请勿重试;改用 /api/media/generate。/v1/images/generations 可正常使用。 |
413 | invalid_request_error / 413 | 仅限 Files API:文件超过 50 MiB。请压缩文件,然后创建新请求。 |
503 | overloaded / 503 | 全局边缘节点过载。请在 Retry-After: 2 后重试。其他 503 错误在不更改模型或请求的情况下可能无法重试。 |
请求错误(400、413、422):错误码与修复方法
每个请求错误都包含下表中一个固定的 error.code、指明相关字段的 error.param(模型未指明字段时为 null),以及位于 error.message 末尾、指向对应表格行的链接——Codex 和其他 CLI 只显示消息,因此链接放在消息中。
| error.code | error.param | 处理方法 |
|---|---|---|
unsupported_parameter | 字段名称 | 所选模型或通道不接受此参数。请从请求中移除该参数(在 Codex/IDE 中,从配置中移除),然后重试。 |
invalid_parameter_value | 字段名称 | 参数已提供,但该模型不允许使用此值:例如,启用推理时 temperature 不为 1、max_tokens 超过上限,或在无法关闭推理时将 effort 设为 "none"。请按照消息提示修正参数值。 |
missing_parameter | 字段名称 | 缺少必填字段或该字段为空。请补充该字段。 |
invalid_tool_schema | tools[].function.* | 工具定义被拒绝:名称只能包含拉丁字母、数字、"_" 和 "-";parameters 必须是根类型为 type: "object" 的 JSON Schema。或者选择该模型的其他变体。 |
tool_choice_unsupported | tool_choice | 该模型不支持强制选择工具。请将 tool_choice 设为 "auto" 或 "none"。 |
invalid_tool_history | messages / input | 历史记录中包含没有结果的工具调用。请添加具有相同 id 的结果,或在裁剪历史记录时将调用及其结果一起删除。 |
invalid_image | — | 无法读取图片。请发送完整的 PNG、JPEG、WebP 或 GIF 文件(不接受 BMP、TIFF、AVIF 和 SVG)。 |
unsupported_input_modality | — | 该模型不接受此类附件(PDF、音频、视频、图片)。请移除附件,或选择模型目录条目中列明支持此类输入的模型。 |
conversation_state_unreadable | — | 历史记录中的推理内容由另一个通道生成。请求有效;请重试,如果错误再次出现,请开始新对话。 |
invalid_json | — | 请求体不是 JSON,或在传输过程中被截断。对于包含图片的超长对话,请开始新对话或压缩历史记录。 |
request_too_large | — | 请求过大。请减少附件或历史记录。 |
request_rejected_by_channel | — | 模型通道拒绝了请求,但未说明原因;请求本身很可能有效。请重试;如果仍被拒绝,请选择该模型的其他变体(冒号后的后缀)或不带后缀的模型。如果仍无效,请联系支持团队并提供 request_id。 |
model_not_available_on_route | — | 尚未为该模型配置路由。请选择其他模型或变体。 |
context_length_exceeded | messages / input / prompt | 请求超出上下文窗口。请压缩历史记录(在 Codex 中使用 /compact),或选择上下文窗口更大的模型。 |
content_moderation | — | 请求或回答被提供商的内容过滤器拦截。请换一种表述或选择其他模型。 |
invalid_request | — | 未能识别原因。请对照 API 参考文档检查请求;如果请求正确,请联系支持团队并提供响应中的 request_id。 |
响应标头
| 参数 | 类型 | 描述 |
|---|---|---|
x-pv-cost-rub | string | 尽力而为的卢布成本估算。在流式响应中,当输入估算可用时会提供 x-pv-cost-rub;最终 usage 事件中的 pv_cost_rub 需要设置 x-pv-cost: 1。使用记录中包含实际扣款金额。 |
x-pv-generation-id | string | 使用情况历史记录的记录 id(GET /v1/generations/{id})。仅对非流式 chat/completions 请求返回。 |
x-pv-dropped-params | string | 所选路由不接受、因此未发送给模型的请求参数,以逗号分隔(例如 temperature,top_p)。仅当确实有参数被保留时才会出现,在回答和错误中均如此。我们绝不会静默丢弃参数:如果没有该请求头,则你发送的所有内容都会原样到达模型。 |
Retry-After | integer | 等待的秒数。边缘服务会在 429 速率限制、429 并发(5)、503 全局过载(2)以及某些临时 402 情况下设置该值。并非每个 429/503 都假定有此值。 |
响应开始前后发生的错误
慢速流(stream: true)在静默 5 秒后会获得 200 和 : pv-keepalive 注释,以免连接看起来已经失效;长时间运行的非流式请求会在收到首个令牌后获得 200 和空白字符。此后状态无法更改,错误会出现在响应正文中。如果你的客户端在 HTTP 错误时回退到另一个供应商,请发送 x-pv-honest-errors: 1(或联系支持团队为账户启用该选项):这样便不会有 keepalive,也不会在收到首个响应字节之前提前返回 200;每次失败都会是带有 JSON 正文的普通 HTTP 状态。代价是,在收到首个令牌之前 socket 会保持静默;你的 header 超时设置必须覆盖这段时间。
响应开始后发生的错误是一个终止事件:对于聊天请求,使用 event: error,随后为 {"error":{message,type,code,status},"choices":[{"finish_reason":"error"}]} 和 data: [DONE];对于 /v1/responses,使用携带相同 error 的 event: response.failed;对于 /v1/messages,使用 Anthropic 的 event: error。code 是机器可读的原因,status 是响应开始前该错误本应具有的 HTTP 状态。
速率和并发限制
这两项限制均取决于账户的当前余额,并由该账户的所有 API 密钥共同使用。等级会自动重新计算:充值后限额提高;余额低于某个阈值时等级降低。不设每分钟 token 数(TPM)限制。
| 余额起点 | 每分钟请求数(RPM) | 并发请求数 |
|---|---|---|
| 0 $ | 300 | 10 |
| 1 $ | 1 100 | 50 |
| 2 $ | 6 600 | 300 |
| 4 $ | 19 800 | 900 |
| 12 $ | 44 000 | 2 000 |
| 参数 | 类型 | 描述 |
|---|---|---|
429 rate_limit_exceeded | RPM | 该账户在过去 60 秒(滑动窗口)内发送的请求数已达到其等级允许的上限。Retry-After 表示距离窗口内有名额释放还需等待的秒数(至少为 1);x-ratelimit-limit-requests 表示您当前的 RPM。响应体:error.cause = key_rate_limited, error.details = { enforced_by: "getvibe", limit, unit: "requests_per_minute", retry_after_seconds }。 |
429 inflight_client_cap | concurrency | 当前正在运行的请求数已达到该等级允许的上限。请求在完成前会一直占用名额;流式请求则会一直占用到最后一个事件。Retry-After: 5。响应体:error.cause = account_concurrency_limited, error.details = { enforced_by: "getvibe", limit, unit: "parallel_requests", retry_after_seconds: 5 }。 |
Personal limit | RPM | 如果账户设置了自定义请求限制,该限制只能降低所属等级的 RPM,不能提高。 |
503 overloaded | service | 这不是您的限额,而是服务保护机制:Retry-After: 2 表示触及所有账户共享的全局上限,Retry-After: 1 表示某台服务器繁忙。请等待相应时间后重试。 |
429 from a provider | upstream | error.cause = supplier_rate_limited 表示模型提供商对请求进行了限流,而您自身的限额尚未用尽;channel_rate_limited 表示触及提供商通道的共享上限(Retry-After: 10,未发送任何请求)。 |
重试请求
对于可重试的响应,首先使用 Retry-After(如果存在)。如果没有该标头,不要将任何 429 或 503 自动视为可重试:请检查 HTTP 状态和公开的 error.type,修复不可重试的原因,并且仅对瞬时错误使用有界退避。
import time, requests
def call_with_retry(url, headers, payload, max_retries=5):
for attempt in range(max_retries):
r = requests.post(url, headers=headers, json=payload)
if r.status_code == 429:
# honor Retry-After, otherwise exponential backoff
wait = int(r.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait)
continue
return r
return r