Aller au contenu

Limites de débit

L’API est soumise à une limitation de débit afin de rester rapide et équitable pour tous. Les limites sont appliquées à l’aide d’un algorithme de seau percé (leaky bucket) et sont agrégées par restaurant (sur l’ensemble des clés d’API de ce restaurant).

Les lectures et les écritures puisent dans deux budgets distincts, et une requête dépense exactement l’un des deux. GET, HEAD et OPTIONS dépensent le budget de lecture ; toute autre méthode — POST, PATCH, DELETE — dépense le budget d’écriture. Une écriture ne dépense jamais aussi du quota de lecture.

Limite Lectures Écritures
Débit soutenu ~2 requêtes par seconde ~1 requête par seconde
Rafale jusqu’à 60 requêtes jusqu’à 20 requêtes
Plafond quotidien ~25 000 requêtes par jour ~2 000 requêtes par jour

Le seau percé vous laisse brièvement effectuer une rafale, puis se vide au débit soutenu — ainsi un trafic régulier s’écoule sans à-coups, tandis que les pics sont lissés plutôt que bloqués net dès la première requête supplémentaire.

Le budget d’écriture est le plus bas parce qu’une création ou une modification prend un verrou sur la journée de service du restaurant pendant qu’elle cherche une table. Tout ce qui écrit ce jour-là — le back-office, le widget, l’équipe du restaurant — attend derrière. Une file de 250 écritures rejouée après une panne s’écoule tout de même en quatre minutes environ.

Lorsqu’une réponse communique l’état de la limite, elle le fait dans quatre en-têtes :

RateLimit-Limit: 60
RateLimit-Remaining: 42
RateLimit-Reset: 9
RateLimit-Resource: read
En-tête Signification
RateLimit-Limit La capacité du seau (taille de la rafale).
RateLimit-Remaining Le nombre de requêtes que vous pouvez encore effectuer maintenant.
RateLimit-Reset Le nombre de secondes avant que la capacité ne soit entièrement reconstituée.
RateLimit-Resource Le budget que les trois autres décrivent : read ou write.

Le triplet décrit toujours le budget que cette requête a dépensé. Réglez le rythme des lectures sur une réponse de lecture et celui des écritures sur une réponse d’écriture ; lire RateLimit-Remaining sans regarder RateLimit-Resource revient à suivre deux séries sans rapport sous un même nom.

Une réponse peut arriver sans aucun de ces en-têtes. Lorsque RateLimit-Remaining est absent, lisez-le comme « non communiqué » et non comme « illimité » : réglez votre rythme sur les limites du tableau ci-dessus, et continuez à respecter 429 et Retry-After.

Dépasser la limite renvoie 429 Too Many Requests avec un en-tête Retry-After (le nombre de secondes à attendre) et une enveloppe rate_limit_error :

HTTP/1.1 429 Too Many Requests
Retry-After: 1
RateLimit-Limit: 20
RateLimit-Remaining: 0
RateLimit-Reset: 1
RateLimit-Resource: write

RateLimit-Resource nomme le budget que vous avez épuisé. Il vaut ip lorsque aucun des deux seaux du restaurant n’a refusé l’appel et qu’une limite par adresse l’a fait, ce qui est un problème différent du quota de votre clé.

{
"error": {
"type": "rate_limit_error",
"code": "rate_limited",
"message": "Too many requests. Retry after 1 second.",
"doc_url": "https://docs.useservice.app/api/errors#rate_limited"
}
}
  • Respectez Retry-After. Sur un 429, attendez le nombre de secondes indiqué avant de réessayer.
  • Reculez de façon exponentielle en cas de 429 répétés, avec un peu de gigue (jitter).
  • Surveillez RateLimit-Remaining, et RateLimit-Resource avec lui, puis ralentissez avant d’atteindre zéro.
  • Réglez le rythme des écritures à part. Une boucle qui crée des réservations aussi vite qu’elle les lit épuise d’abord le budget d’écriture, et une tempête de nouvelles tentatives atteint la rafale d’écriture en moins d’une seconde.
  • Synchronisez de façon incrémentale. Utilisez updated_since au lieu de relire sans cesse des collections entières, et préférez les webhooks aux boucles de sondage serrées.