驗證原因碼
BillionVerify API 所有驗證結果 reason 欄位的完整參考手冊——每個原因碼的含義及處理建議。
每條驗證結果都包含一個 reason 欄位,用於說明該郵箱被判定為當前狀態的具體原因。參考本文件可構建精準的過濾規則、診斷異常結果,並優化發送策略。
原因碼的工作方式
reason 欄位與 status 欄位一同出現在所有驗證響應中:
{
"email": "user@example.com",
"status": "valid",
"reason": "smtp_deliverable"
}原因碼是穩定的字串識別符,可直接用於過濾規則或下游條件邏輯。
valid(有效)
status: "valid" 的郵箱經確認可投遞。
| 原因碼 | 說明 |
|---|---|
smtp_deliverable | SMTP RCPT 返回 250 OK——郵箱確認可投遞。當 Microsoft 365 DBEB 模式確認投遞,或 catch-all 域名同時確認了該具體地址時,也會使用此原因碼。 |
invalid(無效)
status: "invalid" 的郵箱應從名單中移除——無法投遞。
| 原因碼 | 說明 |
|---|---|
invalid_syntax | 郵箱地址語法解析失敗——本地部分、域名格式有誤或缺少 @。 |
no_mx_records | 域名沒有 MX 記錄(NXDOMAIN 或 MX 查詢返回空)。 |
spf_reject_all | 域名沒有 MX 記錄且 SPF 記錄包含 -all——域名明確拒絕所有入站郵件。 |
mailbox_not_found | SMTP 550/5xx 確認遠程服務器上該郵箱不存在。 |
host_not_found | MX 主機無響應——主機不可達或不存在。 |
unknown(未知)
status: "unknown" 的郵箱無法得出確定結論。部分原因是臨時性的(可重試),其餘則屬於結構性限制。
| 原因碼 | 可重試 | 說明 |
|---|---|---|
smtp_unverifiable | 否 | 該服務商屏蔽自動化 SMTP 驗證(Apple iCloud、Microsoft 消費者郵箱、Proton、Tuta),結果基於域名級啟發式判斷。 |
smtp_blocked | 否 | 遠程 SMTP 服務器明確屏蔽或封禁了連接。 |
smtp_eof_blocked | 是 | MX 服務器在發送 banner 之前關閉了連接——通常是 IP 速率限制或 fail2ban 規則觸發。 |
smtp_timeout | 是 | SMTP 操作超時(上下文截止時間或取消)。 |
smtp_connection_failed | 否 | 通用 SMTP 連接失敗——無更具體的分類命中。 |
smtp_rate_limited | 是 | 遠程 SMTP 服務器返回了速率限制響應(421、450、451 或消息限制超額)。 |
smtp_greylisted | 是 | 檢測到通用灰名單響應——延遲後可重試。 |
mimecast_greylist | 是 | Mimecast 專屬灰名單 / 451 臨時失敗。 |
proofpoint_ad_lookup | 是 | Proofpoint AD 異步查詢進行中(收件人驗證時返回 421 4.1.1 臨時失敗)。 |
policy_temp_fail | 是 | 遠程策略強制執行導致通用 4xx 臨時失敗。 |
google_rate_limit | 是 | Google MX 返回速率限制或臨時拒絕響應。 |
google_dmarc_misalignment | 否 | 域名 DMARC 配置不對齊——Google 按 DMARC 策略拒絕。 |
m365_ip_rep_block | 是 | Microsoft 365 因 IP 信譽問題拒絕連接(4.7.650 / 4.7.651 代碼)。 |
mailbox_full | 否 | 郵箱存在但已超出配額(SMTP 452 或郵箱已滿響應)。 |
mailbox_disabled | 否 | 郵箱存在但已被禁用或停用。 |
dns_timeout | 是 | DNS 或 MX 查詢超時——臨時解析器問題。 |
dns_lookup_error | 是 | DNS 查詢失敗,非 NXDOMAIN 錯誤(SERVFAIL、UDP 超時或解析器錯誤)。 |
yahoo_api_verified | 否 | Yahoo 注冊 API 確認該地址可投遞(批量路徑)。 |
yahoo_api_not_deliverable | 否 | Yahoo 注冊 API 確認該地址不可投遞(批量路徑)。 |
yahoo_api_error | 是 | Yahoo 注冊 API 調用失敗——通用錯誤。 |
yahoo_api_unavailable | 是 | Yahoo 注冊 API 不可用(批量級健康失敗)。 |
yahoo_api_eof | 是 | Yahoo API 返回提前 EOF——TCP/TLS 短暫中斷。 |
yahoo_api_unavailable_after_fallback | 是 | Yahoo API 失敗且 SMTP 兜底也失敗。 |
carrier_blocked | 否 | 日本運營商域名(docomo.ne.jp、au.com 等)——運營商策略屏蔽 SMTP。 |
internal_verifier_error | 是 | 未分類內部驗證器錯誤——臨時故障。 |
rate_limited | 是 | 批量處理中被速率限制(文件任務中 smtp_rate_limited 的別名)。 |
bucket_default_skip_smtp_unknown | 否 | 賬戶級驗證模式設置為跳過 SMTP——結果僅基於域名檢查。 |
risky(高風險)
status: "risky" 的郵箱存在中等程度的投遞風險。
| 原因碼 | 可重試 | 說明 |
|---|---|---|
mx_only_verification_semaphore_timeout | 是 | SMTP 並發信號量超時——MX 兜底驗證確認 MX 記錄有效,但無法單獨驗證該郵箱。 |
catchall(全收域)
status: "catchall" 的郵箱屬於接受所有地址的域名,無法確認單個地址是否可投遞。
| 原因碼 | 說明 |
|---|---|
catch_all_domain | 域名確認為 catch-all——隨機 RCPT 探測被郵件服務器接受。 |
catch_all_deliverable | Catch-all 域名,且該具體地址的 RCPT 也返回了 250 OK。 |
catch_all_inferred | 從緩存證據推斷出 catch-all 狀態(間接推斷,非實時探測)。 |
m365_internal_relay | Microsoft 365 域名配置為內部中繼——所有 RCPT 均被接受,但未單獨驗證。 |
gateway_accept_all | 安全網關(Mimecast、Proofpoint 等)處於全收模式。 |
forwarding_alias | 郵件轉發別名服務(SimpleLogin、Firefox Relay、Duck.com)。 |
region_consumer_accept_all | 已知接受所有入站郵件的區域消費者域名(如 naver.com、daum.net)——跳過 SMTP 探測。 |
bucket_default_skip_smtp_catchall | 賬戶級驗證模式設置為跳過 SMTP catch-all 檢測。 |
role(角色郵箱)
status: "role" 的郵箱屬於共享收件箱(如 info@、support@、noreply@)。這類地址通常可投遞,但互動率較低。
角色郵箱繼承其底層 SMTP 檢查的 reason——該狀態沒有專屬的原因碼。例如,通過 SMTP 驗證的角色郵箱會顯示 reason: "smtp_deliverable"。
disposable(一次性郵箱)
status: "disposable" 的郵箱屬於臨時郵箱服務。接受這類郵箱通常會導致低質量注冊。
| 原因碼 | 說明 |
|---|---|
disposable_domain | 域名在已知一次性/臨時郵箱服務商列表中。 |
按原因碼過濾的示例
結合 status 和 reason 可實現精準名單分類。例如,僅保留因臨時問題而 unknown 的郵箱:
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);
}