Docs
Errors
Kunavo returns OpenAI-shaped error payloads with HTTP status codes that signal whether you should retry. Stick to standard OpenAI-SDK error handling and you'll be fine.
Every non-2xx response has the same JSON shape — the OpenAI standard. Match on error.code for programmatic handling, on status_code for retry policy.
Error payload
{
"error": {
"message": "Model 'xyz-2025' is not available",
"type": "model_not_found",
"code": "model_not_found",
"param": null
}
}| Field | Type | Notes |
|---|---|---|
message | string | Human-readable. Safe to log; never includes secrets. |
type | string | Coarse category (authentication_error, invalid_request_error, …). |
code | string | Fine-grained identifier. Use for programmatic branching. |
param | string|null | When the error is about a specific field, names it. |
HTTP status codes
| HTTP | Meaning | Retry? |
|---|---|---|
| 400 | invalid_request_error — your payload is malformed. | No — fix the request. |
| 401 | authentication_error — bad / missing / revoked API key. | No — rotate the key. |
| 402 | insufficient_quota — wallet empty or per-key cap hit. | No — top up at /app/billing. |
| 404 | model_not_found — model id unknown or disabled. | No — check /v1/models. |
| 408 | Client request timeout. | Yes, with idempotency caution. |
| 422 | upstream_422 — upstream rejected your input (e.g. unsupported size). | No — adjust input. |
| 429 | Rate limited — too many concurrent calls. | Yes — exponential backoff. |
| 500 | Internal Kunavo error. | Yes — short backoff. |
| 502 | upstream_error — upstream provider failed. | Yes — exponential backoff. |
| 504 | Task timed out (image / video generation exceeded our poll budget). | Yes, but expect cost. |
usage_logs is $0. Exception: 504 timeouts on long-running task APIs may show upstream cost if the task completed but we couldn't deliver the result — rare.Common error codes
authentication_error
- Forgot to set
Authorization: Bearer ...header. - API key was revoked from
/app/keys. - Key still has wrong prefix (must start with
sk-kunavo-).
insufficient_quota
- Wallet balance ≤ $0 → top up at
/app/billing. - Per-key monthly cap reached. Reset is at calendar month start (UTC). Raise the cap at
/app/keys.
model_not_found
- Misspelled slug. Use /models for the canonical list.
- Model is currently disabled (upstream outage or pricing review).
upstream_error
Indicates the upstream provider (kie.ai or one of its sub-providers) returned an error that we couldn't translate to a more specific code. Body includes the original message. Common causes:
- Provider-side overload.
- Content moderation rejection (try a different prompt).
- Region / availability gating.
Retry strategy
The simplest robust pattern: exponential backoff with jitter on 429 / 5xx only.
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="gemini-3-flash",
messages=[{"role": "user", "content": "hi"}],
))- Cap the wait at 30 seconds per attempt and the total at 5 attempts.
- Don't retry 4xx (except 408 and 429). Doing so just burns time.
- For idempotent endpoints (image / video generation), retries are safe — failed calls were never billed.
- For chat with side effects in your own code, deduplicate via an idempotency key in your application layer.
Debugging from the dashboard
Every API call — successful or failed — is visible at /app/usage. Click any row for the full request/response detail page:
- HTTP status code returned to the client.
- Upstream error code (when applicable).
- Latency, request IP, user-agent.
- Filtering by status helps spot patterns (e.g. all 422s on a specific model).
Reporting an incident
If you see persistent 5xx for a model that should work, email support@kunavo.com with:
- The model slug and a sample request body (redact secrets).
- The time window when failures occurred.
- The error
code+messagefrom the response. - If possible, a usage-log link from
/app/usage/[id].
One-business-day response time, faster for urgent revenue-impacting issues.