Guides
Rate Limits
API rate limiting tiers, headers, and how to handle 429 responses.
Overview
FeedHorizon uses a sliding-window rate limiter per API key. Each key has a maximum number of requests allowed within a rolling time window.
Rate limit tiers
| Tier | Requests | Window | Description |
|---|---|---|---|
| Default | 100 | 60 seconds | Applied to all API keys |
Rate limits are applied per API key, not per user. If you have multiple keys, each has its own independent limit.
Response headers
Every API response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Seconds until the window resets |
Example response headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 42Rate limit exceeded
When you exceed the limit, the API returns 429 Too Many Requests:
{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests"
}
}The response still includes rate limit headers so you know when to retry.
Handling rate limits
Best practices
- Check headers proactively — Monitor
X-RateLimit-Remainingand slow down before hitting 0 - Respect
X-RateLimit-Reset— Wait the indicated seconds before retrying - Use exponential backoff as a fallback
- Batch operations when possible — Create posts with all platforms in one request
Example implementation
async function apiCall(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(url, options);
if (res.status === 429) {
const resetIn = parseInt(
res.headers.get('X-RateLimit-Reset') || '60'
);
console.log(`Rate limited. Retrying in ${resetIn}s...`);
await new Promise(r => setTimeout(r, resetIn * 1000));
continue;
}
return res;
}
throw new Error('Max retries exceeded');
}import time
import requests
def api_call(url, headers, max_retries=3):
for attempt in range(max_retries):
res = requests.get(url, headers=headers)
if res.status_code == 429:
reset_in = int(res.headers.get("X-RateLimit-Reset", 60))
print(f"Rate limited. Retrying in {reset_in}s...")
time.sleep(reset_in)
continue
return res
raise Exception("Max retries exceeded")