Skip to main content

Rate limits & usage headers

Each plan has two limits: a monthly quota of checks and a per-second limit.

PlanChecks per monthRequests per second
Free2,5002
Premium100,00020

Prices and plan details are in Plans & billing.

Monthly quota​

  • Every authenticated POST /v1/check with a valid body counts as one check, including addresses that turn out to be invalid (400).
  • Requests rejected with 401, 422 or 429, and checks that fail with 503, are not counted.
  • The quota resets on the 1st of every month at 00:00 UTC, whatever your plan and whenever you paid. Unused checks don't carry over. Annual Premium also gets 100,000 checks per month.
  • When the quota is used up, /v1/check answers 429 with type: "QuotaExceededError" until the reset. Retry-After is the number of seconds until the reset:
HTTP/1.1 429 Too Many Requests
Retry-After: 712800
X-RateLimit-Limit: 2500
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1793491200
X-Account-Status: active
X-Plan: free
{
"error": {
"type": "QuotaExceededError",
"message": "Monthly quota of 2,500 checks reached. It resets on the 1st of next month (UTC)."
}
}

Need more checks this month? Upgrade to Premium: your existing key gets the Premium quota immediately, and the checks you already made this month still count.

Per-second limit​

Requests above your plan's per-second limit get 429 with type: "RateLimitError" and Retry-After: 1:

{
"error": {
"type": "RateLimitError",
"message": "Too many requests per second for your plan. Slow down and retry."
}
}

In batch jobs, pace your calls (Free: one call every 500 ms or slower). In a signup flow, don't make the user wait for a retry: fail open instead.

Telling the two 429s apart​

Both limits answer 429. Branch on error.type, never on the message text:

error.typeMeaningRetry-AfterWhat to do
RateLimitErrorToo many requests per second1Slow down. Retrying after 1 second is fine
QuotaExceededErrorMonthly quota used upSeconds until the 1stDon't retry this month: fail open and upgrade

Never block a signup shows this check in Node.js and Python.

Usage headers​

HeaderExampleMeaning
X-RateLimit-Limit2500Checks per month in the plan that applies to this request
X-RateLimit-Remaining2391Checks left this month
X-RateLimit-Reset1793491200Unix time (seconds) of the next reset: the 1st of next month, 00:00 UTC
X-Account-Statusactiveactive, past_due or expired: see When Premium ends
X-PlanfreeThe plan whose limits apply to this request: free or premium
Retry-After1Only on 429: seconds to wait (1 for RateLimitError, seconds until the reset for QuotaExceededError)

When each header is sent:

  • X-Account-Status and X-Plan: on every request with a valid API key.
  • X-RateLimit-*: on every request that reaches the quota step, that is every 200, 400 for an invalid address, 503 and monthly-quota 429. They are not sent on 401, 422 or a per-second 429.

Watch X-RateLimit-Remaining and X-Account-Status in your monitoring to avoid surprises.