Rate Limits
Understanding and handling API rate limits
Overview
Rate limits protect the API from abuse and ensure fair usage for all developers. Limits are applied per API key and reset every minute.
Default Rate Limit
All accounts have a default rate limit of 60 requests per minute. Contact us if you need higher limits.
Rate Limit Headers
Every API response includes headers to help you track your rate limit status:
| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit |
Maximum requests allowed per minute | 60 |
X-RateLimit-Remaining |
Requests remaining in current window | 45 |
X-RateLimit-Reset |
Unix timestamp when the window resets | 1701432060 |
Example Response Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1701432060
Rate Limit Exceeded
When you exceed the rate limit, you'll receive a 429 Too Many Requests response:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please wait before making more requests.",
"retry_after": 30
}
}
The response includes additional headers:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1701432060
Retry-After: 30
Handling Rate Limits
Best Practices
- Monitor the
X-RateLimit-Remainingheader to know when you're approaching the limit - Implement exponential backoff when rate limited
- Use the
Retry-Afterheader to know how long to wait - Cache responses when possible to reduce API calls
- Batch operations where possible
Example Implementation (Python)
import requests
import time
def make_request_with_retry(url, headers, max_retries=3):
"""Make an API request with rate limit handling."""
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
# Check rate limit headers
remaining = int(response.headers.get('X-RateLimit-Remaining', 1))
if remaining == 0:
reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
sleep_time = max(reset_time - time.time(), 0)
print(f"Rate limit low, sleeping for {sleep_time}s")
time.sleep(sleep_time)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after}s before retry...")
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")
Example Implementation (JavaScript)
async function makeRequestWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
// Check rate limit headers
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '1');
if (remaining === 0) {
const resetTime = parseInt(response.headers.get('X-RateLimit-Reset') || '0');
const sleepTime = Math.max(resetTime - Date.now() / 1000, 0);
console.log(`Rate limit low, sleeping for ${sleepTime}s`);
await new Promise(r => setTimeout(r, sleepTime * 1000));
}
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
console.log(`Rate limited. Waiting ${retryAfter}s before retry...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
Tips for Staying Under Limits
Cache Responses
Cache GET requests locally to avoid redundant API calls. SpotCast data doesn't change once completed.
Use Webhooks
Instead of polling for status, use webhooks to be notified when SpotCasts complete.
Batch Requests
Create multiple SpotCasts in sequence rather than parallel to spread requests over time.
Monitor Usage
Track your API usage in the dashboard to understand your patterns and needs.
Higher Limits
If you need higher rate limits for your application, please contact us at support@sealegs.ai with:
- Your developer account email
- Your use case and expected request volume
- Why the default limits are insufficient
Enterprise Plans
Enterprise customers can get custom rate limits, dedicated support, and SLA guarantees. Contact us to learn more.