Rate Limits & Quotas

Emailyze enforces rate limits per API key to ensure fair usage. Limits are applied per plan.

Per-Plan Limits

| Plan | Requests/sec | Requests/day | Batch size | Downloads/hr | |------|-------------|--------------|-----------|--------------| | Free | 1 | 1,000 | 100 | 1 | | Starter | 10 | 10,000 | 1,000 | 6 | | Growth | 50 | 100,000 | 1,000 | 24 | | Enterprise | 100+ | Unlimited | 1,000 | Unlimited |

Enterprise limits are configurable per key. Contact sales for custom quotas.


Rate Limit Headers

Every response includes rate limit information in the headers:

| Header | Description | |--------|-------------| | X-RateLimit-Limit | Maximum requests allowed per second | | X-RateLimit-Remaining | Requests remaining in the current window | | Retry-After | Seconds to wait after a 429 response |


429 Response

When you exceed the per-second limit, the API returns:

HTTP/1.1 429 Too Many Requests
Retry-After: 1

{
  "error": "Request was throttled. Expected available in 1 second."
}

Handling Rate Limits

Simple retry with back-off (Python)

import time
import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.emailyze.dev/v1/check/"

def check_email(email: str) -> dict:
    for attempt in range(5):
        resp = requests.get(
            BASE_URL,
            headers={"X-API-Key": API_KEY},
            params={"email": email},
        )
        if resp.status_code == 429:
            wait = int(resp.headers.get("Retry-After", 2 ** attempt))
            time.sleep(wait)
            continue
        resp.raise_for_status()
        return resp.json()
    raise RuntimeError("Rate limit not cleared after 5 retries")

Batch to reduce API calls

Instead of checking emails one at a time, use the batch endpoint to check up to 1,000 emails per request. This is significantly more efficient:

import requests

def batch_check(emails: list[str], api_key: str) -> list[dict]:
    """Check up to 1000 emails in one request."""
    resp = requests.post(
        "https://api.emailyze.dev/v1/check/batch/",
        headers={"X-API-Key": api_key, "Content-Type": "application/json"},
        json={"emails": emails},
    )
    resp.raise_for_status()
    return resp.json()["results"]

def batch_check_large_list(emails: list[str], api_key: str) -> list[dict]:
    """Chunk a large list into batches of 1000."""
    results = []
    for i in range(0, len(emails), 1000):
        chunk = emails[i:i + 1000]
        results.extend(batch_check(chunk, api_key))
    return results

Single Check vs. Batch: Cost Comparison

| Approach | Emails | API calls | Requests/day used | |----------|--------|-----------|-------------------| | Single check loop | 1,000 | 1,000 | 1,000 (all quota) | | Batch (1,000/req) | 1,000 | 1 | 1 (1 quota) |

Always use batch for list validation. Use single check only for real-time validation (e.g., signup form check).


Quota Reset

Check your current usage in the [dashboard](/dashboard).


Upgrading Your Plan

If you regularly hit limits, [upgrade your plan](/pricing) to increase quotas. Enterprise plans support custom limits and dedicated capacity.