BillionVerify LogoBillionVerify

Verification Reasons

Complete reference for all verification reason codes returned by BillionVerify API — what each reason means and how to act on it.

Every verification result includes a reason field that explains why the email received its status. Use this reference to build precise filtering logic, diagnose unexpected results, and tune your sending strategy.

How reasons work

The reason field appears in all verification responses alongside the status field:

{
  "email": "user@example.com",
  "status": "valid",
  "reason": "smtp_deliverable"
}

Reasons are stable string identifiers — you can use them directly in filtering rules or downstream conditional logic.

Valid

Emails with status: "valid" are confirmed deliverable.

ReasonDescription
smtp_deliverableSMTP RCPT returned 250 OK — mailbox confirmed deliverable. Also produced when Microsoft 365 DBEB mode confirms delivery or when a catch-all domain additionally confirms the specific address.

Invalid

Emails with status: "invalid" should be removed from your list — delivery is not possible.

ReasonDescription
invalid_syntaxEmail address fails syntax parsing — malformed local part, domain, or missing @.
no_mx_recordsDomain has no MX records (NXDOMAIN or empty MX lookup result).
spf_reject_allDomain has no MX records and an SPF record with -all — the domain explicitly rejects all inbound mail.
mailbox_not_foundSMTP 550/5xx confirmed the mailbox does not exist on the remote server.
host_not_foundThe MX hostname did not respond — host unreachable or non-existent.

Unknown

Emails with status: "unknown" could not be conclusively verified. Some of these are temporary (retryable); others represent structural limitations.

ReasonRetryableDescription
smtp_unverifiableNoThe provider blocks automated SMTP verification (Apple iCloud, Microsoft consumer, Proton, Tuta). Result is based on domain-level heuristics.
smtp_blockedNoThe remote SMTP server explicitly blocked or blacklisted the connection.
smtp_eof_blockedYesThe MX closed the connection before sending a banner — typically a per-IP rate limiter or fail2ban rule.
smtp_timeoutYesSMTP operation timed out (context deadline or cancellation).
smtp_connection_failedNoGeneric SMTP connection failure — no more specific class matched.
smtp_rate_limitedYesRemote SMTP server returned a rate-limit response (421, 450, 451, or messaging limit exceeded).
smtp_greylistedYesGeneric greylisting response detected — retry after a delay.
mimecast_greylistYesMimecast-specific greylist / 451 temporary failure.
proofpoint_ad_lookupYesProofpoint AD async lookup in progress (421 4.1.1 temp-fail during recipient validation).
policy_temp_failYesGeneric 4xx temporary failure from remote policy enforcement.
google_rate_limitYesGoogle MX returned a rate-limit or temporary rejection response.
google_dmarc_misalignmentNoDomain DMARC configuration is misaligned — Google rejects based on DMARC policy.
m365_ip_rep_blockYesMicrosoft 365 rejected the connection due to IP reputation (4.7.650 / 4.7.651 codes).
mailbox_fullNoMailbox exists but is over quota (SMTP 452 or full inbox response).
mailbox_disabledNoMailbox exists but has been disabled or deactivated.
dns_timeoutYesDNS or MX lookup timed out — transient resolver issue.
dns_lookup_errorYesDNS lookup failed with a non-NXDOMAIN error (SERVFAIL, UDP timeout, or resolver error).
yahoo_api_verifiedNoYahoo Registration API confirmed the address is deliverable (batch path).
yahoo_api_not_deliverableNoYahoo Registration API confirmed the address is not deliverable (batch path).
yahoo_api_errorYesYahoo Registration API call failed — general error.
yahoo_api_unavailableYesYahoo Registration API was unavailable (batch-level health failure).
yahoo_api_eofYesYahoo API returned early EOF — transient TCP/TLS drop.
yahoo_api_unavailable_after_fallbackYesYahoo API failed and the SMTP fallback also failed.
carrier_blockedNoJapanese carrier domain (docomo.ne.jp, au.com, etc.) — SMTP is blocked by carrier policy.
internal_verifier_errorYesUnclassified internal verifier error — transient failure.
rate_limitedYesEmail was rate-limited during batch processing (alias for smtp_rate_limited in file jobs).
bucket_default_skip_smtp_unknownNoAccount-level verification mode is set to skip SMTP — result is based on domain checks only.

Risky

Emails with status: "risky" have a moderate deliverability risk.

ReasonRetryableDescription
mx_only_verification_semaphore_timeoutYesSMTP concurrency semaphore timed out — MX-only fallback confirmed valid MX records but the mailbox could not be individually verified.

Catch-all

Emails with status: "catchall" belong to domains that accept mail for all addresses. Individual deliverability cannot be confirmed.

ReasonDescription
catch_all_domainDomain confirmed as catch-all — random RCPT probe accepted by the mail server.
catch_all_deliverableCatch-all domain, and the specific address also returned 250 OK on RCPT.
catch_all_inferredCatch-all status inferred from cached evidence (indirect, not a live probe).
m365_internal_relayMicrosoft 365 domain configured as internal relay — all RCPT accepted but not individually verified.
gateway_accept_allSecurity gateway (Mimecast, Proofpoint, etc.) is in accept-all mode.
forwarding_aliasEmail forwarding alias service (SimpleLogin, Firefox Relay, Duck.com).
region_consumer_accept_allRegional consumer domain (e.g. naver.com, daum.net) known to accept all inbound — SMTP probe is skipped.
bucket_default_skip_smtp_catchallAccount-level verification mode is set to skip SMTP catch-all detection.

Role

Emails with status: "role" belong to shared inboxes (e.g. info@, support@, noreply@). These addresses are typically deliverable but have low engagement.

Role addresses inherit the reason from their underlying SMTP check — no dedicated reason codes exist for this status. For example, a role address that passes SMTP will show reason: "smtp_deliverable".

Disposable

Emails with status: "disposable" belong to temporary email services. Accepting these usually leads to low-quality signups.

ReasonDescription
disposable_domainDomain is listed as a known disposable / temporary email provider.

Using reasons in filtering

You can combine status and reason for precise list segmentation. For example, to keep unknown emails that are only unknown due to temporary issues:

function isRetryableUnknown(result) {
  const retryableReasons = new Set([
    'smtp_eof_blocked', 'smtp_timeout', 'smtp_rate_limited',
    'smtp_greylisted', 'mimecast_greylist', 'proofpoint_ad_lookup',
    'policy_temp_fail', 'google_rate_limit', 'm365_ip_rep_block',
    'dns_timeout', 'dns_lookup_error', 'yahoo_api_error',
    'yahoo_api_unavailable', 'yahoo_api_eof',
    'yahoo_api_unavailable_after_fallback', 'internal_verifier_error',
    'rate_limited', 'mx_only_verification_semaphore_timeout',
  ]);
  return result.status === 'unknown' && retryableReasons.has(result.reason);
}

On this page