Un 429 d’OpenAI signifie que vous avez franchi l’un des cinq plafonds — et la première tâche consiste à déterminer lequel, car les corrections vont dans des directions opposées. Cette page explique ce que mesure chaque limite, comment lire la réponse directement dans les en-têtes, quelle logique de nouvelle tentative arrête réellement les erreurs et quoi faire lorsque le backoff correct ne suffit pas.
Vérifié le 30 septembre 2026 par rapport à la documentation des limites de débit d’OpenAI.
Cinq limites, dont chacune peut déclencher l’erreur
| Métrique | Mesure | Se manifeste généralement lorsque |
|---|---|---|
| RPM | Requêtes par minute | Nombreuses petites requêtes — classification, embeddings, boucles d’agents |
| TPM | Tokens par minute | Quelques grandes requêtes — RAG avec un contexte récupéré volumineux, longs documents |
| RPD | Requêtes par jour | Niveaux Free et bas ; une tâche par lots qui termine le quota quotidien |
| TPD | Tokens par jour | Même chose, mesurée en tokens |
| IPM | Images par minute | Charges de génération d’images |
La première limite épuisée déclenche l’erreur ; ainsi, « nous sommes loin de la limite de tokens » ne permet pas d’écarter une limite de débit — vous pouvez être loin du TPM tout en étant exactement sur le RPM. Les limites s’appliquent par organisation et par modèle, et non par clé : créer des clés supplémentaires ne crée pas de quota supplémentaire.
À quoi ressemble un 429
HTTP/1.1 429 Too Many Requests
retry-after: 12
x-ratelimit-limit-requests: 500
x-ratelimit-remaining-requests: 0
x-ratelimit-reset-requests: 12s
x-ratelimit-limit-tokens: 200000
x-ratelimit-remaining-tokens: 143820
x-ratelimit-reset-tokens: 17s
{
"error": {
"message": "Rate limit reached for gpt-5.4 in organization org-... on requests per min (RPM).",
"type": "requests",
"code": "rate_limit_exceeded"
}
}Tout ce dont vous avez besoin se trouve dans cette réponse. Le corps nomme la dimension (« requests per min (RPM) »), tandis que les en-têtes indiquent le plafond exact, ce qu’il vous reste et le moment où il est rétabli.
| En-tête | Signification |
|---|---|
retry-after | Nombre minimal de secondes à attendre avant une nouvelle tentative |
x-ratelimit-limit-requests | Nombre maximal de requêtes autorisées avant d’épuiser la limite |
x-ratelimit-remaining-requests | Requêtes restantes avant épuisement |
x-ratelimit-limit-tokens | Nombre maximal de tokens autorisés |
x-ratelimit-remaining-tokens | Tokens restants |
x-ratelimit-reset-requests / -reset-tokens | Temps avant la réinitialisation de chaque compteur — ils se réinitialisent indépendamment |
Niveaux d’utilisation
Vos plafonds sont définis par votre niveau d’utilisation, qu’OpenAI augmente automatiquement à mesure que les dépenses cumulées s’accumulent :
| Niveau | Conditions d’accès | Limite d’utilisation mensuelle |
|---|---|---|
| Gratuit | Utilisateur situé dans une zone géographique autorisée | 100 $ / mois |
| Niveau 1 | 5 $ payés | 100 $ / mois |
| Niveau 2 | 50 $ payés | 500 $ / mois |
| Niveau 3 | 100 $ payés | 1 000 $ / mois |
| Niveau 4 | 250 $ payés | 5 000 $ / mois |
| Niveau 5 | 1 000 $ payés | 200 000 $ / mois |
Délibérément non reproduits ici : les chiffres RPM et TPM par modèle. Ils diffèrent selon le modèle, changent à la sortie de nouveaux modèles et peuvent être ajustés pour chaque compte — tout tableau publié sur un site tiers n’est donc qu’une estimation datée. Les deux sources faisant autorité pour votre compte sont la page des limites du tableau de bord OpenAI et les en-têtes x-ratelimit-* de chaque réponse que vous envoyez déjà. Lisez les en-têtes.
La solution : respecter Retry-After, puis ajouter une gigue
La recommandation documentée d’OpenAI est d’utiliser un backoff exponentiel avec gigue, en suivant Retry-After lorsque la réponse en contient un. Les deux aspects comptent. Sans l’en-tête, vous risquez de réessayer trop tôt ; sans la gigue, tous les clients qui ont échoué au même instant réessaient au même instant et échouent ensemble — un effet de troupeau qui transforme une mauvaise seconde en une mauvaise minute.
import random, time
import openai
client = openai.OpenAI()
def call_with_backoff(fn, *, max_attempts=6, base=0.5, cap=30.0):
"""Retry 429s: honour Retry-After when present, jittered backoff otherwise."""
for attempt in range(max_attempts):
try:
return fn()
except openai.RateLimitError as err:
if attempt == max_attempts - 1:
raise
# The server's own answer beats any formula you invent.
retry_after = (err.response.headers or {}).get("retry-after")
if retry_after:
delay = float(retry_after)
else:
# Full jitter: sleep a random point in [0, 2^n * base], capped.
# Without the randomness every client that failed at the same
# instant retries at the same instant and fails again together.
delay = random.uniform(0, min(cap, base * 2**attempt))
time.sleep(delay)
resp = call_with_backoff(lambda: client.responses.create(
model="gpt-5.4",
input="Summarise this changelog in three bullets.",
))La même logique en TypeScript :
import OpenAI from "openai";
const client = new OpenAI();
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
export async function callWithBackoff<T>(
fn: () => Promise<T>,
{ maxAttempts = 6, baseMs = 500, capMs = 30_000 } = {},
): Promise<T> {
for (let attempt = 0; ; attempt++) {
try {
return await fn();
} catch (err) {
const status = (err as { status?: number }).status;
if (status !== 429 || attempt === maxAttempts - 1) throw err;
const retryAfter = (err as { headers?: Headers }).headers?.get("retry-after");
const delay = retryAfter
? Number(retryAfter) * 1000
: Math.random() * Math.min(capMs, baseMs * 2 ** attempt);
await sleep(delay);
}
}
}
const resp = await callWithBackoff(() =>
client.responses.create({ model: "gpt-5.4", input: "Hello" }),
);Les SDK officiels réessaient déjà les 429 à votre place ; la plupart des applications n’en ont donc besoin que lorsqu’elles encapsulent les appels dans leur propre client HTTP ou lorsqu’elles veulent un comportement différent — un plafond plus long pour le travail en arrière-plan, ou un échec immédiat pour une requête destinée à l’utilisateur, lorsqu’attendre 12 secondes est pire qu’une erreur.
Surveillez avant la panne
Les compteurs figurent dans chaque réponse, pas uniquement dans les échecs. Journaliser les valeurs restantes transforme la limitation de débit d’un incident en jauge : vous pouvez voir la marge diminuer plusieurs jours avant qu’un lancement ne l’épuise.
# Log the remaining counters on every response, not just on failures.
# By the time you see a 429 the useful signal is already an hour old.
resp = client.responses.with_raw_response.create(model="gpt-5.4", input="…")
h = resp.headers
log.info(
"openai_quota model=%s req_left=%s tok_left=%s reset_req=%s reset_tok=%s",
"gpt-5.4",
h.get("x-ratelimit-remaining-requests"),
h.get("x-ratelimit-remaining-tokens"),
h.get("x-ratelimit-reset-requests"),
h.get("x-ratelimit-reset-tokens"),
)
parsed = resp.parse() # the normal response objectDeux habitudes à adopter en complément : déclencher une alerte lorsque x-ratelimit-remaining-tokens passe sous une certaine fraction de la limite plutôt que sur le nombre de 429, et ajouter une gigue aux planifications, pas seulement aux nouvelles tentatives. Un cron qui déclenche tout à :00 fabrique lui-même son pic de trafic.
Quand le backoff n’est pas la solution
Un backoff correct corrige les pics de trafic. Il ne fait rien face à une demande soutenue supérieure à votre plafond ; dans ce cas, les nouvelles tentatives ne font que déplacer l’échec. Les corrections structurelles, classées approximativement par effort :
- Plafonnez la sortie. Les tokens de raisonnement sont facturés et comptabilisés comme sortie ; une génération sans limite est donc le moyen le plus rapide de consommer le TPM.
- Réduisez le contexte récupéré. Avec un plafond TPM, diviser par deux les chunks récupérés double gratuitement votre débit.
- Dimensionnez correctement le modèle. Une étape de classification n’a pas besoin d’un modèle de pointe, et les petits modèles disposent de leur propre budget séparé.
- Séparez les charges de travail. Les tâches par lots et le trafic sensible à la latence qui se disputent un seul plafond au niveau de l’organisation constituent la forme la plus courante de ce problème que l’on s’inflige soi-même.
- Augmentez le niveau. Les niveaux évoluent avec les dépenses cumulées, donc cela est souvent déjà en cours.
Répartir la charge entre les familles de modèles
Le dernier élément de cette liste est l’endroit où une passerelle trouve sa justification. Kunavo expose une API compatible avec OpenAI — même SDK, même format d’appel, une seule clé — sur plusieurs familles de modèles ; déplacer une charge depuis un plafond saturé consiste donc à modifier le nom du modèle plutôt qu’à réaliser une seconde intégration :
from openai import OpenAI
client = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1",
)
# Same SDK, same call shape — the model string chooses the family.
client.chat.completions.create(
model="gpt-5-6-terra", # or claude-sonnet-5, claude-haiku-4-5, …
messages=[{"role": "user", "content": "Hello"}],
)Concrètement : la tâche de résumé par lots qui était en concurrence avec votre trafic de production peut s’exécuter sur claude-haiku-4-5 à $0.70 / $3.50 par million, tandis que le chemin sensible à la latence reste sur gpt-5-6-terra ($0.70 / $4.20) ou claude-sonnet-5 ($1.40 / $7.00). Famille différente, file différente.
Soyez clair sur ce que cela fait et ne fait pas. Cela supprime le goulot d’étranglement compte unique-modèle unique et vous donne une solution de basculement. Cela ne crée pas de capacité : si votre volume total dépasse réellement ce qu’autorise un niveau donné, la solution reste d’augmenter le niveau ou de réduire le travail. Les tarifs de chaque modèle figurent sur la page des tarifs, et le guide équivalent pour les limites d’Anthropic se trouve dans Claude API 429 rate_limit_error.
Questions fréquentes
Quelles sont les limites de débit de l’API d’OpenAI ?
OpenAI mesure simultanément cinq dimensions — RPM (requêtes par minute), TPM (tokens par minute), RPD (requêtes par jour), TPD (tokens par jour) et IPM (images par minute) — et renvoie HTTP 429 dès que l’une d’elles est dépassée. Les plafonds réels dépendent de votre niveau d’utilisation et du modèle concerné ; les chiffres faisant autorité pour votre compte se trouvent donc sur la page des limites de votre organisation dans le tableau de bord OpenAI et dans les en-têtes x-ratelimit-* de chaque réponse, et non dans un tableau publié.
Quels sont les niveaux d’utilisation d’OpenAI ?
En date du 30 septembre 2026, OpenAI documente six niveaux, chacun débloqué par des dépenses cumulées et associé à une limite d’utilisation mensuelle : Free (disponible dans les zones géographiques prises en charge, 100 $/mois), niveau 1 après 5 $ payés (100 $/mois), niveau 2 après 50 $ payés (500 $/mois), niveau 3 après 100 $ payés (1 000 $/mois), niveau 4 après 250 $ payés (5 000 $/mois) et niveau 5 après 1 000 $ payés (200 000 $/mois). La promotion est automatique à mesure que les dépenses s’accumulent.
Comment corriger un rate_limit_exceeded 429 d’OpenAI ?
Respectez l’en-tête Retry-After lorsque la réponse en contient un ; sinon, réessayez avec un backoff exponentiel et une gigue aléatoire — c’est la recommandation documentée par OpenAI. Les SDK officiels réessaient déjà automatiquement ; un client HTTP développé manuellement doit l’implémenter. Si les 429 persistent après un backoff correct, vous dépassez réellement votre quota plutôt que de produire un pic de trafic, et les corrections sont structurelles : réduisez la taille des lots, plafonnez les tokens de sortie maximaux, répartissez les tâches planifiées sur la minute ou passez à un niveau supérieur.
Quelle limite de débit ai-je réellement atteinte ?
Lisez les en-têtes. Une valeur nulle pour x-ratelimit-remaining-requests signifie que vous avez atteint la limite de requêtes ; une valeur nulle pour x-ratelimit-remaining-tokens signifie que vous avez atteint la limite de tokens. Les deux se réinitialisent indépendamment : x-ratelimit-reset-requests et x-ratelimit-reset-tokens indiquent quand chacune revient à la normale. Le corps du message nomme également la dimension. Deviner laquelle est en cause fait perdre du temps, car les corrections sont opposées : les limites de requêtes nécessitent une mise en file d’attente, tandis que les limites de tokens nécessitent des prompts plus courts.
Les limites de débit s’appliquent-elles par clé ou par organisation ?
Par organisation et par modèle, et non par clé. Créer des clés API supplémentaires ne crée pas de quota supplémentaire ; c’est pourquoi une charge de production intense et une tâche par lots dans la même organisation se disputent le même plafond — et pourquoi les isoler est plus important qu’ajouter des clés.
Une passerelle peut-elle aider à gérer les limites de débit d’OpenAI ?
Elle aide lorsque le plafond par modèle d’un compte constitue le goulot d’étranglement, car une passerelle vous permet de déplacer le travail vers une autre famille de modèles avec la même clé et le même SDK — une tâche de résumé par lots n’a pas besoin de se retrouver dans la même file que votre trafic sensible à la latence. Elle ne crée pas de capacité à partir de rien : si le volume total dépasse réellement ce qu’autorise un niveau donné, la solution reste d’augmenter le niveau ou de réduire le travail.
Pourquoi suis-je limité alors que mon compte est tout neuf ?
Les comptes Free et de niveau 1 ont des plafonds quotidiens (RPD et TPD) que les niveaux supérieurs n’ont pas ; un script de test modeste peut donc épuiser l’allocation d’une journée en une après-midi. Le niveau 1 est débloqué après 5 $ de paiements cumulés.
Un 429 me coûte-t-il quelque chose ?
Non : une requête rejetée n’est ni traitée ni facturée. Ce qu’elle coûte, c’est de la latence, ainsi que ce que votre logique de nouvelle tentative fait de cette latence.
Davantage de clés API me donneront-elles plus de débit ?
Non. Les limites s’appliquent par organisation et par modèle. Les clés supplémentaires servent à l’attribution et à la révocation, pas à augmenter la capacité.
Dois-je intercepter les 429 ou laisser le SDK les gérer ?
Laissez le SDK gérer le cas courant et interceptez-les vous-même lorsque le comportement par défaut ne vous convient pas : pour une requête destinée à l’utilisateur qui doit échouer rapidement, ou pour une tâche en arrière-plan qui peut tolérer un plafond bien plus long que celui par défaut.
Qu’en est-il des 429 qui correspondent en réalité à un quota épuisé ?
Une limite d’utilisation mensuelle épuisée apparaît également sous la forme d’un 429, et aucun backoff ne la réinitialisera — le corps du message distingue les deux cas. Si les compteurs des en-têtes sont corrects mais que vos requêtes sont toujours refusées, vérifiez la facturation avant de modifier votre code de nouvelle tentative.