What Are Rate Limits?#
Rate limits control how many API requests you can make within a specific time window. They ensure fair use, prevent abuse, and maintain performance for all VerseDB API users.
Your account has a set number of API calls it can make per hour, which varies based on your user tier and the type of endpoint.
Rate Limits by User Tier#
| User Tier | Read Requests | Write Requests | Search Requests |
|---|---|---|---|
| Free | 300/hour | 150/hour | 60/hour |
| Pro | 1,000/hour | 500/hour | 120/hour |
PRO users also get access to relationship endpoints (series/issues, etc.), market data endpoints, and priority API access during high traffic.
Rate Limits by Request Type#
Read-Only Endpoints (GET requests)#
- Free users: 300/hour
- PRO users: 1,000/hour
Examples:
GET /api/publishers- Browse publishersGET /api/series/{id}- Get series detailsGET /api/issues- List issuesGET /api/characters/{id}- Get character infoGET /api/user/collections- View your collection
Read operations are less resource-intensive and don't modify data, hence the higher limits.
Write Operations (POST, PUT, DELETE, PATCH)#
- Free users: 150/hour
- PRO users: 500/hour
Examples:
POST /api/collections- Create collectionPOST /api/collections/{id}/items- Add to collectionDELETE /api/lists/{id}- Delete listPOST /api/pull-list/items- Add to pull listPOST /api/issues/{id}/read-status- Mark as read
Write operations modify data and require more validation and processing.
Search Operations#
- Free users: 60/hour
- PRO users: 120/hour
Examples:
GET /api/series?q=spider-man- Search seriesGET /api/characters?q=wolverine- Search charactersGET /api/creators?q=stan+lee- Search creators
Search queries are computationally expensive, especially with complex filters. The lower limits help maintain fast search performance for everyone.
Rate Limit Headers#
Every API response includes headers showing your current rate limit status:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 247
X-RateLimit-Reset: 1712869200
| Header | Description |
|---|---|
X-RateLimit-Limit |
Your maximum requests per hour for this endpoint type |
X-RateLimit-Remaining |
How many requests you have left in the current window |
X-RateLimit-Reset |
Unix timestamp when your limit resets (UTC) |
Reading Headers in JavaScript#
fetch('https://versedb.com/api/series/123', {
headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
})
.then(response => {
console.log('Limit:', response.headers.get('X-RateLimit-Limit'));
console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));
console.log('Resets at:', new Date(response.headers.get('X-RateLimit-Reset') * 1000));
return response.json();
});
Reading Headers in Python#
response = requests.get('https://versedb.com/api/series/123', headers=headers)
print(f"Limit: {response.headers['X-RateLimit-Limit']}")
print(f"Remaining: {response.headers['X-RateLimit-Remaining']}")
print(f"Resets: {response.headers['X-RateLimit-Reset']}")
What Happens When You Hit the Limit?#
If you exceed your rate limit, the API returns a 429 Too Many Requests error. Stop sending requests and wait for the reset time.
Response Body:
{
"error": "Too Many Requests",
"message": "API rate limit exceeded. Please try again later.",
"retry_after": 3600
}
Response Headers:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712869200
Retry-After: 3600
Best Practices for Managing Rate Limits#
1. Implement Exponential Backoff#
When you receive a 429 error, wait before retrying:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
2. Cache API Responses#
Store frequently accessed data locally:
- Cache series details for 24 hours
- Cache character info for 1 week
- Cache publisher data for 1 week
- Invalidate cache when data changes
3. Monitor Rate Limit Headers#
Check remaining requests before making calls:
if (parseInt(response.headers.get('X-RateLimit-Remaining')) < 10) {
console.warn('Approaching rate limit, slowing down requests');
await delay(1000);
}
4. Implement Request Queuing#
Spread requests over time instead of bursts:
const queue = new RequestQueue({ requestsPerSecond: 5 });
queue.add(() => fetch('/api/series/1'));
queue.add(() => fetch('/api/series/2'));
5. Optimize Queries#
- Use filters to reduce response size
- Request only fields you need
- Paginate results appropriately
- Combine related requests when possible
When to Upgrade to PRO#
Consider upgrading to PRO if you:
- Regularly hit the free tier limits
- Run automated scripts or bots
- Build production applications or integrations
- Need search-heavy operations
- Require relationship endpoints or market data
PRO tier benefits:
- 3.3x more read requests (1,000 vs 300)
- 3.3x more write operations (500 vs 150)
- 2x more search requests (120 vs 60)
- Access to PRO-only endpoints
- Priority support for API issues
Troubleshooting#
- Monitor rate limit headers
- Implement retry logic with backoff
- Cache frequently accessed data
- Spread requests over time
- Ignore rate limit headers
- Retry immediately after 429 errors
- Make requests in tight loops
- Skip caching for repeated requests
Calculating Time Until Reset#
const resetTime = parseInt(response.headers.get('X-RateLimit-Reset'));
const now = Math.floor(Date.now() / 1000);
const secondsUntilReset = resetTime - now;
console.log(`Rate limit resets in ${secondsUntilReset} seconds`);