Skip to content

Rate limiting

Request quotas, X-RateLimit headers and recommended back-off strategy.

The API enforces quotas to ensure platform stability. When you exceed your limit, the API returns 429 Too Many Requests.

Quotas

Limits are per team, per rolling 60-second window, and depend on your subscription plan. Sandbox and live requests share the same per-team quota — there's no separate sandbox rate:

PlanLimit
Unauthenticated requests30 requests / minute (per IP)
Default / no plan feature set120 requests / minute
starter, growth, pro360 requests / minute
scale, business, enterprise720 requests / minute

On top of the per-team quota, the API also enforces a per-API-key ceiling (100 requests/minute), a per-IP ceiling (120 requests/minute), and tighter per-endpoint quotas on payments, transfers, refunds, and customers that scale with your plan tier. Any one of these limits can trigger a 429 independently of the others.

Adjust your quota

Need a higher limit? Contact support to adjust the cap based on your volume and plan.

Response headers

Each response exposes your current team-level usage:

Headers
X-RateLimit-Limit: 360
X-RateLimit-Remaining: 357
X-RateLimit-Reset: 1748083260
X-RateLimit-Limitintegeroptional
Total quota for your plan over the current 60-second window.
X-RateLimit-Remainingintegeroptional
Requests remaining before blocking.
X-RateLimit-Resetunix timestampoptional
Moment when the counter resets.

A 429 response additionally includes type (which limit tripped: team, api_key, ip, or endpoint), retry_after (seconds), retry_after_human, and a Retry-After header:

429 Too Many Requests
{
"code": 429,
"message": "Too many requests",
"type": "team",
"retry_after": 42,
"retry_after_human": "00:00:42"
}

Exponential back-off

async function withRetry(fn, max = 5) {
for (let attempt = 0; ; attempt++) {
  try {
    return await fn();
  } catch (err) {
    if (err.code !== 429 || attempt >= max) throw err;
    const wait = err.retryAfter ?? 2 ** attempt;
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
}
}

Smooth out your peaks

Batch jobs (reconciliation, exports, bulk transfers) should space out their calls and respect the Retry-After header rather than hammering the API in a tight loop.