Skip to content

Rate Limiting

The MailShield API implements rate limiting to ensure fair usage and maintain service quality for all users.

Rate Limits

Limit TypeRateDescription
General60 requests/minutePer token, applies to all endpoints
DNS Checks5 checks/minutePer domain, for the /checks endpoint

Rate Limit Headers

Every API response includes rate limit information in the headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1706270400
HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the limit resets

Handling Rate Limits

When you exceed the rate limit, you'll receive a 429 Too Many Requests response:

json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Please slow down your requests."
  }
}

The response includes a Retry-After header indicating how many seconds to wait:

Retry-After: 15

Best Practices

  1. Check headers proactively - Monitor X-RateLimit-Remaining to avoid hitting limits

  2. Implement exponential backoff - When rate limited, wait and retry with increasing delays

  3. Cache responses - Store and reuse data that doesn't change frequently

  4. Batch operations - Use pagination efficiently instead of making many small requests

Python Example with Retry

python
import time
import requests

def api_request(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(response.headers.get('Retry-After', 60))
            print(f"Rate limited. Waiting {retry_after} seconds...")
            time.sleep(retry_after)
            continue

        return response

    raise Exception("Max retries exceeded")

Node.js Example with Retry

javascript
async function apiRequest(url, headers, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, { headers });

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
      console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }

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

DNS Check Rate Limits

The /domains/{id}/checks endpoint has a more restrictive rate limit (5 per minute per domain) because DNS checks are resource-intensive operations.

If you need to check multiple domains:

bash
# Good: Spread checks across domains
curl .../api/v1/domains/domain-1-id/checks
curl .../api/v1/domains/domain-2-id/checks
curl .../api/v1/domains/domain-3-id/checks

# Bad: Rapid checks on same domain
curl .../api/v1/domains/same-id/checks  # OK
curl .../api/v1/domains/same-id/checks  # OK
curl .../api/v1/domains/same-id/checks  # OK
curl .../api/v1/domains/same-id/checks  # OK
curl .../api/v1/domains/same-id/checks  # OK
curl .../api/v1/domains/same-id/checks  # Rate limited!

Tips for Staying Under Limits

  1. Use webhooks (coming soon) instead of polling for changes

  2. Fetch data in bulk - Get all domains in one request with pagination

  3. Schedule checks wisely - Run daily checks during off-peak hours

  4. Cache DNS check results - Results are stored in the database, use GET instead of POST to retrieve them

Monitor and secure your email domains.