Rate Limits
The API enforces rate limits to ensure fair usage and system stability. Limits are applied per API key.
Rate Limit Tiers
| Endpoint Type | Limit | Window |
|---|---|---|
| Read (GET requests) | 20 requests | Per minute |
| Write (POST/PATCH/DELETE requests) | 5 requests | Per minute |
Response Headers
Every API response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed in the current window |
X-RateLimit-Remaining |
Requests remaining in the current window |
X-RateLimit-Reset |
Unix timestamp when the window resets |
Example headers:
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 17
X-RateLimit-Reset: 1711843200
Handling Rate Limits
When you exceed the rate limit, the API returns HTTP 429 Too Many Requests:
{
"error": "Rate limit exceeded. Retry after 23 seconds.",
"retry_after": 23
}
The Retry-After header is also included in the response.
Best Practices
- Check headers proactively — monitor
X-RateLimit-Remainingto throttle before hitting limits - Implement exponential backoff — when you receive a 429, wait the
retry_afterduration before retrying - Cache responses — reduce redundant API calls by caching data locally
- Batch operations — use search endpoints with filters instead of fetching records one at a time
Example: Retry with Backoff
import requests
import time
def api_get(path):
response = requests.get(
f"https://tuberalytics.com/api/v1/{path}",
headers={"Authorization": "Bearer sk_live_your_api_key"}
)
if response.status_code == 429:
retry_after = response.json().get("retry_after", 60)
time.sleep(retry_after)
return api_get(path)
return response.json()
require "net/http"
require "json"
def api_get(path)
uri = URI("https://tuberalytics.com/api/v1/#{path}")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer sk_live_your_api_key"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
if response.code == "429"
retry_after = JSON.parse(response.body)["retry_after"] || 60
sleep(retry_after)
return api_get(path)
end
JSON.parse(response.body)
end
async function apiGet(path) {
const response = await fetch(`https://tuberalytics.com/api/v1/${path}`, {
headers: { "Authorization": "Bearer sk_live_your_api_key" }
});
if (response.status === 429) {
const { retry_after } = await response.json();
await new Promise(r => setTimeout(r, (retry_after || 60) * 1000));
return apiGet(path);
}
return response.json();
}