Aller au contenu

Gestion des limites de requêtes

Les plafonds appliqués à une requête et la façon d'isoler les traitements par lots du checkout.

Un 429 n'est pas une défaillance de l'API. L'API vous indique qu'une partie de votre code envoie des requêtes plus vite que nécessaire. Si le problème atteint un client, c'est uniquement parce que le job trop actif et l'appel du checkout partagent le même quota.

Le tableau des quotas se trouve dans Limites de requêtes. Cette page vous aide à ne pas atteindre ces limites.

Trois plafonds vérifiés dans l'ordre

Chaque requête authentifiée passe par trois compteurs indépendants, chacun calculé sur une fenêtre de 60 secondes. Le premier compteur plein interrompt la requête et son nom apparaît dans le corps de la réponse.

typeComptabilisePlafond
teamToutes les requêtes de votre équipeLe plafond de votre plan
api_keyToutes les requêtes effectuées avec une même cléLe même plafond que l'équipe
endpointLes requêtes qui concernent payments, transfers, refunds ou customersPlus strict, avec une valeur adaptée au plan

Deux conséquences sont à retenir. Toutes les clés puisent dans le même budget d'équipe : répartir le trafic entre plusieurs clés n'ajoute donc aucune marge. Les plafonds par endpoint sont aussi les premiers touchés lors d'un pic : une boucle sur les paiements déclenche endpoint bien avant team. Sur Enterprise, aucun des trois n'est compté.

Les requêtes envoyées sans clé reconnue sont limitées à 30 par minute et par IP, avec type à ip. C'est la limite que vous rencontrez lorsqu'une clé est incorrecte, et non simplement très sollicitée.

Lisez le plafond, ne l'écrivez pas en dur

Chaque réponse indique la consommation actuelle de votre équipe. Ces trois en-têtes font foi et leurs valeurs évoluent avec votre plan.

En-têtes présents dans chaque réponse
X-RateLimit-Limit: 360
X-RateLimit-Remaining: 357
X-RateLimit-Reset: 1748083260

Si l'un de vos jobs approche de la limite, faites-lui lire X-RateLimit-Remaining et ralentir avant d'être bloqué. Réagir à l'en-tête ne coûte rien. Réagir au 429 ajoute un aller-retour et un délai que vous n'avez pas choisi.

Deux formes de réponse 429

La plupart des réponses 429 proviennent des compteurs ci-dessus et contiennent un type. Quelques routes possèdent une seconde limitation dédiée et répondent sans ce champ. Les écritures de payout sont les plus importantes : POST /transfers, POST /transfers/batch, POST /accounts/{id}/payouts, POST /beneficiaries, POST /beneficiaries/{id}/receivables et POST /beneficiaries/{id}/receivables/{receivable}/settle partagent un plafond fixé à 20 requêtes par minute, par équipe et par environnement, quel que soit votre plan, car un payout s'exécute sans intervention humaine. Une boucle qui crée un bénéficiaire puis le paie compte deux fois.

Les deux corps de réponse
{
  "code": 429,
  "status": "Too Many Requests",
  "message": "Too many requests",
  "type": "endpoint",
  "retry_after": 24,
  "retry_after_human": "00:00:24"
}

{
  "code": 429,
  "status": "Too Many Requests",
  "message": "Too Many requests. Merchant limit : 360",
  "retry_after": 24
}

Lisez type lorsqu'il est présent. S'il est absent, considérez qu'il s'agit d'une limite propre à la route, et non d'une réponse incorrecte. Les deux formes contiennent retry_after en secondes. Seule la première définit aussi l'en-tête Retry-After.

Respectez le délai indiqué

Le délai se trouve dans la réponse. L'estimer vous fait soit attendre inutilement, soit recevoir un second 429.

Respectez Retry-After, puis augmentez progressivement l'attente
import { WajubRateLimitError } from '@wajub/node';

export async function withRateLimitRetry(fn, maxAttempts = 5) {
  for (let attempt = 1; ; attempt++) {
    try {
      return await fn();
    } catch (err) {
      if (!(err instanceof WajubRateLimitError) || attempt >= maxAttempts) throw err;

      const seconds = err.retryAfter ?? 2 ** attempt;
      await new Promise((r) => setTimeout(r, seconds * 1000 + Math.random() * 500));
    }
  }
}

Le SDK lit Retry-After et place sa valeur dans err.retryAfter. La part d'aléa est importante lorsque plusieurs workers ont été limités en même temps. Sans elle, ils reprennent tous au même instant et remplissent de nouveau le compteur qu'ils attendaient.

Isolez les traitements par lots du checkout

Les opérations de rapprochement, les exports de règlements et toute boucle sur les transferts ou les bénéficiaires provoquent souvent des réponses 429. Ce sont aussi les traitements les plus simples à corriger, car personne n'attend leur résultat.

HabitudeÀ faire à la place
Promise.all sur tous les identifiantsUne boucle cadencée sous le plafond de l'endpoint, voir Performances
Une opération chaque minuteUne opération toutes les 15 minutes, sur une fenêtre plus large
Lancer l'export à midiLe lancer lorsque votre checkout est peu sollicité
Une seule clé pour toutUne clé restreinte distincte pour les traitements par lots, limitée aux lectures nécessaires

Une clé distincte ne protège pas le checkout à elle seule : toutes les clés puisent dans le même budget d'équipe et les mêmes plafonds par endpoint. Elle vous permet de révoquer le job sans toucher au checkout. Seul l'espacement des appels empêche un export incontrôlé de consommer les requêtes dont votre checkout a besoin.

Lorsque vous avez réellement besoin de plus

Si le plafond limite du trafic réel et non une boucle, c'est le nombre de requêtes par minute de votre plan qui doit évoluer. Contactez le support en indiquant l'endpoint, le profil de trafic et le volume attendu. Augmenter la limite d'un job qui interroge chaque paiement toutes les cinq secondes ne fait que repousser le problème.

Que pensez-vous de ce contenu ?