Skip to main content

Use cases

API rate limiting (60/min prod, 1000/min sandbox, client backoff)

Per-tenant limits, quota headers, client exponential backoff

Scell.io applies a per-tenant rate limit: 60 req/min in production (sk_live_*), 1000 req/min in sandbox (sk_test_*) to ease load testing. Response headers `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (epoch) let the client adjust. On exceedance: HTTP 429 + `Retry-After` header (seconds). Recommended client pattern: exponential backoff with jitter (1s, 2s, 4s, 8s, 16s) over max 5 attempts. For needs > 60/min, contact support for a custom quota (enterprise and SSII).

Key facts

  • Production: 60 req/min/tenant
  • Sandbox: 1000 req/min/tenant
  • `X-RateLimit-*` headers on all responses
  • HTTP 429 + `Retry-After` on exceedance
  • Exponential backoff + jitter recommended client-side
  • Custom quota available for enterprises and SSIIs

Code example

async function callWithBackoff<T>(fn: () => Promise<T>, maxAttempts = 5): Promise<T> {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await fn();
    } catch (err: any) {
      if (err.status !== 429 || attempt === maxAttempts) throw err;
      const retryAfter = Number(err.headers?.['retry-after'] ?? 0);
      const backoff = retryAfter > 0 ? retryAfter * 1000 : Math.min(1000 * 2 ** (attempt - 1), 16_000);
      const jitter = Math.random() * 250;
      await new Promise((r) => setTimeout(r, backoff + jitter));
    }
  }
  throw new Error('unreachable');
}

const invoice = await callWithBackoff(() => scell.invoices.create(payload));

See also

Your cookie preferences

We use cookies to improve your experience. Essential cookies are always active. Cookie policy.