DocsGuidesRate limits

Rate limits

Lire les en-têtes X-RateLimit, anticiper les quotas et gérer les 429 avec file d'attente, backoff exponentiel et respect de Retry-After.

Guides3 min de lectureMis à jour le 10 juin 2026
Télécharger en PDF

L'API Coffrify applique une limite de débit par espace de travail pour garantir un service stable et équitable. Chaque réponse vous indique précisément où vous en êtes via une série d'en-têtes X-RateLimit-*, et lorsque vous dépassez votre quota, l'API répond avec le statut 429 et un en-tête Retry-After. Ce guide explique comment lire ces signaux, les anticiper côté client, et mettre en place des stratégies robustes : file d'attente, backoff exponentiel avec jitter, et respect strict de Retry-After.

Comment fonctionne la limite

La limite s'applique par espace de travail sur une fenêtre glissante de 60 secondes. Elle est calculée séparément selon la classe de l'endpoint appelé, ce qui vous laisse beaucoup de marge en lecture tout en protégeant les opérations plus coûteuses. Toutes vos clés d'un même espace de travail (live et test) partagent le même compteur. Les requêtes en environnement sandbox ne sont pas concernées par ces quotas : elles relèvent de garde-fous distincts.

ClasseEndpoints concernés
readLes lectures GET (lister, récupérer un transfert, etc.)
writeLes écritures POST, PATCH, PUT, DELETE (créer un transfert, etc.)
expensiveLes opérations lourdes : listes paginées volumineuses, export d'audit, synthèses analytiques

Les en-têtes de limite

Chaque réponse de l'API porte ces quatre en-têtes. Ils sont exposés via CORS, vous pouvez donc les lire aussi bien côté serveur que depuis un navigateur.

En-têteSignification
X-RateLimit-LimitLe quota maximal pour la classe d'endpoint et votre plan, sur la fenêtre de 60 s.
X-RateLimit-RemainingLe nombre de requêtes encore autorisées dans la fenêtre courante.
X-RateLimit-ResetL'horodatage Unix (secondes UTC) auquel le quota se réinitialise.
X-RateLimit-PolicyLa politique sous la forme <limite>;w=60 (fenêtre de 60 secondes).
HTTP/1.1 200 OK
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 587
X-RateLimit-Reset: 1749552000
X-RateLimit-Policy: 600;w=60

La réponse 429

Quand vous dépassez le quota, l'API renvoie le statut 429 avec le code d'erreur rate_limited et un en-tête Retry-After qui indique le nombre de secondes à attendre avant de réessayer. Respectez cette valeur : c'est le délai exact au-delà duquel votre prochaine requête sera de nouveau acceptée.

POST/v1/transfersEn cas de dépassement, répond 429 rate_limited avec Retry-After.
HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1749552000
X-RateLimit-Policy: 600;w=60
Content-Type: application/json
 
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded for this workspace.",
"request_id": "req_8sJ2c0Qd"
}
}

Anticiper plutôt que subir

La meilleure stratégie consiste à ne jamais atteindre la limite. Surveillez X-RateLimit-Remaining après chaque appel et ralentissez volontairement quand il approche de zéro. Vous lissez ainsi votre trafic au lieu de l'envoyer par rafales qui déclenchent des 429.

const res = await fetch("https://api.coffrify.com/v1/transfers", {
headers: { Authorization: `Bearer ${process.env.COFFRIFY_API_KEY}` },
});
 
const remaining = Number(res.headers.get("X-RateLimit-Remaining"));
const reset = Number(res.headers.get("X-RateLimit-Reset"));
 
// Si on approche de la limite, on patiente jusqu'au reset.
if (remaining <= 2) {
const waitMs = Math.max(0, reset * 1000 - Date.now());
await new Promise((r) => setTimeout(r, waitMs));
}

File d'attente côté client

Pour un traitement par lots (par exemple créer de nombreux transferts), n'envoyez pas toutes les requêtes en parallèle. Faites-les transiter par une file d'attente avec une concurrence bornée : vous gardez un débit régulier, sous le quota, et vous évitez les pics qui provoquent des refus en cascade.

async function runQueue(tasks, concurrency = 3) {
const queue = [...tasks];
const workers = Array.from({ length: concurrency }, async () => {
while (queue.length) {
const task = queue.shift();
await task();
}
});
await Promise.all(workers);
}
 
// Chaque task() effectue un appel API et applique le backoff ci-dessous.
await runQueue(transfers.map((t) => () => createWithRetry(t)), 3);

Backoff exponentiel avec jitter

Si un 429 survient malgré tout, réessayez en respectant d'abord Retry-After. En l'absence de cet en-tête, appliquez un backoff exponentiel (le délai double à chaque tentative) auquel vous ajoutez un jitter aléatoire. Le jitter évite que plusieurs clients, repartis en même temps, ne se resynchronisent et ne saturent l'API au même instant. Limitez le nombre de tentatives et plafonnez le délai maximal.

async function createWithRetry(payload, attempt = 0) {
const res = await fetch("https://api.coffrify.com/v1/transfers", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.COFFRIFY_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": payload.idempotencyKey,
},
body: JSON.stringify(payload.body),
});
 
if (res.status !== 429) return res;
if (attempt >= 5) throw new Error("rate_limited: tentatives epuisees");
 
// 1) Respecter Retry-After s'il est present (en secondes).
const retryAfter = res.headers.get("Retry-After");
let delayMs;
if (retryAfter) {
delayMs = Number(retryAfter) * 1000;
} else {
// 2) Sinon : backoff exponentiel (base 500 ms) + jitter <= 250 ms.
const base = Math.min(500 * 2 ** attempt, 30_000);
delayMs = base + Math.random() * 250;
}
 
await new Promise((r) => setTimeout(r, delayMs));
return createWithRetry(payload, attempt + 1);
}

À retenir

  • La limite est par espace de travail, sur une fenêtre glissante de 60 secondes, et distincte selon la classe d'endpoint (lecture, écriture, opérations lourdes).
  • Lisez X-RateLimit-Remaining et X-RateLimit-Reset en continu pour ralentir avant d'atteindre la limite.
  • Sur un 429, respectez d'abord Retry-After ; à défaut, appliquez un backoff exponentiel avec jitter.
  • Lissez les lots via une file d'attente à concurrence bornée plutôt que des rafales parallèles.
  • Au rejeu d'une écriture, réutilisez la même Idempotency-Key pour éviter tout doublon.
Cette page vous a-t-elle aidé ?
Anonyme, dédupliqué 24h par signature locale.