Skip to content
Dashboard

Rate Limits

Understand rate limit tiers, response headers, and strategies for staying within limits.

Limits by Plan

PlanPer-Minute LimitDaily Limit
Free60 requests/min1,000 requests/day
Starter200 requests/min10,000 requests/day
Pro1,000 requests/min50,000 requests/day
EnterpriseCustomCustom

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.

HeaderTypeDescription
X-RateLimit-LimitintegerMaximum requests per minute for your plan
X-RateLimit-RemainingintegerRequests remaining in the current minute window
X-RateLimit-Resetunix timestampWhen the current minute window resets (UTC epoch seconds)
X-RateLimit-Daily-LimitintegerMaximum requests per day for your plan
X-RateLimit-Daily-RemainingintegerRequests remaining today
X-Request-IdstringUnique 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_abc123def456

Handling 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-Remaining header and slow down when it's low
  • Implement exponential backoff for 429 responses using the Retry-After header
  • Use limit=100 in 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