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 type | Limit |
|---|---|
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| Header | Meaning |
|---|---|
X-RateLimit-Limit | Your ceiling for the current window. |
X-RateLimit-Remaining | Requests left before you're limited. |
X-RateLimit-Reset | Unix 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
Error Handling
Parse Stile's error envelope, branch on stable error codes, and retry safely with exponential backoff and idempotency keys — in any language, no SDK required.
Testing & Sandbox
Build against sandbox mode, simulate verified sessions with skip_verification, test webhooks through a tunnel, and run the going-live checklist.