Rate limits
Plan-tier sliding-window limits with endpoint-specific sub-caps.
Brime enforces a per-key sliding-window rate limit. Limits are plan-dependent and apply uniformly across all endpoints, with two endpoints carving smaller sub-caps for additional protection.
There is no separate development / production key — your single Brime key inherits the limits of your account's plan tier. This is the OpenAI / Anthropic SDK pattern.
Global limits (all endpoints)
| Plan | Requests / minute | Notes |
|---|---|---|
| Free | 150 | No credit card |
| Pay as you go | 500 | |
| Pro | 1,500 |
Endpoint-specific sub-caps
A small subset of endpoints has its own bucket on top of the global budget — these are either expensive (research) or sensitive (admin):
| Endpoint | Cap (all paid tiers) | Window |
|---|---|---|
POST /v1/research | 30 | per minute |
GET /admin/usage | 15 | per 10 min |
Polling GET /v1/research/{job_id} and GET /v1/research/{job_id}/stream follow the global budget — only the create call is sub-capped.
Soft-overrun (20%)
Up to 20% above the hard cap is granted with X-RateLimit-Soft-Overrun: true so spiky-but-bursty traffic doesn't hard-fail on a one-off. You should still throttle on the next call — sustained traffic above the cap will eventually 429.
Headers on every response
X-RateLimit-Limit: 1500
X-RateLimit-Remaining: 1487
X-RateLimit-Reset: 1715000060Plus X-RateLimit-Soft-Overrun: true when applicable.
When you hit the limit
429 rate_limited:
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded for this API key",
"details": {
"retry_after_seconds": 12,
"limit": 1500,
"endpoint_class": "global",
"window_seconds": 60
}
}
}Retry-After: 12 header carries the seconds-to-wait. Back off exponentially.
import time
from brime import Brime, RateLimitError
client = Brime()
for attempt in range(5):
try:
result = client.search(query="...")
break
except RateLimitError:
wait = min(2 ** attempt, 30)
time.sleep(wait)import { Brime, RateLimitError } from "@brime-ai/brime";
const client = new Brime();
for (let attempt = 0; attempt < 5; attempt++) {
try {
const result = await client.search({ query: "..." });
break;
} catch (e) {
if (!(e instanceof RateLimitError)) throw e;
await new Promise(r => setTimeout(r, Math.min(2 ** attempt, 30) * 1000));
}
}How the limiter works
- Edge abuse protection — coarse IP-level filtering at the gateway.
- Per-key sliding window — fine-grained per-key budget per endpoint class, holding a 60-second (or 600-second for
admin_usage) rolling window of request timestamps.
Both layers fail closed. If the limiter is unreachable, requests fail open (we'd rather let one extra request through than reject legitimate traffic on infra blip).
Tenant isolation
Limits are per API key. Multiple keys minted on the same account each get their own bucket; they share the credit balance but not the rate-limit budget.
Going beyond Pro
Need higher limits than Pro? Email sales@brime.dev with your expected volume.