Limites
Les plafonds d'appels par clé, le 429 avec Retry-After et les en-têtes RateLimit, et comment reprendre sans surcharger.
L'API limite le rythme des appels, clé par clé. Un dépassement reçoit un 429 RATE_LIMITED. Il ne coûte aucun crédit et dit quand réessayer.
Les plafonds d'une clé
| Plafond | Valeur | Ce qui compte |
|---|---|---|
| Par seconde | 10 appels | Tous les appels de la clé |
| Par minute | 300 appels | Tous les appels de la clé |
| Écritures | 60 par minute | Les opérations de nature write |
| Suppressions | 20 par minute | Les opérations de nature delete |
Les compteurs sont propres à chaque clé : un outil bavard ne ralentit pas les autres. Une écriture compte aussi dans les deux plafonds généraux. Une lecture ne compte jamais dans les deux derniers. La nature d'une opération se lit dans kind de GET /operations, pas dans la méthode HTTP, puisque toutes les opérations passent par POST.
Lire un 429
HTTP/1.1 429 Too Many Requests
Retry-After: 1
RateLimit-Limit: 10
RateLimit-Remaining: 0
RateLimit-Reset: 1Le corps est { "error": { "name": "PARTNER_API", "message": "RATE_LIMITED" } }. Retry-After donne les secondes à attendre. Les en-têtes RateLimit-* disent où tu en es : la limite, ce qu'il reste et le délai avant la remise à zéro.
Reprendre après un 429
Attends Retry-After secondes, puis réessaie. Si le 429 revient, attends de plus en plus longtemps : une, deux, quatre secondes. Pour une écriture, garde la même Idempotency-Key : un 429 n'est jamais stocké, donc le nouvel essai s'exécute.
La fonction call de Écrire un script attend déjà Retry-After. L'attente croissante est à ajouter, voici le principe :
Python
wait = 1
for _ in range(5):
res = requests.request(method, url, headers=headers, json=body)
if res.status_code != 429:
break
time.sleep(max(int(res.headers.get("Retry-After", 0)), wait))
wait *= 2JavaScript
let wait = 1;
for (let attempt = 0; attempt < 5; attempt++) {
const res = await fetch(url, { method, headers, body });
if (res.status !== 429) return res;
const retryAfter = Number(res.headers.get("Retry-After") ?? 0);
await new Promise((done) =>
setTimeout(done, Math.max(retryAfter, wait) * 1000)
);
wait *= 2;
}Rester sous les plafonds
- Demande
limit=200sur les listes et ne relis que les changements avecsince: Pagination. - Étale les appels au lieu de les lancer tous ensemble : 10 par seconde est vite atteint.
- Crée une clé par outil, pour que chacun ait ses compteurs.
Un 429 n'est pas un 402. Le 429 vient du rythme et passe tout seul. Le 402 vient d'un solde vide : voir Clés et crédits.