Erreurs et limites
Les erreurs suivent le format OpenAI : un objet error avec type, code et message. Cette page liste tout ce que l'API peut vous renvoyer et la bonne réaction à chaque cas.
Les statuts
| Statut | error.code |
Cause | Réaction |
|---|---|---|---|
400 |
— | corps de requête invalide | corriger la requête |
400 |
model_unknown |
nom nu ne correspondant à aucun modèle connu | vérifier le nom via GET /v1/models |
400 |
model_ambiguous |
nom nu correspondant à plusieurs modèles | utiliser l'id complet vendor/model |
401 |
— | clé absente, invalide ou révoquée | vérifier la clé (Authentification) |
402 |
insufficient_credits |
solde prépayé épuisé | recharger via la console (Coûts) |
413 |
— | corps de requête au-delà de la taille maximale | réduire la taille (contexte, pièces jointes) |
429 |
rate limit | trop de requêtes sur la fenêtre | respecter Retry-After, lisser le trafic |
429 |
spend_cap_exceeded |
plafond de dépense journalier atteint | attendre minuit UTC (Retry-After) ou ajuster le plafond |
504 |
— | fournisseur amont injoignable après retries | retenter avec backoff |
Erreurs des fournisseurs amont : normalisées
Quand le fournisseur amont refuse ou échoue, OpenMulti préserve le statut HTTP d'origine mais normalise le corps — le détail brut du fournisseur n'est jamais relayé :
{
"error": {
"type": "upstream_error",
"code": 503,
"message": "..."
}
}
error.type |
Sens |
|---|---|
rate_limit_error |
l'amont rate-limite (429) |
upstream_rejected |
l'amont a refusé la requête (4xx) |
upstream_error |
erreur serveur amont (5xx) |
error.code porte le statut HTTP renvoyé par l'amont. Notez qu'avant de vous renvoyer une erreur transitoire, OpenMulti a déjà retenté le même modèle et basculé de chemin d'accès quand c'était possible.
Limites
- Taille du corps — les requêtes trop volumineuses reçoivent
413. - Débit — une limite de requêtes par minute et par projet peut s'appliquer ; en cas de
429, l'en-têteRetry-Afterfait foi. - Champs inconnus — retirés silencieusement avant transmission, jamais une cause d'erreur.
- Flux figé — un stream amont sans chunk pendant 60 s est coupé.
Stratégie de retry recommandée
import time, random
def call_with_retry(fn, max_attempts=4):
for attempt in range(max_attempts):
try:
return fn()
except Exception as e:
status = getattr(e, "status_code", None)
retriable = status in (429, 500, 502, 503, 504)
if not retriable or attempt == max_attempts - 1:
raise
retry_after = getattr(getattr(e, "response", None), "headers", {}).get("retry-after")
delay = float(retry_after) if retry_after else min(2 ** attempt, 30) + random.random()
time.sleep(delay)
- Retentez
429et5xxavec backoff exponentiel et jitter ; respectezRetry-Afterquand il est présent. - Ne retentez pas
400,401,402: la cause ne disparaîtra pas d'elle-même. 402et429 spend_cap_exceededsont des signaux de facturation, pas des pannes — traitez-les côté produit (Coûts et facturation).