Snooplytics API DocsHome

Rate Limits

Per-IP and per-endpoint request limits, the headers that expose them, and how to retry safely

3 min read

The API enforces two layers of rate limiting: a global per-IP budget that protects every route, and tighter windows on auth-critical endpoints like sign-in and two-factor verification. Both layers return 429 Too Many Requests with a stable error code and standard headers you can read on every response.

Global limit

A single IP may issue up to 500 requests per 15 minutes across all routes combined.

WindowMax requestsScope
15 minutes500Per IP, global

Per-endpoint auth limits

On top of the global budget, auth-critical endpoints have stricter windows to prevent credential stuffing and brute-force.

EndpointMax attemptsWindow
/api/auth/sign-in/email560 seconds
/api/auth/sign-up/email360 seconds
/api/auth/two-factor/*560 seconds
/api/auth/passkey/*1060 seconds
/api/auth/magic-link/*51 hour

Hitting any of these returns 429 with code RATE_LIMIT_ERROR. Wait for the window to expire — there is no retry-with-backoff strategy that beats the limit.

Response headers

Every response carries standard rate-limit headers.

HeaderDescription
RateLimit-LimitMaximum requests permitted in the current window
RateLimit-RemainingRequests remaining in the current window
RateLimit-ResetSeconds until the window resets
Retry-AfterPresent on 429 responses — seconds to wait before retrying
HTTP/1.1 200 OK
RateLimit-Limit: 500
RateLimit-Remaining: 482
RateLimit-Reset: 612
Content-Type: application/json; charset=UTF-8

{
"success": true,
"status": 200,
"code": "OK",
"message": "Projects fetched successfully",
"data": [...]
}

429 response

When you exceed the global limit, the API returns:

{
"success": false,
"status": 429,
"code": "RATE_LIMIT_ERROR",
"message": "Too many requests from this IP, please try again later.",
"meta": {
  "message": "Too many requests from this IP, please try again later."
}
}

The accompanying Retry-After header tells you how many seconds to wait. Honour it.

Retry with backoff

Use exponential backoff for 429 and transient 5xx responses. Read Retry-After first; fall back to 2^attempt seconds if the header is missing.

async function requestWithBackoff(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
  const res = await fetch(url, options);

  if (res.status !== 429 && res.status < 500) return res;
  if (attempt === maxRetries) return res;

  const retryAfter = Number(res.headers.get('Retry-After')) || Math.pow(2, attempt);
  await new Promise((r) => setTimeout(r, retryAfter * 1000));

}
}

Staying under the limit

  • Cache reads: Cache responses whose underlying data changes slowly (reference data, organization settings, user profile).
  • Batch writes when possible: Use endpoints that accept arrays rather than calling a single-resource endpoint in a loop.
  • Poll sparingly: For long-running work, poll every few seconds rather than every few milliseconds.
  • Use webhooks when available: Subscribing to provider webhooks is far cheaper than polling for state changes.
  • Observe your budget: Log RateLimit-Remaining on hot paths; a low floor is a signal to back off preemptively.

Need higher limits?

If your integration legitimately needs more headroom, contact your account manager with details about your use case and traffic pattern.

Best Practices

  • Read Retry-After before guessing a delay: The server knows exactly when the window resets. Your backoff math is an approximation.
  • Never retry sign-in or 2FA on 429: These use credential-safety limits. Retrying only extends the lockout.
  • Log code === 'RATE_LIMIT_ERROR' separately: Distinguish rate limits from generic 4xx so you can spot noisy callers.
  • Distribute traffic across IPs where legitimate: The limiter is per-IP. A single bot from one IP will hit the cap long before a fleet of workers across a NAT pool.
  • Do not rotate IPs to dodge the limit: That is treated as abuse and can get the account suspended.

Next Steps

  1. Handle errors: Review Error Handling for the full list of codes including RATE_LIMIT_ERROR.
  2. Scope down: Confirm your Scopes & Permissions before you ship anything that runs in a tight loop.
  3. Plan for SSO: If you administer an organization, set up Enterprise SSO.
  4. Explore endpoints: Jump into the API Reference.