Documentation

Documentation

Erreurs

Kunavo renvoie des charges utiles d’erreur au format OpenAI, accompagnées de codes d’état HTTP qui indiquent s’il faut réessayer. Utilisez la gestion des erreurs standard du SDK OpenAI pour traiter ces erreurs.

Toutes les réponses autres que 2xx ont la même structure JSON — celle de la norme OpenAI. Utilisez error.code pour le traitement programmatique et status_code pour déterminer la stratégie de nouvelle tentative.

Charge utile d’erreur

{
  "error": {
    "message": "Model 'xyz-2025' is not available",
    "type": "model_not_found",
    "code": "model_not_found",
    "param": null
  }
}
ChampTypeRemarques
messagestringLisible par un humain. Peut être journalisé en toute sécurité ; ne contient jamais de secrets.
typestringCatégorie générale (authentication_error, invalid_request_error, …).
codestringIdentifiant précis. À utiliser pour le branchement programmatique.
paramstring|nullLorsqu’une erreur concerne un champ précis, en indique le nom.

Codes d’état HTTP

HTTPSignificationRetry?
400invalid_request_error — votre charge utile est mal formée.Non — corrigez la requête.
401authentication_error — clé API incorrecte, manquante ou révoquée.Non — remplacez la clé.
402insufficient_quota — portefeuille vide (code: insufficient_balance) ou plafond mensuel atteint.Non — approvisionnez le compte sur /app/billing. Exception : un en-tête Retry-After signifie qu’un rechargement automatique est en cours ; réessayez ensuite.
403permission_error — la clé est valide, mais sa liste d’adresses IP autorisées ne vous inclut pas.Non — appelez depuis une adresse autorisée.
404model_not_found — identifiant de modèle inconnu ou désactivé.Non — consultez /v1/models.
404missing_v1_prefix — chemin de point de terminaison sur api.kunavo.com sans /v1, ou requête POST vers l’hôte seul.Non — définissez l’URL de base sur https://api.kunavo.com/v1.
404unknown_url — aucun point de terminaison à ce chemin sous /v1 ; le message indique le plus proche.Non — corrigez le chemin.
408Délai d’attente de la requête client.Oui, avec prudence concernant l’idempotence.
422upstream_422 — le fournisseur en amont a rejeté votre entrée (par exemple, taille non prise en charge).Non — ajustez l’entrée.
429Limitation du débit — trop d’appels simultanés.Oui — avec un délai exponentiel.
500Erreur interne de Kunavo.Oui — avec un bref délai.
502upstream_error — échec du fournisseur en amont.Oui — avec un délai exponentiel.
504Délai d’attente de la tâche dépassé (la génération d’images ou de vidéos a dépassé notre budget d’interrogation).Oui, mais prévoyez des frais.
Les appels échoués (4xx + 5xx) ne sont pas facturés. Le coût indiqué dans usage_logs est de $0. Exception : les délais d’attente 504 sur les API de tâches de longue durée peuvent afficher un coût amont si la tâche s’est terminée, mais que nous n’avons pas pu transmettre le résultat — cas rare.

Codes d’erreur courants

authentication_error

  • Vous avez oublié de définir l’en-tête Authorization: Bearer ....
  • La clé API a été révoquée depuis /app/keys.
  • La clé a toujours le mauvais préfixe (elle doit commencer par sk-kn-).

insufficient_quota

  • Solde du portefeuille trop faible pour cette requête → error.code vaut insufficient_balance, et l’erreur indique le montant détenu dans le portefeuille (balance_usd), le montant réservé pour cette requête (needed_usd), ainsi que deux liens : topup_url ouvre la page de facturation avec un rechargement déjà sélectionné, auto_recharge_url l’ouvre dans les paramètres de rechargement automatique. Aucun de ces liens ne déclenche de paiement à lui seul.
  • Plafond mensuel par clé atteint. La réinitialisation a lieu au début du mois civil (UTC). Augmentez le plafond sur /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"
  }
}

Cessez de réessayer après insufficient_balance, sauf si la réponse comporte un en-tête Retry-After — celui-ci signifie qu’un rechargement automatique est en train de débiter votre carte enregistrée ; la même requête devrait réussir quelques secondes plus tard.

permission_error

  • La clé comporte une liste d’adresses IP autorisées et votre appel provient d’une adresse qui n’y figure pas. Le message indique l’adresse détectée — ajoutez-la (ou son bloc CIDR) sur /app/keys, ou supprimez complètement la liste pour autoriser toutes les adresses.
  • Le déplacement d’un agent vers un nouvel hôte, une nouvelle passerelle NAT ou un ordinateur portable connecté à un autre réseau modifie cette adresse. Une clé sans liste d’adresses autorisées n’est jamais refusée pour cette raison.

model_not_found

  • Identifiant mal orthographié. Utilisez /models pour consulter la liste officielle.
  • Le modèle est actuellement désactivé (panne en amont ou examen tarifaire).

upstream_error

Indique qu’un fournisseur de modèles en amont a renvoyé une erreur que nous n’avons pas pu convertir en un code plus précis. Le corps de la réponse contient le message d’origine. Causes courantes :

  • Surcharge du fournisseur.
  • Rejet par la modération du contenu (essayez un autre prompt).
  • Restrictions liées à la région ou à la disponibilité.

Stratégie de nouvelle tentative

La méthode robuste la plus simple : un délai exponentiel avec une valeur aléatoire sur les erreurs 429 / 5xx uniquement.

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"}],
))
  • Limitez l’attente à 30 secondes par tentative et le total à 5 tentatives.
  • Ne réessayez pas après une erreur 4xx (sauf 408 et 429). Cela ne fait que vous faire perdre du temps.
  • La génération d’images et de vidéos n’est pas idempotente : une nouvelle tentative est une nouvelle génération, facturée si elle aboutit. Un appel en échec n’a jamais été facturé : le relancer est donc sans risque. Pour la vidéo, POST /v1/videos accepte un en-tête Idempotency-Key : une soumission répétée avec la même clé renvoie la première tâche.
  • Pour les échanges de chat ayant des effets secondaires dans votre propre code, éliminez les doublons à l’aide d’une clé d’idempotence dans la couche applicative.

Débogage depuis le tableau de bord

Chaque appel API — réussi ou échoué — est visible sur /app/usage. Cliquez sur une ligne pour afficher la page détaillée de la requête et de la réponse :

  • Code d’état HTTP renvoyé au client.
  • Code d’erreur amont (le cas échéant).
  • Latence, adresse IP de la requête, agent utilisateur.
  • Le filtrage par état permet de repérer des tendances (par exemple, toutes les erreurs 422 sur un modèle donné).

Signaler un incident

Si vous constatez des erreurs 5xx persistantes sur un modèle qui devrait fonctionner, écrivez à support@kunavo.com en indiquant :

  • L’identifiant du modèle et un exemple de corps de requête (en masquant les secrets).
  • La période durant laquelle les échecs se sont produits.
  • L’erreur code + message figurant dans la réponse.
  • Si possible, un lien vers le journal d’utilisation depuis /app/usage/[id].

Délai de réponse d’un jour ouvré, plus rapide pour les problèmes urgents qui affectent le chiffre d’affaires.

Étapes suivantes