Error codes

HTTP status codes

Code Error Body Retry?
400 Malformed payload {"error":"bad_request"} No
401 Missing key {"error":"missing_api_key"} No
401 Invalid / revoked key {"error":"invalid_api_key"} No
402 Insufficient credits {"error":"insufficient_credits","balance":0,...} No (top up)
422 Missing email {"error":"email_required"} No
429 Rate limit exceeded {"error":"rate_limited"} + Retry-After Yes (wait)
5xx Internal error {"error":"internal_error"} Yes (expo backoff)

Business codes (the reason field in a 200 response)

A 200 OK response always includes a valid boolean and a reason qualifying the result:

reason Meaning
ok Valid email
syntax_invalid RFC 5322 format not respected
mx_missing Domain has no MX or A record
disposable Known disposable email provider
possible_typo Domain has no MX AND matches a popular-domain typo — see suggested_email
smtp_reject SMTP rejected the address (550 / 551 / 553)
smtp_catch_all The server accepts any RCPT TO — existence cannot be confirmed
smtp_anti_probe Provider blocks RCPT TO probes (Proton, Tutanota, etc.)
smtp_silent Server drops the connection silently (anti-enumeration strict)
smtp_unknown Unreachable server, timeout, or unknown response

Using confidence + reason in your logic

valid is a fast binary verdict, but sometimes you want more granularity:

Use case Recommended check
Anti-typo filtering (web form, fast) valid === true
Critical signup (SaaS, newsletter) valid === true && confidence === 'verified'
Lead scoring, list cleaning Inspect details.disposable, details.role_based, score
Accept unverifiable Accept reason === 'smtp_unknown' or smtp_anti_probe as "probably OK"

Why smtp_unknown / smtp_anti_probe happens

Some servers (Proton, Tutanota) systematically reject RCPT TO probes for privacy reasons. Others (strict cPanel, o2switch) drop the TCP connection silently. In these cases, we cannot confirm existence without actually sending a real email. If this is blocking for your business, fall back to MX + disposable + role_based checks and use a double opt-in strategy.

Retry strategy

  • 429 — use Retry-After, never retry without a delay.
  • 5xx — exponential backoff (1s, 2s, 4s, 8s max, 3 attempts).
  • 401, 402, 422 — fix client-side, don't retry.