Zum Inhalt springen

Rate limits

So that one integration does not slow down all the others, DebtFlow limits the number of requests per minute. Every response shows how much headroom is left.
CallerLimitCounted per
API key120 requests per minutekey
OAuth app120 requests per minuteconnection (app and user)
Unauthenticated (e.g. token endpoint)set per endpointIP address
All paths under /api/v1 combined1,000 requests per minuteIP address

The per-IP limit applies in addition and only absorbs load peaks: if several keys run from the same server, they share these 1,000 requests. Individual resource-intensive endpoints may have their own, lower limit; the headers of each response are authoritative. The IP limit also responds with 429, error: "rate_limited" and Retry-After.

Headers

HeaderMeaning
X-RateLimit-Limitrequests in the current time window
X-RateLimit-Remainingof which still remaining
Retry-Afteronly with 429: seconds until the next attempt
Response 429
HTTP/1.1 429 Too Many Requests
Retry-After: 17
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0

{ "error": "rate_limited", "message": "Too many requests. Please wait a moment.", "details": { "retryAfter": 17 } }

Reacting correctly

On 429, wait at least as long as Retry-After specifies, then retry. For POST requests, use the same Idempotency-Key.

async function debtflow(path, init = {}, attempt = 0) {
  const res = await fetch('https://www.debt-flow.io/api/v1' + path, {
    ...init,
    headers: { ...init.headers, Authorization: `Bearer ${process.env.DEBTFLOW_API_KEY}` },
  });
  if (res.status === 429 && attempt < 5) {
    const wait = Number(res.headers.get('Retry-After') ?? 1) * 1000;
    await new Promise((r) => setTimeout(r, wait));
    return debtflow(path, init, attempt + 1);
  }
  return res;
}
Fewer requests rather than more speed
Instead of polling lists regularly, get notified by webhook. For bulk imports, use the page size limit=100 and send requests one after another rather than in parallel.