Rate Limits & Errors
Understanding API rate limits and error handling.
Rate Limits
Each API key has three independent rate-limit counters. The defaults are conservative so unattended keys can't run away with usage; you can raise them per-key up to the maximums below.
| Window | Default | Max configurable |
|---|---|---|
| Per minute | 10 | 100 |
| Per hour | 100 | 1,000 |
| Per day | 1,000 | 10,000 |
Limits are configured per API key in your agent's settings.
Rate Limit Response
When any counter is exceeded, the API returns 429 Too Many Requests:
{
"error": "Rate limit exceeded",
"message": "Too many requests. Please try again later.",
"rateLimits": {
"requestsPerMinute": 10,
"requestsPerHour": 100,
"requestsPerDay": 1000
}
}
The rateLimits object contains the limits configured on the key that triggered the 429 — useful for surfacing to users or logs.
Handling Rate Limits
Exponential Backoff
async function retryWithBackoff(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.status === 429) {
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
Smooth out request bursts
If you have bursty traffic, prefer queuing client-side over retrying 429s. A small in-process queue that paces requests to a safe fraction of your per-minute limit is cheaper than backoff loops.
Error Codes
| Code | Status | Description | Retry? |
|---|---|---|---|
| 400 | Bad Request | Invalid request | No |
| 401 | Unauthorized | Invalid API key | No |
| 403 | Forbidden | Access denied | No |
| 404 | Not Found | Resource not found | No |
| 429 | Too Many Requests | Rate limit exceeded | Yes |
| 500 | Internal Server Error | Server error | Yes |
| 503 | Service Unavailable | Service down | Yes |