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
PRO users get:
- Higher limits across all endpoint types
- Access to relationship endpoints (series/issues, etc.)
- Access to market data endpoints
- 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
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
- 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
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`);
- Free users: 300 read, 150 write, 60 search requests per hour
- PRO users: 1,000 read, 500 write, 120 search requests per hour
- Check `X-RateLimit-Remaining` header to monitor usage
- Implement exponential backoff for 429 errors
- Cache data and spread requests to stay within limits