stile
Guides

Rate Limits

Per-key request limits, the rate-limit headers on every response, and how to back off cleanly.

Stile rate-limits API requests per key on a rolling per-minute window. The limits are generous for normal traffic and exist to bound the blast radius of a leaked key or a runaway retry loop.

Limits

Limits are per key, by key type:

Key typeLimit
Secret (stile_sk_)1,000 requests / min
Publishable (stile_pk_)100 requests / min

Publishable keys get a tighter budget because they're exposed in the browser. Limits are per key, not per organization — a separate key for each service gets its own budget.

Rate-limit headers

Every response includes the current state of your window, so you can throttle proactively instead of waiting for a 429:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997
X-RateLimit-Reset: 1741564920
HeaderMeaning
X-RateLimit-LimitYour ceiling for the current window.
X-RateLimit-RemainingRequests left before you're limited.
X-RateLimit-ResetUnix timestamp (seconds) when the window resets.

When you're limited

Exceeding the limit returns 429 Too Many Requests with code rate_limit_exceeded and a Retry-After header (seconds to wait). Honor it:

if (res.status === 429) {
  const retryAfter = parseInt(res.headers.get("Retry-After") || "1", 10);
  await new Promise((r) => setTimeout(r, retryAfter * 1000));
  // retry the request
}

The Node SDK retries for you

@stile/node automatically retries 429 and 5xx responses with exponential backoff (up to maxRetries, default 2). You only need to handle rate limits manually when calling the API directly.

A separate limit protects returning-user lookups

accept_existing is additionally rate-limited to 5 attempts per email per 15-minute window (429 accept_existing_rate_limited) to prevent credential enumeration. See Returning Users.

Next steps

On this page