Skip to main content

Rate Limits

Rate limits ensure fair usage and protect the API from abuse.

Rate Limit Tiers

PlanRequests/MonthRate Limit
Free20010/min
Developer50,000100/sec
Pro150,000500/sec
Enterprise500,000Custom

Domain Monitoring Limits

Domain monitoring subscriptions have separate limits based on your plan. Monitoring data is private to your organization and never shared.

PlanMonitored DomainsData RetentionScore Monitoring
Free1 domain--
Developer10 domains90 days-
Pro50 domains360 days5 score types
EnterpriseUnlimitedUnlimited5 score types

Each subscription monitors up to 9 service types: ping, DNS, WHOIS, certificates, and 5 health scores (email, security, trust, performance, SEO). Check intervals range from 1 minute (ping) to daily (scores).

Rate Limit Headers

Each API response includes headers to help you track your usage:

X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 99500
X-RateLimit-Reset: 1704067200
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current time window
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the rate limit window resets
Retry-AfterSeconds to wait before retrying (only included on 429 responses)

Handling Rate Limits

When you exceed your rate limit, the API returns a 429 Too Many Requests status code with a Retry-After header indicating when you can retry.

429 Response
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704067200

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please retry after 60 seconds.",
    "details": {
      "retry_after": 60
    }
  },
  "request_id": "req_abc123"
}

Reading Rate Limit Headers

Monitor the rate limit headers to track your usage and handle limits gracefully:

JavaScript
async function fetchWithRateLimit(url, options) {
  const response = await fetch(url, options);

  // Read rate limit headers
  const limit = response.headers.get('X-RateLimit-Limit');
  const remaining = response.headers.get('X-RateLimit-Remaining');
  const reset = response.headers.get('X-RateLimit-Reset');

  console.log(`Rate limit: ${remaining}/${limit} remaining`);

  // Handle 429 responses
  if (response.status === 429) {
    const retryAfter = parseInt(response.headers.get('Retry-After')) || 60;
    console.log(`Rate limited. Retrying in ${retryAfter} seconds...`);
    await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
    return fetchWithRateLimit(url, options);
  }

  return response;
}

Exponential Backoff

For production applications, implement exponential backoff with jitter to avoid the thundering herd problem:

JavaScript
async function fetchWithBackoff(url, options, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

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

    // Exponential backoff: 1s, 2s, 4s, 8s, 16s
    const baseDelay = Math.pow(2, attempt) * 1000;
    // Add jitter (0-1000ms) to prevent synchronized retries
    const jitter = Math.random() * 1000;
    const delay = baseDelay + jitter;

    console.log(`Attempt ${attempt + 1} failed. Retrying in ${delay}ms...`);
    await new Promise(resolve => setTimeout(resolve, delay));
  }

  throw new Error('Max retries exceeded');
}

Best Practices

  • Monitor remaining requests - Check X-RateLimit-Remaining and slow down before hitting limits
  • Cache responses - Store API responses locally to reduce unnecessary requests
  • Use composite endpoints - Use /v1/domain/report to combine multiple lookups into one request
  • Implement circuit breakers - Prevent cascading failures by temporarily stopping requests when errors spike
  • Log rate limit events - Track when limits are hit for debugging and capacity planning

Need Higher Limits?

Upgrade your plan for higher rate limits or contact us for enterprise pricing.