Rate Limits
Understand rate limit tiers, response headers, and strategies for staying within limits.
Limits by Plan
| Plan | Per-Minute Limit | Daily Limit |
|---|---|---|
| Free | 60 requests/min | 1,000 requests/day |
| Starter | 200 requests/min | 10,000 requests/day |
| Pro | 1,000 requests/min | 50,000 requests/day |
| Enterprise | Custom | Custom |
These limits apply per API key. If you have multiple keys, each has its own limit.
Rate Limit Headers
Every API response includes rate limit headers so you can monitor your usage in real time.
| Header | Type | Description |
|---|---|---|
X-RateLimit-Limit | integer | Maximum requests per minute for your plan |
X-RateLimit-Remaining | integer | Requests remaining in the current minute window |
X-RateLimit-Reset | unix timestamp | When the current minute window resets (UTC epoch seconds) |
X-RateLimit-Daily-Limit | integer | Maximum requests per day for your plan |
X-RateLimit-Daily-Remaining | integer | Requests remaining today |
X-Request-Id | string | Unique request identifier for debugging |
Example Response Headers
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 958
X-RateLimit-Reset: 1738368060
X-RateLimit-Daily-Limit: 50000
X-RateLimit-Daily-Remaining: 49958
X-Request-Id: req_abc123def456Handling Rate Limit Errors
When you exceed the rate limit, the API returns a 429 status code with a Retry-After header.
429Response
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 45 seconds."
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-02-01T12:00:00Z",
"retry_after": 45
}
}async function rateLimitAwareRequest(url, options) {
const res = await fetch(url, options);
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get('Retry-After') || '60');
console.log(`Rate limited. Retrying in ${retryAfter} seconds...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return rateLimitAwareRequest(url, options); // Retry
}
return res;
}Monitoring Daily Quota
Use the usage endpoint to check your daily remaining quota.
const res = await fetch('https://brainpercent.app/api/v1/user/usage', {
headers: { 'Authorization': 'Bearer bp_your_key' },
});
const { data } = await res.json();
const { rate_limit } = data;
console.log(`Per-minute: ${rate_limit.remaining_per_minute}/${rate_limit.limit_per_minute}`);
console.log(`Daily: ${rate_limit.remaining_per_day}/${rate_limit.limit_per_day}`);Best Practices
- Monitor
X-RateLimit-Remainingheader and slow down when it's low - Implement exponential backoff for 429 responses using the
Retry-Afterheader - Use
limit=100in pagination to reduce total number of requests - Cache responses that don't change frequently (project lists, credit balances)
- Spread requests evenly over time rather than bursting
- Contact support for Enterprise-level custom limits if you need higher throughput