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.

Quatre plafonds vérifiés dans l'ordre

Chaque requête authentifiée passe par quatre compteurs indépendants, chacun calculé sur une fenêtre glissante 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é100 par minute
ipToutes les requêtes provenant d'une même adresse source120 par minute
endpointLes requêtes qui concernent payments, transfers, refunds ou customersPlus strict, avec une valeur adaptée au plan

Deux conséquences sont à retenir. Le plafond de 100 requêtes par clé est inférieur à celui de la plupart des plans. Répartir le trafic entre plusieurs clés augmente donc réellement votre marge, alors que tout faire passer par une seule clé la réduit. 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.

Les requêtes envoyées sans clé reconnue sont limitées à 30 par minute et par 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 quatre compteurs ci-dessus et contiennent un type. Quelques routes possèdent une seconde limitation dédiée et répondent sans ce champ. La route POST /transfers est la plus importante : son plafond est fixé à 20 requêtes par minute et par équipe, quel que soit votre plan, car un payout s'exécute sans intervention humaine.

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 et définissent 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 identifiantsUn groupe de 5 à 10, 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é distincte pour les traitements par lots, avec sa propre limite de 100 par minute

La dernière ligne offre le gain le plus simple. Une clé restreinte aux lectures nécessaires à votre job possède son propre compteur. Un export incontrôlé épuise donc son propre quota sans toucher à la clé utilisée par votre checkout.

Lorsque vous avez réellement besoin de plus

Si le plafond limite du trafic réel et non une boucle, c'est la valeur max_requests du 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 ?