Understanding API Rate Limits on VerseDB

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 publishers
  • GET /api/series/{id} - Get series details
  • GET /api/issues - List issues
  • GET /api/characters/{id} - Get character info
  • GET /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 collection
  • POST /api/collections/{id}/items - Add to collection
  • DELETE /api/lists/{id} - Delete list
  • POST /api/pull-list/items - Add to pull list
  • POST /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 series
  • GET /api/characters?q=wolverine - Search characters
  • GET /api/creators?q=stan+lee - Search creators

Note

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?#

Warning

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`);