Accueil → Aide

Un 429 d'une passerelle d'API peut signifier deux choses différentes

Lisez le corps, pas le code de statut. Un 429 dû à un solde vide ne réussira jamais en relançant, peu importe le temps d'attente. Un 429 dû à une congestion de l'amont se résout généralement en quelques secondes.

Ce que vous voyez

Pourquoi cela arrive

HTTP n'a pas de statut qui signifie « vous n'avez plus d'argent ». 402 Payment Required existe mais n'est presque jamais utilisé, donc les passerelles surchargent 429 pour la facturation comme pour la limitation. Les deux sont opposés à tous égards : l'un est permanent tant que vous n'agissez pas, l'autre est transitoire et se résout tout seul.

C'est important parce que la plupart des mécanismes de relance des SDK se basent uniquement sur le code de statut. Le client Python d'OpenAI relance les 429 par défaut. Pointez-le vers une passerelle au solde vide et il épuisera toutes ses tentatives sur une requête qui ne peut pas réussir, puis affichera un timeout, ce qui vous envoie chercher un problème réseau qui n'existe pas.

Il existe une troisième cause à connaître, car elle ressemble à la deuxième et se corrige autrement : une limite de concurrence par compte. Le message la nomme directement — Concurrency limit exceeded for user, please retry later. Il ne s'agit pas du nombre de requêtes envoyées en une minute, mais du nombre de requêtes en cours au même instant. Attendre aide, mais la vraie correction est de plafonner le parallélisme dans votre client ; c'est l'augmenter qui a provoqué l'erreur.

Vérifiez si c'est bien la cause

Faites une requête et regardez le corps plutôt que le statut :

curl -s -o /tmp/r.json -w '%{http_code}\n' \
  'YOUR_BASE_URL/chat/completions' \
  -H 'Authorization: Bearer YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"model":"YOUR_MODEL","messages":[{"role":"user","content":"hi"}],"max_tokens":1}'

cat /tmp/r.json

Un code ou un message mentionnant quota, balance ou credit indique la facturation. Tout ce qui mentionne rate, busy ou upstream indique une limitation. Si le corps est vide, cherchez l'en-tête Retry-After : sa présence pointe vers une limitation.

Comment le corriger

  1. Décidez selon le corps avant de relancerAnalysez le JSON et traitez les 429 de facturation comme fatals. Les relancer gaspille vos tentatives et cache la vraie cause derrière un timeout.
  2. Respectez Retry-After quand il est présentLes réponses de limitation le contiennent souvent. En son absence, un backoff exponentiel commençant vers une seconde est un choix raisonnable ; relancer immédiatement aggrave généralement la congestion.
  3. Surveillez le solde séparément des erreursUn solde vide est un événement commercial, pas un incident. La plupart des passerelles exposent le solde via leur propre API ou un tableau de bord : surveillez ce chiffre et vous ne rencontrerez jamais ce 429 en production.
  4. Plafonnez les requêtes simultanées, pas seulement le débitSi le message parle de concurrence, une boucle de relance plus lente n'aidera pas — la limite compte les requêtes simultanées. Un sémaphore autour de votre client, dimensionné selon ce que permet la passerelle, règle vraiment le problème.
  5. N'augmentez pas la concurrence pour corriger un 429 de limitationPlus de requêtes parallèles contre un amont saturé produisent plus de 429, pas plus de débit. Réduisez la concurrence et laissez le backoff faire son travail.
Sur APICLAN, les deux se distinguent sans deviner. Un solde vide renvoie {"code":"API_KEY_QUOTA_EXHAUSTED"} ; une congestion de l'amont renvoie {"error":{"type":"api_error","message":"Upstream rate limit exceeded, please retry later"}}. Votre solde est sur le tableau de bord, et les recharges s'appliquent immédiatement.

Voir aussi

Unexpected token '<' lors d'un appel à une API compatible OpenAI401 invalid API key : quand la clé semble correcte mais échoue quand même

Dernière vérification le 2026-10-01. Rédigé à partir de problèmes diagnostiqués sur une passerelle compatible OpenAI en production, pas compilé à partir d'autres sites.