文档

文档

错误

Kunavo 返回符合 OpenAI 格式的错误负载,并通过 HTTP 状态码指示是否应重试。遵循 OpenAI SDK 的标准错误处理方式即可。

每个非 2xx 响应都采用相同的 JSON 结构,即 OpenAI 标准格式。程序化处理时匹配 error.code,制定重试策略时匹配 status_code。

错误负载

{
  "error": {
    "message": "Model 'xyz-2025' is not available",
    "type": "model_not_found",
    "code": "model_not_found",
    "param": null
  }
}
字段类型备注
messagestring人类可读。可安全记录日志;绝不包含机密。
typestring粗略类别(authentication_error、invalid_request_error 等)。
codestring更精细的标识符。用于编写程序分支逻辑。
paramstring|null如果错误与特定字段有关,这里会指出该字段。

HTTP 状态码

HTTP含义Retry?
400invalid_request_error — 请求负载格式错误。否 — 修正请求。
401authentication_error — API 密钥无效、缺失或已撤销。否 — 轮换密钥。
402insufficient_quota — 钱包余额为零(code: insufficient_balance)或已达到月度上限。不能 — 请前往 /app/billing 充值。例外情况:Retry-After 标头表示自动充值正在处理中;处理完成后重试。
403permission_error — 密钥有效,但其 IP 允许列表未包含你的 IP。否 — 从允许的地址发起调用。
404model_not_found — 模型 ID 未知或已停用。否 — 检查 /v1/models。
404missing_v1_prefix — 在 api.kunavo.com 上请求的端点路径缺少 /v1,或向裸主机名发送了 POST 请求。否 — 将 base URL 设为 https://api.kunavo.com/v1。
404unknown_url — /v1 下该路径没有端点;错误消息会指出最接近的端点。否 — 修正路径。
408客户端请求超时。是,但需注意幂等性。
422upstream_422 — 上游拒绝了你的输入(例如,不支持的尺寸)。否 — 调整输入。
429触发速率限制 — 并发调用过多。是 — 使用指数退避。
500Kunavo 内部错误。是 — 短暂退避。
502upstream_error — 上游提供商故障。是 — 使用指数退避。
504任务超时(图像 / 视频生成超出了轮询预算)。可以,但仍会产生费用。
失败的调用(4xx + 5xx)不计费。usage_logs 中的成本记录为 $0。例外情况:长时间运行的任务 API 出现 504 超时时,如果任务已完成但我们未能交付结果,可能会显示上游成本——这种情况很少见。

常见错误代码

authentication_error

  • 忘记设置 Authorization: Bearer ... 标头。
  • API key 已在 /app/keys 撤销。
  • 密钥仍使用错误的前缀(必须以 sk-kn- 开头)。

insufficient_quota

  • 钱包余额不足,无法处理此请求 → error.code 为 insufficient_balance;错误信息会附带钱包当前余额(balance_usd)、此请求的预留金额(needed_usd)以及两个链接:topup_url 会打开已预先填入充值金额的账单页面,auto_recharge_url 会打开自动充值设置页面。点击任一链接本身都不会产生扣款。
  • 已达到单个密钥的月度上限。该上限会在每个日历月月初(UTC)重置。请前往 /app/keys 提高上限。
{
  "error": {
    "message": "Wallet balance is too low for this request. Top up at https://kunavo.com/app/billing — or turn on auto-recharge there, and a saved card refills the wallet before requests are refused.",
    "type": "insufficient_quota",
    "code": "insufficient_balance",
    "param": null,
    "balance_usd": 0.0142,
    "needed_usd": 0.0381,
    "topup_url": "https://kunavo.com/app/billing?topup=20",
    "auto_recharge_url": "https://kunavo.com/app/billing?autorecharge=1&src=api_402"
  }
}

遇到 insufficient_balance 时请停止重试,除非响应中包含 Retry-After 标头——这表示自动充值正在从您保存的银行卡扣款,几秒后使用相同请求即可成功。

permission_error

  • 该密钥设置了 IP 允许列表,而您的调用来自列表之外的地址。错误消息会指出我们检测到的地址——请在 /app/keys 添加该地址(或其 CIDR 网段),或完全移除允许列表以允许任何地址。
  • 将智能体迁移到新主机、新 NAT 网关,或换到不同网络上的笔记本电脑,都会改变该地址。未设置允许列表的密钥不会因此被拒绝。

model_not_found

  • Slug 拼写错误。规范列表请使用 /models。
  • 模型目前已停用(上游服务中断或正在审核定价)。

upstream_error

表示上游模型提供商返回了一个我们无法转换为更具体代码的错误。响应正文包含原始消息。常见原因:

  • 提供商侧过载。
  • 内容审核未通过(请尝试更换提示词)。
  • 区域或可用性限制。

重试策略

最简单且可靠的模式:仅在 429 / 5xx 时使用带抖动的指数退避。

import time, random
from openai import OpenAI, RateLimitError, APIError

client = OpenAI(api_key=os.environ["KUNAVO_API_KEY"], base_url="https://api.kunavo.com/v1")

def call_with_retry(call, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            return call()
        except RateLimitError:
            if attempt + 1 == max_attempts: raise
            # 429: exponential backoff with jitter
            time.sleep(min(2 ** attempt, 30) + random.random())
        except APIError as e:
            if e.status_code and 500 <= e.status_code < 600 and attempt + 1 < max_attempts:
                time.sleep(min(2 ** attempt, 30) + random.random())
            else:
                raise

result = call_with_retry(lambda: client.chat.completions.create(
    model="claude-haiku-4-5",
    messages=[{"role": "user", "content": "hi"}],
))
  • 每次尝试的等待时间上限为 30 秒,总尝试次数上限为 5 次。
  • 不要重试 4xx(408 和 429 除外)。这样只会浪费时间。
  • 图像和视频生成都不是幂等的:每次重试都是一次新的生成,成功才计费。失败的调用从未计费,因此重试它们是安全的。对于视频,POST /v1/videos 支持 Idempotency-Key 请求头:用相同的幂等键重复提交,会返回第一个任务。
  • 对于在你自己的代码中带有副作用的聊天请求,请在应用层通过幂等键进行去重。

在控制面板中调试

每次 API 调用——无论成功还是失败——都会显示在 /app/usage。点击任意行可查看完整的请求 / 响应详情页:

  • 返回给客户端的 HTTP 状态码。
  • 上游错误代码(如适用)。
  • 延迟、请求 IP、user-agent。
  • 按状态筛选有助于发现规律(例如,特定模型的所有 422 错误)。

报告事故

如果某个本应正常工作的模型持续出现 5xx 错误,请发送邮件至 support@kunavo.com,并提供:

  • 模型 slug 和一份示例请求正文(请隐去机密信息)。
  • 故障发生的时间段。
  • 响应中的错误 code + message。
  • 如有可能,提供来自 /app/usage/[id] 的使用日志链接。

一个工作日内回复;对紧急且影响收入的问题会更快处理。

接下来