api reference

Rate limits and quotas

Per-second, daily and in-flight limits for each tier, how batch and deep checks count, rate-limit headers, and how to handle 429 responses.

View as Markdown

The API is free, so limits keep it fast and fair for everyone. These are the defaults; we can change them, and we can raise them for you.

Tiers

Tier Who Per second Per day In flight
0 New accounts 5 100 10
1 Automatic after 7 clean days 10 1,000 10
2 On request 20 10,000 20
3 High volume, on request 200 100,000 50
  • “Clean” means no abuse flags, no limit-evasion and no terms violations.
  • Need tier 2 or 3? Need more limits? Contact us. Request it from the dashboard or by email. Tell us your use case and expected volume.
  • Limits are per account, shared by all its keys.
  • These are the defaults. Your dashboard’s Settings page shows the limits that apply to your account right now, and GET /v1/usage returns them.

What counts

Request Counts as
/v1/check 1
/v1/check with deep=true 5 (and at most 1,000 deep checks a day)
/v1/check/batch 1 per item (up to 100 items per request)
/v1/feedback 0 checks; separate limit of 50 a day per key
/v1/usage, /v1/health 0
Test addresses 0, never counted

Daily quotas reset at 00:00 UTC.

Headers

Every counted response carries rate-limit headers in both the standardized and the legacy format:

Header Meaning
RateLimit-Policy The limits that apply to you, in the format of the IETF HTTPAPI RateLimit header fields draft
RateLimit Current remaining allowance and time to reset, same draft
X-RateLimit-Limit Your daily quota
X-RateLimit-Remaining Checks left today
X-RateLimit-Reset When the daily quota resets
Retry-After On 429 (and 503): seconds to wait before retrying

Parse whichever your HTTP client already understands.

Errors

Code Status Meaning What to do
rate_limited 429 Too many requests per second, or too many in flight Wait Retry-After seconds, retry with backoff and jitter
quota_exceeded 429 Daily quota used up Stop until 00:00 UTC, or ask for a higher tier. Signups should fail open.
batch_too_large 413 More than 100 items Split the batch
payload_too_large 413 Body over 256 KB Send smaller batches

When you hit your daily quota we send one email that day with your usage and a link to request higher limits.

Handling 429 well

async function checkWithRetry(body, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    const res = await fetch('https://api.isbusinessemail.com/v1/check', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.IBE_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(body),
      signal: AbortSignal.timeout(2500),
    });
    if (res.status !== 429) return res;

    const problem = await res.json();
    if (problem.code === 'quota_exceeded') return res; // retrying won't help today
    const wait = Number(res.headers.get('Retry-After') ?? 1) * 1000;
    await new Promise((r) => setTimeout(r, wait + Math.random() * 250));
  }
  throw new Error('rate limited');
}

For a live signup form, don’t retry at all: fail open and re-check in the background.

Staying well under your limits

  • Cache on your side by domain. Verdicts for a domain rarely change within a day.
  • Check once per signup, on submit, not on every keystroke. For inline hints, debounce and use a publishable key, which has its own limits.
  • De-duplicate before batch jobs, and check domains instead of addresses when you only need the company.

Fair use

Limits exist to keep the service free. Creating multiple accounts to get around them, rotating IPs, or reselling access are against the Acceptable Use Policy and lead to suspension. If you need more, ask; we say yes to most reasonable requests.