Limites de requêtes
Les limites de requêtes par forfait communes à Listings et Social, la structure de la réponse 429 et la façon d'espacer les nouvelles tentatives.
Listings API comptabilise les requêtes par compte en fonction de la limite de votre forfait. Respecter cette limite permet à votre intégration de rester réactive ; la dépasser entraîne une réponse 429 Too Many Requests contenant tout ce dont vous avez besoin pour effectuer une nouvelle tentative dans de bonnes conditions.
Limites par forfait
Vous essayez l'API sans forfait payant ? L'accès à la journée gratuit à l'environnement de test fournit ses limites de requêtes en vigueur avec la clé API lorsque vous activez cet accès.
Les limites dépendent du forfait et s'appliquent par compte : toutes les clés API d'un compte utilisent le même quota. Les requêtes sont comptabilisées sur trois fenêtres temporelles : une limite par minute pour les pics de trafic, une limite horaire et un plafond quotidien. Chaque requête a le même coût, quel que soit le point de terminaison. Un essai gratuit utilise le forfait que vous avez choisi et est donc soumis aux limites de ce forfait dès la première requête.
Social utilise le même quota
Les requêtes vers les points de terminaison Social sont décomptées du même quota de requêtes par compte que toutes les autres requêtes. Un appel POST /social/bulk-posts contenant 500 lignes compte pour une requête, et non 500 ; les opérations en masse sont donc le moyen le plus économique de charger beaucoup de contenu.
Listings et Social font l'objet d'abonnements distincts, mais ne disposent pas de quotas distincts. Un compte disposant des deux bénéficie des limites les plus élevées des deux forfaits, appliquées une seule fois à l'ensemble des points de terminaison — sans addition des limites ni quota par produit. Pour un client disposant de Listings Launch et de Social Growth, l'ensemble du trafic est soumis aux limites Growth indiquées ci-dessus.
La réponse 429
Lorsque vous dépassez une limite, l'API renvoie le statut HTTP 429 et la réponse d'erreur standard. Trois champs sont utiles pour les nouvelles tentatives :
retry_after_seconds: le délai à attendre avant une nouvelle tentative. L'en-tête HTTPRetry-Aftercontient la même valeur lorsqu'il est présent.correlation_id: un identifiant de requête à communiquer si vous contactez l'assistance.doc_url: un lien vers l'entréerate_limitedde la référence des codes d'erreur.
{ "error": { "code": "RATE_LIMITED", "message": "Too many requests. Slow down.", "retry_after_seconds": 30, "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c", "doc_url": "https://listingsapi.com/docs/error-codes#rate_limited" }}Gestion des réponses 429 avec un délai d'attente progressif
Respectez retry_after_seconds lorsqu'il est présent et, sinon, augmentez le délai d'attente de façon exponentielle : doublez-le à chaque réponse 429 consécutive jusqu'à un plafond, en ajoutant une légère variation aléatoire afin qu'un ensemble de clients ne relance pas ses requêtes simultanément.
import randomimport time import requests MAX_RETRIES = 5 def get_with_backoff(url: str, headers: dict, max_retries: int = MAX_RETRIES): for attempt in range(max_retries): resp = requests.get(url, headers=headers) if resp.status_code != 429: resp.raise_for_status() return resp.json() # Prefer the server's hint; fall back to exponential backoff + jitter. body = resp.json().get("error", {}) retry_after = body.get("retry_after_seconds") if retry_after is None: retry_after = min(2 ** attempt, 30) + random.uniform(0, 1) time.sleep(retry_after) raise RuntimeError("Still rate limited after retrying")Rester sous la limite
- Demandez une seule page à la fois : les boucles de pagination qui enchaînent rapidement les requêtes en parallèle sont la cause la plus fréquente des réponses
429. LisezpageInfo.hasNextPageet ne récupérez la page suivante qu'une fois la page en cours reçue. - Filtrez côté serveur à l'aide du paramètre de requête
filterau lieu de récupérer toutes les pages et d'écarter des lignes côté client. - Mettez en cache les réponses qui changent peu souvent plutôt que de les récupérer à nouveau à chaque requête.