Rate limits

Requests are rate-limited per organization. Handle 429s by backing off and retrying.

To keep the platform responsive for everyone, requests are rate-limited per organization. Limits are generous for normal integration traffic; you'll typically only encounter them during a burst — a backfill, a batch of payouts, or a retry storm.

What counts

Rate limits are applied against your organization (identified by your API key), not against a single key or IP — so spreading calls across multiple keys does not raise your ceiling. If you have a genuine need for higher sustained throughput (for example, large scheduled payout batches), contact us and we can raise your organization's limit.

When you hit a limit

Over-limit requests are rejected with 429 Too Many Requests and a rate_limit_error:

json
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "Rate limit exceeded",
    "request_id": "req_5c1a9f2b"
  }
}

A 429 is safe to retry — no payout was created. When retrying a payout creation, reuse the same Idempotency-Key so the retry can never duplicate the payout.

Backing off

Retry with exponential backoff and jitter. If the response includes a Retry-After header, wait at least that long before retrying; otherwise start around one second and double each attempt, adding a little randomness so many clients don't retry in lockstep.

javascript
async function requestWithBackoff(doRequest, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const res = await doRequest();
    if (res.status !== 429) return res;

    const retryAfter = Number(res.headers.get("retry-after")); // seconds, if present
    const base = Number.isFinite(retryAfter) && retryAfter > 0
      ? retryAfter * 1000
      : 1000 * 2 ** attempt;
    const jitter = Math.random() * 250;
    await new Promise((r) => setTimeout(r, base + jitter));
  }
  throw new Error("rate limited: exhausted retries");
}

Staying under the limit

  • Prefer webhooks over polling. Don't poll a payout in a tight loop waiting for it to settle — subscribe to webhook events instead.
  • Page with large limits. Use limit=100 when listing so you make fewer calls.
  • Smooth out batches. When creating many payouts, add a small delay between requests or a concurrency cap rather than firing them all at once.
  • Cap your retries. A bounded retry with backoff recovers from a transient spike; an unbounded one turns a spike into a sustained overload.