Rate Limiting
Understand ProBeya API rate limits per plan, response headers, and strategies for handling throttling.
Overview
The ProBeya API enforces rate limits to ensure fair usage and platform stability. Limits are applied per API key using a sliding window algorithm backed by Redis. Every response includes rate limit headers so your application always knows its current standing.
Limits by Plan
| Plan | Requests per Minute | Burst Allowance | Concurrent Connections |
|---|---|---|---|
| Free | 100 | 20 | 5 |
| Pro | 1,000 | 100 | 25 |
| Enterprise | 10,000 | 500 | 100 |
Burst allowance allows short spikes above the per-minute rate. For example, a Pro plan key can send up to 100 requests in a 1-second burst before the sliding window kicks in.
Response Headers
Every API response includes three rate limit headers:
| Header | Type | Description |
|---|---|---|
X-RateLimit-Limit | number | Maximum requests allowed in the current window |
X-RateLimit-Remaining | number | Requests remaining before throttling begins |
X-RateLimit-Reset | number | Unix timestamp (seconds) when the window resets |
Example response headers:
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 947
X-RateLimit-Reset: 1711032060
When You Hit the Limit
When you exceed the rate limit, the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 12
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711032060
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"status": 429,
"message": "Rate limit exceeded. Retry after 12 seconds.",
"retryAfter": 12
}
}
Retry Strategy
Implement exponential backoff with jitter to avoid thundering-herd effects when multiple clients are throttled simultaneously:
Proactive Rate Limit Monitoring
Rather than waiting for a 429, monitor the X-RateLimit-Remaining header and slow down before hitting the limit:
async function fetchWithThrottle(url, options) {
const response = await fetch(url, options);
const remaining = parseInt(
response.headers.get("X-RateLimit-Remaining") || "999",
10
);
const resetAt = parseInt(
response.headers.get("X-RateLimit-Reset") || "0",
10
);
// If fewer than 10% of requests remain, throttle proactively
const limit = parseInt(
response.headers.get("X-RateLimit-Limit") || "1000",
10
);
if (remaining < limit * 0.1) {
const waitMs = Math.max(0, (resetAt * 1000) - Date.now());
console.warn(
`Only ${remaining} requests remaining. ` +
`Pausing ${Math.round(waitMs / 1000)}s until window resets.`
);
await new Promise((resolve) => setTimeout(resolve, waitMs));
}
return response;
}
Best Practices
Was this page helpful?