Rate limits
How rate limiting works and how to handle 429 responses.
Limits by plan
| Plan | Monthly checks | Requests/min |
|---|---|---|
| Free | 1,000 | 10 |
| Starter ($9/mo) | 10,000 | 60 |
| Pro ($29/mo) | 50,000 | 200 |
| Business ($79/mo) | 200,000 | 500 |
| Enterprise ($199/mo) | 500,000 | 1,000 |
Rate limit headers
Every API response includes these headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per minute for your plan |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
X-Monthly-Remaining | Checks remaining in your monthly quota |
Handling 429 responses
When you exceed the rate limit, the API returns 429 Too Many Requests. Use exponential backoff:
async function verifyWithRetry(email, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const res = await fetch("/api/v1/verify", { /* ... */ })
if (res.status !== 429 && res.status !== 500) return res.json()
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)))
}
throw new Error("Max retries reached")
}
Double the delay each time (1s, 2s, 4s) up to 30 seconds. Never retry in a tight loop.