Rate Limiting
The MailShield API implements rate limiting to ensure fair usage and maintain service quality for all users.
Rate Limits
| Limit Type | Rate | Description |
|---|---|---|
| General | 60 requests/minute | Per token, applies to all endpoints |
| DNS Checks | 5 checks/minute | Per 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| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the limit resets |
Handling Rate Limits
When you exceed the rate limit, you'll receive a 429 Too Many Requests response:
{
"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: 15Best Practices
Check headers proactively - Monitor
X-RateLimit-Remainingto avoid hitting limitsImplement exponential backoff - When rate limited, wait and retry with increasing delays
Cache responses - Store and reuse data that doesn't change frequently
Batch operations - Use pagination efficiently instead of making many small requests
Python Example with Retry
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
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:
# 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
Use webhooks (coming soon) instead of polling for changes
Fetch data in bulk - Get all domains in one request with pagination
Schedule checks wisely - Run daily checks during off-peak hours
Cache DNS check results - Results are stored in the database, use GET instead of POST to retrieve them