Skip to main content

Current Rate Limits

demeterrr enforces the following rate limits per organization:
Limit TypeRequestsTime Window
Per Hour1,00060 minutes
Per Minute10060 seconds
Rate limits apply per organization, not per API key. All API keys within your organization share the same rate limit pool.

Rate Limit Headers

Every API response includes these headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1644518400
HeaderDescription
X-RateLimit-LimitTotal requests allowed in the window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the limit resets

Rate Limit Exceeded

When you exceed the rate limit, you’ll receive: Status: 429 Too Many Requests
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please try again later.",
    "details": {
      "retryAfter": 60,
      "limit": 1000,
      "window": "1 hour"
    }
  }
}
The Retry-After header indicates how many seconds to wait before retrying.

Best Practices

1. Monitor Rate Limit Headers

Check X-RateLimit-Remaining before making large batches of requests:
async function makeRequest(url, options) {
  const response = await fetch(url, options);

  const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
  const reset = parseInt(response.headers.get('X-RateLimit-Reset'));

  if (remaining < 10) {
    const waitTime = reset - Math.floor(Date.now() / 1000);
    console.warn(`Rate limit low (${remaining}). Resets in ${waitTime}s`);
  }

  return response.json();
}

2. Implement Exponential Backoff

When you hit a rate limit, wait progressively longer between retries:
async function requestWithBackoff(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status !== 429) {
      return response.json();
    }

    // Exponential backoff: 1s, 2s, 4s
    const backoffTime = Math.pow(2, attempt) * 1000;
    await new Promise(resolve => setTimeout(resolve, backoffTime));
  }

  throw new Error('Rate limit exceeded after max retries');
}

3. Batch Operations

Instead of making many individual requests, use batch parameters where available:
// 100 API calls
for (const contact of contacts) {
  await createContact(contact);
}

4. Cache Responses

Cache data that doesn’t change frequently:
const cache = new Map();

async function getCachedContacts(maxAge = 5 * 60 * 1000) {
  const cached = cache.get('contacts');

  if (cached && Date.now() - cached.timestamp < maxAge) {
    return cached.data;
  }

  const response = await fetch('/api/v1/contacts', {
    headers: { 'X-API-Key': apiKey }
  });

  const data = await response.json();
  cache.set('contacts', { data, timestamp: Date.now() });

  return data;
}

5. Use Webhooks

Instead of polling for updates, use webhooks (coming soon) to receive real-time notifications.

Increasing Rate Limits

Need higher rate limits for your integration?

Contact Sales

Enterprise plans include higher rate limits. Contact our sales team to discuss your needs.

Rate Limit by Plan

PlanHourly LimitMinute Limit
Free50050
Starter1,000100
Pro5,000200
Business10,000500
EnterpriseCustomCustom
Rate limits shown are current targets. Actual limits may vary during beta.

Next Steps

Error Handling

Learn how to handle API errors

Quick Start

Make your first API call