Skip to main content

Rate Limits

The Benchmark Email API enforces two levels of rate limiting to ensure fair usage and platform stability: an hourly rate limit and a monthly quota.

Hourly Rate Limit

Each account is limited to 3,600 requests per hour, which is approximately 1 request per second sustained. This limit applies across all API keys on the account — if you have multiple keys, they share the same hourly budget.

Rate Limit Response Headers

Every successful API key request includes headers showing your current rate limit status:
HeaderDescriptionExample
X-RateLimit-LimitMaximum requests allowed per hour3600
X-RateLimit-RemainingRequests remaining in the current hour3542
X-RateLimit-ResetUnix timestamp (seconds) when the hourly window resets1711828800
Example response headers:
HTTP/1.1 200 OK
X-RateLimit-Limit: 3600
X-RateLimit-Remaining: 3542
X-RateLimit-Reset: 1711828800
X-Monthly-Limit: 100000
X-Monthly-Remaining: 98750
Content-Type: application/json

Monthly Quota

Each account has a monthly API request quota that resets at the start of each billing period. The default quota is calculated as:
Monthly quota = Contact limit x 10
For example, an account with a 10,000 contact limit has a default monthly quota of 100,000 API requests. Some plans may have a custom quota configured by the account’s subscription.

Monthly Quota Response Headers

HeaderDescriptionExample
X-Monthly-LimitMaximum requests allowed in the current billing period100000
X-Monthly-RemainingRequests remaining in the current billing period98750

Exceeding Rate Limits

When you exceed either limit, the API returns a 429 Too Many Requests response.

Hourly Limit Exceeded

curl -H "X-API-Key: bme_abc123def456ghi789jkl012mno345pqr678stu90v" \
  https://api-us1-1.benchmarkemail.com/api/contact
Response (429 Too Many Requests):
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 3600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711828800
{
  "errors": [
    {
      "errorType": "TooManyRequestsError",
      "message": "Rate limit exceeded. Retry after 45 seconds."
    }
  ]
}
The Retry-After header indicates how many seconds to wait before retrying.

Monthly Quota Exceeded

HTTP/1.1 429 Too Many Requests
Retry-After: 86400
{
  "errors": [
    {
      "errorType": "TooManyRequestsError",
      "message": "Monthly API quota exceeded."
    }
  ]
}
When the monthly quota is exceeded, the Retry-After value indicates the number of seconds until the billing period resets.

Handling Rate Limits

Best Practices

  1. Monitor response headers. Check X-RateLimit-Remaining and X-Monthly-Remaining on each response to stay within limits.
  2. Use exponential backoff. When you receive a 429 response, wait for the duration specified in the Retry-After header. If you continue to receive 429 responses, increase the wait time exponentially:
    Wait time = min(Retry-After * 2^attempt, 300)
    
    Cap the maximum wait at 5 minutes (300 seconds).
  3. Spread requests evenly. Instead of bursting 3,600 requests in a few minutes, distribute them evenly across the hour (~1 per second).
  4. Cache responses. If you repeatedly fetch the same data, cache it locally instead of re-requesting it from the API.

Example: Retry Logic (pseudocode)

function makeRequest(url, headers):
    maxRetries = 3
    for attempt in 0..maxRetries:
        response = httpGet(url, headers)

        if response.status != 429:
            return response

        retryAfter = response.headers["Retry-After"] or 60
        waitTime = min(retryAfter * (2 ^ attempt), 300)
        sleep(waitTime)

    raise Error("Rate limit exceeded after retries")

Failed Authentication Protection

To protect against key probing and brute-force attacks, the API monitors failed authentication attempts by IP address. If an IP address sends too many requests with invalid API keys, it will be temporarily blocked. During a block, all API key requests from that IP address receive a 429 Too Many Requests response:
{
  "errors": [
    {
      "errorType": "TooManyRequestsError",
      "message": "Too many failed authentication attempts. Please try again later."
    }
  ]
}
The Retry-After header indicates when the block will expire. To avoid triggering this protection:
  • Verify your API key is correct before sending many requests.
  • Do not cycle through possible key values.
  • If you receive repeated 401 responses, stop and check your key rather than retrying immediately.

Summary

LimitThresholdScopeReset
Hourly rate limit3,600 requests/hourPer account (shared across all keys)Fixed 1-hour window
Monthly quotaContact limit x 10 (default)Per accountBilling period start
Failed auth blockingExcessive invalid keys per IPPer IP addressAutomatic (temporary block)

Next Steps