Guides

Error Handling

Handle errors gracefully and implement retries so your application stays resilient.

Error response format

Most errors on /v1/* endpoints return an OpenAI-style envelope:

JSON
{
  "error": {
    "message": "Wallet balance is insufficient. Top up at /wallet/topup.",
    "type": "insufficient_quota",
    "code": "insufficient_credit"
  }
}

code is the stable, machine-readable value to branch your error handling on — message wording can change. A small number of guards (per-key RPM/TPD rate limits — see Rate Limiting) instead return a bare {"detail": "..."} body; branch on the HTTP status for those, not the body shape.

Which errors to retry

429Yesrate_limit_exceeded. Wait and retry with exponential backoff (honor Retry-After when present).
503Yesmodel_unavailable / model_misconfigured. Every configured route for the model failed. Retry after a short wait — this is an operator-side issue, not your request.
402Noinsufficient_credit. Wallet empty. Top up at the dashboard before retrying.
401Noinvalid_api_key. Check the key and do not retry.
403Nokyc_required / permission_denied. Complete KYC or fix the key’s scopes — retrying as-is will not help.
404Nomodel_not_found. Check the model ID against GET /v1/models.
400NoBad request body — missing field, unsupported role/voice/language, input too long. Fix the payload before retrying.

Retry with exponential backoff

retry.py
from inferexai import InferexAI, InferexAIError
import time

client = InferexAI(api_key="sk-live-your-key")

def chat_with_retry(messages, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model="default",
                messages=messages,
            )
        except InferexAIError as e:
            if e.status == 402:
                raise RuntimeError("Wallet empty — top up at the dashboard") from e
            if e.status == 429 or e.status == 503:
                wait = 2 ** attempt          # 1s, 2s, 4s
                print(f"Retry {attempt + 1} after {wait}s...")
                time.sleep(wait)
                continue
            raise                            # 400, 401, 403, 404 — don't retry
    raise RuntimeError("Max retries exceeded")