Help Center / api
Rate limits
Rate Limits
Our API uses rate limiting to ensure fair usage and stability. Learn how limits work and how to handle them.
Default Limits
| Plan | Requests/Minute | Requests/Day |
|---|---|---|
| Free | 60 | 1,000 |
| Starter | 300 | 10,000 |
| Business | 1,000 | 100,000 |
| Enterprise | Custom | Custom |
Rate Limit Headers
Every response includes rate limit information:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640000000
| Header | Description |
|---|---|
| X-RateLimit-Limit | Max requests per window |
| X-RateLimit-Remaining | Requests left in window |
| X-RateLimit-Reset | Unix timestamp when limit resets |
Endpoint-Specific Limits
Some endpoints have lower limits:
| Endpoint | Limit | Reason |
|---|---|---|
| Domain availability check | 30/min | External API calls |
| VPS create | 10/min | Resource intensive |
| Bulk operations | 5/min | Heavy processing |
Handling Rate Limits
Check Headers
const response = await fetch('https://api.osir.com/v1/domains')
const remaining = response.headers.get('X-RateLimit-Remaining')
if (remaining < 10) {
// Slow down requests
}
Handle 429 Errors
async function fetchWithRetry(url, options, retries = 3) {
const response = await fetch(url, options)
if (response.status === 429 && retries > 0) {
const retryAfter = response.headers.get('Retry-After') || 60
await sleep(retryAfter * 1000)
return fetchWithRetry(url, options, retries - 1)
}
return response
}
429 Response
When rate limited:
{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please retry after 60 seconds.",
"retry_after": 60
}
Best Practices
1. Implement Exponential Backoff
async function backoff(attempt) {
const delay = Math.min(1000 * Math.pow(2, attempt), 30000)
await sleep(delay)
}
2. Use Caching
// Cache responses that don't change often
const cache = new Map()
const CACHE_TTL = 60000 // 1 minute
async function getCachedDomains() {
if (cache.has('domains') && cache.get('domains').expires > Date.now()) {
return cache.get('domains').data
}
const data = await fetchDomains()
cache.set('domains', { data, expires: Date.now() + CACHE_TTL })
return data
}
3. Batch Requests
Instead of:
// Bad: 100 requests
for (const domain of domains) {
await checkDomain(domain)
}
Use:
// Good: 1 request
await checkDomains(domains) // Bulk endpoint
Increasing Limits
Need higher limits?
- Upgrade your plan
- Contact sales for enterprise pricing
- Apply for partner program