文件
錯誤
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
}
}| 欄位 | 類型 | 備註 |
|---|---|---|
message | string | 可讀性高。可安全記錄;絕不包含密密。 |
type | string | 概括類別(authentication_ |
code | string | 細部識別碼。用於程式化分支判斷。 |
param | string|null | 若錯誤與特定欄位有關,會指出該欄位名稱。 |
HTTP 狀態碼
| HTTP | 意義 | Retry? |
|---|---|---|
| 400 | invalid_ — 您的 payload 格式錯誤。 | 否 — 修正請求。 |
| 401 | authentication_ — API 金鑰無效、缺少或已撤銷。 | 否 — 輪替金鑰。 |
| 402 | insufficient_ — 錢包餘額不足(code: insufficient_)或已達每月上限。 | 不會 — 請前往 /app/billing 儲值。例外:若出現 Retry-After 標頭,表示自動儲值正在處理;請稍後重試。 |
| 403 | permission_ — 金鑰有效,但其 IP 允許清單未包含您的 IP。 | 否 — 從允許的位址呼叫。 |
| 404 | model_ — 模型 ID 不明或已停用。 | 否 — 檢查 /v1/models。 |
| 404 | missing_ — api./v1,或是對裸主機發出 POST 請求。 | 否 — 將 base URL 設為 https://api. |
| 404 | unknown_url — /v1 下的該路徑沒有端點;訊息會指出最接近的端點。 | 否 — 修正路徑。 |
| 408 | 用戶端請求逾時。 | 是,但請留意冪等性。 |
| 422 | upstream_422 — 上游拒絕了您的輸入(例如:不支援的尺寸)。 | 否 — 調整輸入。 |
| 429 | 受到速率限制 — 同時進行的呼叫過多。 | 是 — 使用指數退避。 |
| 500 | Kunavo 內部錯誤。 | 是 — 短暫退避。 |
| 502 | upstream_ — 上游供應商發生錯誤。 | 是 — 使用指數退避。 |
| 504 | 工作逾時(圖像/影片生成超過我們的輪詢預算)。 | 是,但仍會產生費用。 |
失敗的呼叫(4xx + 5xx)不會計費。
usage_logs 中的費用欄位為 $0。例外情況:長時間執行的工作 API 若發生 504 逾時,但工作已完成而我們無法傳送結果,則可能會顯示上游費用;這種情況很少見。常見錯誤代碼
authentication_error
- 忘了設定
Authorization: Bearer ...標頭。 - API 金鑰已在
/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 seconds,總嘗試次數上限設為 5 attempts。
- 不要重試 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]的使用記錄連結。
一個工作日內回覆;對緊急且影響營收的問題會更快處理。