Published on June 14, 2026 • By Kaiju Team
Every email verification API enforces rate limits, and the way you handle them decides whether your integration runs smoothly at scale or grinds to a halt with cascading 429 Too Many Requests errors. Rate limiting protects the verification service from overload and keeps response times fast for everyone — but it also means your code has to be a good API citizen. This guide covers the rate-limiting patterns that actually matter when you consume an email verification API in 2026: how limits are expressed, how to read the headers, how to back off correctly, and how to batch so you never hit the ceiling in the first place.
Retry-After and X-RateLimit-* headers before retrying; never retry blindly.429 and 5xx responses.An email verification API does real network work on every call: DNS and MX lookups, an SMTP handshake to the recipient mail server, and cross-checks against disposable, role-based and spam-trap databases. That work has a cost, and the mail servers being probed (Gmail, Microsoft 365, Yahoo) themselves rate-limit incoming probes from any single source. So the provider caps your request rate for three reasons:
The practical takeaway: respecting the limit is not just politeness, it is how you keep your own verification accuracy high. KaijuVerifier's single-verify endpoint allows 20 requests per minute on the free tier and scales up with paid plans; batch verification is metered by rows, not by request count.
A well-behaved client never guesses the limit; it reads it off the response. Most modern APIs, including the KaijuVerifier REST API, return standard rate-limit headers on every call:
| Header | Meaning | What to do with it |
|---|---|---|
X-RateLimit-Limit | Max requests in the current window | Size your client-side throttle to stay under it |
X-RateLimit-Remaining | Requests left this window | Slow down as it approaches zero |
X-RateLimit-Reset | When the window resets (epoch or seconds) | Schedule the next burst after this time |
Retry-After | Seconds to wait (sent with 429) | Pause for at least this long before retrying |
When a 429 arrives, the single most important rule is: honor Retry-After. If the header says wait 30 seconds, retrying after 2 will just earn you another 429 and push your reset further out. If no Retry-After is present, fall back to exponential backoff (next section) and wait at least one full window before retrying.
The canonical recovery strategy for both 429 rate-limit and transient 5xx errors is exponential backoff with jitter. You increase the wait after each failed attempt — 1s, then 2s, then 4s, then 8s — and add a random offset so that many clients failing at once don't all retry in the same instant.
Without randomness, every client that got throttled at t=0 retries at exactly t=1s, t=2s, t=4s — synchronized bursts that re-trigger the limit and destabilize the service. Adding "full jitter" (a random wait between zero and the computed backoff) measurably reduces those collisions, a pattern documented in AWS's architecture guidance and now standard across the industry.
In pseudocode, a robust retry wrapper around an email verification API call looks like this:
attempt = 0
while attempt < MAX_RETRIES: # cap at 3–5
res = call_api(email)
if res.status == 200:
return res
if res.status == 429 and res.headers["Retry-After"]:
sleep(int(res.headers["Retry-After"]))
elif res.status in (429, 500, 502, 503):
backoff = min(MAX_BACKOFF, BASE * 2 ** attempt)
sleep(random(0, backoff)) # full jitter
else:
raise ApiError(res) # 4xx other than 429 = don't retry
attempt += 1
raise RateLimitExceeded(email) # surface it, never drop silently
Two rules embedded here are worth calling out: never retry a 4xx that is not a 429 (a bad request will fail forever), and always surface a final error after the retry cap instead of dropping the address quietly.
The most common cause of rate-limit pain is using the single-verify endpoint in a tight loop to clean a list. Don't. Every quality email verification API exposes a batch endpoint for exactly this case, and it is both faster and cheaper on your quota.
| Job | Wrong approach | Right approach |
|---|---|---|
| Verify one signup | — | POST /api/v1/verify-single (real-time) |
| Clean a 50k list | 50k single calls in a loop | POST /api/v1/verify-batch + poll for result |
| Continuous CRM sync | One call per record on save | Queue + batch every N minutes |
With verify-batch you submit the whole list in one request, poll an asynchronous job for completion, and download the results — the provider handles the internal pacing across its IP pools so you never see a 429 at all. See the API reference for the exact request shape, or skip the code entirely with the bulk cleaner CSV upload.
Reacting to 429 is recovery; staying under the limit is prevention, and prevention is faster. Implement a client-side rate limiter so you never send faster than your plan allows. The two algorithms worth knowing:
A simple token-bucket limiter set just below your plan ceiling (say 18/min against a 20/min limit) gives you headroom for retries without ever tripping the limit under normal load.
If your workflow verifies asynchronously, polling a job status endpoint in a loop is itself a rate-limit risk. Register an HMAC-signed webhook instead and let the verification service push the result to you when the batch finishes. This collapses dozens of polling calls into a single inbound notification. KaijuVerifier signs every webhook with HMAC so you can verify authenticity; see webhooks & real-time validation for the integration pattern.
The cheapest API call is the one you never make. Three habits keep you well under any rate limit and lower your bill at the same time:
Together these can cut real API traffic by a large fraction on a typical list, which means you stay under the rate limit naturally and your quota stretches further. Treat your monthly verification quota like a budget: dedupe and cache spend it efficiently; tight loops and re-verification waste it.
X-RateLimit-Remaining on every response and slow down as it nears zero.429, honor Retry-After; if absent, use exponential backoff with full jitter.verify-batch for any job over a few hundred addresses.429 with its endpoint and reset time so you can right-size your plan.It means you sent requests faster than your plan's rate limit allows. The response includes a Retry-After header telling you how many seconds to wait. Pause for at least that long, then retry — and add a client-side throttle so it doesn't happen again.
The free single-verify endpoint allows 20 requests per minute; paid plans raise that ceiling. Batch verification is metered by rows rather than request count, so large list cleanups should always use verify-batch rather than looping single calls. See pricing for per-plan limits.
No. Retry on 429 and transient 5xx (500, 502, 503) errors. Do not retry other 4xx codes — a 400 or 401 is a client-side problem (malformed request, bad API key) that will fail identically every time.
Yes, at any meaningful scale. Without jitter, all your throttled requests retry in lockstep and re-trigger the limit. Random jitter spreads retries out, which both recovers faster and reduces load on the verification service. It is the documented best practice.
Real-time single verify, async batch, and HMAC webhooks — with clear rate-limit headers on every call. Free for your first 500 verifications a month.
Get your API key free