備場景下的郵箱質(zhì)量檢測:接口參數(shù)、返回字段與工程接入要點(diǎn))
為什么要在業(yè)務(wù)里單獨(dú)做一次郵箱檢測用戶準(zhǔn)備、活動(dòng)報(bào)名、郵件訂閱這類流程中郵箱是賬號(hào)恢復(fù)、通知觸達(dá)和身份確認(rèn)的重要載體。一個(gè)看似合法的郵箱地址可能在格式上通過校驗(yàn)但實(shí)際域不存在 MX 記錄或者來自臨時(shí)郵箱域名。若不在入口處攔截后續(xù)會(huì)帶來大量無法送達(dá)的郵件、虛假賬號(hào)和風(fēng)控維護(hù)復(fù)雜度。郵箱地址檢測接口把多個(gè)維度的判斷合并成一次 HTTP 請求返回統(tǒng)一的評(píng)分和原因清單適合嵌入到準(zhǔn)備表單提交、批量名單清洗、KYC 輔助核驗(yàn)等環(huán)節(jié)。本文記錄這個(gè)接口的接入?yún)?shù)、返回結(jié)構(gòu)和工程落地時(shí)的注意事項(xiàng)供后端開發(fā)同學(xué)參考。接口能力邊界在寫代碼之前先明確這個(gè)接口能做什么、不能做什么避免誤用。一次請求完成 6 項(xiàng)檢測RFC 5322 格式校驗(yàn)判斷郵箱整體結(jié)構(gòu)是否符合規(guī)范。臨時(shí)/一次性郵箱檢測基于 72,345 條開源域名庫、3 個(gè)數(shù)據(jù)源合并去重后的結(jié)果進(jìn)行比對。MX 記錄驗(yàn)證通過 AliDNS DoH 查詢域名 MX 記錄不依賴服務(wù)器本地的 getmxrr 函數(shù)結(jié)果更穩(wěn)定。拼寫糾正對常見域名拼寫錯(cuò)誤給出建議例如gmial.com提示為gmail.com。服務(wù)商識(shí)別識(shí)別 QQ 郵箱、Gmail、網(wǎng)易、Outlook 等 40 主流郵箱服務(wù)商。綜合風(fēng)險(xiǎn)評(píng)分輸出 0-100 的風(fēng)險(xiǎn)分?jǐn)?shù)并附帶詳細(xì)原因清單。接口的 QPS 配額為 10 / s郵箱地址最長支持 254 字符RFC 上限。需要說明的是接口返回的是單一時(shí)間點(diǎn)的檢測結(jié)果不保證域名后續(xù)新增或刪除 MX 記錄會(huì)實(shí)時(shí)反映域名庫的更新頻率以文檔為準(zhǔn)。請求參數(shù)與鑒權(quán)Query 參數(shù)參數(shù)名類型必填說明emailstring是要檢測的郵箱地址最長 254 字符Header 參數(shù)參數(shù)名類型必填說明X-API-Keystring否API Key不傳時(shí)走匿名額度接口為 GET 請求地址為https://v1.apizero.cn/api/email-check。匿名額度不要求攜帶X-API-Key但在高并發(fā)或生產(chǎn)環(huán)境建議申請獨(dú)立的 API Key 使用具體申請方式以文檔為準(zhǔn)。curl 接入示例先通過 curl 驗(yàn)證接口連通性替換$APIZERO_API_KEY為你的實(shí)際 Key將email替換為目標(biāo)郵箱curl -sS \ -X GET \ -H X-API-Key: $APIZERO_API_KEY \ https://v1.apizero.cn/api/email-check?emailemail如果不帶 Key直接去掉 Header 即可curl -sS \ https://v1.apizero.cn/api/email-check?emailtestgmial.com上述命令返回 JSON 數(shù)組其中code為 0 時(shí)表示請求成功。注意響應(yīng)是一個(gè)數(shù)組結(jié)構(gòu)即使只返回一個(gè)元素也需要按數(shù)組解析。Python 代碼接入示例在實(shí)際業(yè)務(wù)中通常不在命令行里調(diào)用而是封裝成一個(gè)服務(wù)函數(shù)。以下是一個(gè)基于requests庫的接入示例import requests API_ENDPOINT https://v1.apizero.cn/api/email-check API_KEY your-api-key-here # 不傳則走匿名額度 def check_email(email: str, timeout: float 5.0) - dict: headers {} if API_KEY: headers[X-API-Key] API_KEY params {email: email} resp requests.get(API_ENDPOINT, paramsparams, headersheaders, timeouttimeout) resp.raise_for_status() # 接口返回 JSON 數(shù)組取第一個(gè)元素 body resp.json() if not isinstance(body, list) or len(body) 0: raise ValueError(unexpected response format) item body[0] if item.get(status) ! 200 or item.get(code) ! 0: raise RuntimeError(api error: {}.format(item)) return item[data] if __name__ __main__: result check_email(testgmial.com) print(risk_score:, result[risk_score]) print(risk_level:, result[risk_level]) print(reasons:) for reason in result[reasons]: print( -, reason)這段代碼做了三件必要的事設(shè)置超時(shí)、通過raise_for_status()暴露 HTTP 層錯(cuò)誤、校驗(yàn)響應(yīng)結(jié)構(gòu)后再取數(shù)據(jù)。生產(chǎn)環(huán)境中建議把API_KEY放到環(huán)境變量或密鑰管理服務(wù)中不要硬編碼在代碼倉庫里。返回字段解讀以素材中的testgmial.com為例成功響應(yīng)中data部分包含以下關(guān)鍵字段字段名類型說明emailstring原始郵箱地址inputstring用戶輸入值localstring郵箱地址的本地部分domainstring郵箱地址的域名部分valid_formatbool是否符合 RFC 5322 格式has_mxbool域名是否存在 MX 記錄mx_recordsarrayMX 記錄列表無記錄時(shí)為空數(shù)組is_disposablebool是否屬于臨時(shí)/一次性郵箱域名disposable_matchstring/null命中的臨時(shí)郵箱域名記錄來源providerstring/null識(shí)別的郵箱服務(wù)商名稱is_trustedbool是否屬于可信域名spelling_suggestionstring/null拼寫糾正建議risk_scoreint綜合風(fēng)險(xiǎn)評(píng)分0-100risk_levelstring風(fēng)險(xiǎn)等級(jí)例如invalidreasonsarray[string]風(fēng)險(xiǎn)原因清單data 外層還有code、msg、request_id三個(gè)字段。request_id在排查問題時(shí)非常有用建議在日志中記錄。在示例中risk_score為 5risk_level為invalid原因是域名無 MX 記錄、域名疑似拼寫錯(cuò)誤、本地部分含測試/系統(tǒng)類關(guān)鍵詞。這說明風(fēng)險(xiǎn)評(píng)分不是只看單一維度而是綜合了格式、域名可接收性、臨時(shí)郵箱庫和歷史經(jīng)驗(yàn)等多方面信息。幾個(gè)容易誤解的字段is_disposable: false并不代表郵箱一定安全還需要結(jié)合has_mx和risk_score綜合判斷。provider: null表示接口未能識(shí)別域名屬于哪家服務(wù)商可能是小眾域名或拼寫錯(cuò)誤域名。spelling_suggestion只在識(shí)別出疑似拼寫錯(cuò)誤時(shí)返回正常域名下為null。常見錯(cuò)誤與排查思路接入過程中遇到問題按照以下層次排查效率更高。1. HTTP 層異常400 Bad Requestemail參數(shù)缺失或超過 254 字符檢查 URL 編碼是否正確。401 UnauthorizedX-API-Key無效或已過期確認(rèn) Key 是否復(fù)制完整。429 Too Many Requests請求頻率超過 10 QPS 配額需要降速或聯(lián)系調(diào)整配額。2. 響應(yīng)結(jié)構(gòu)與狀態(tài)碼不一致接口返回 HTTP 200 時(shí)業(yè)務(wù)層面的code字段仍然可能表示失敗。不能只判斷 HTTP 狀態(tài)碼還要檢查code和status。建議在代碼中統(tǒng)一斷言item[status] 200 and item[code] 0。3. DNS 與 MX 查詢的時(shí)延波動(dòng)MX 記錄驗(yàn)證依賴 DNS 查詢極端情況下可能使整體接口耗時(shí)拉長。客戶端設(shè)置 5 秒超時(shí)是一個(gè)相對穩(wěn)妥的起點(diǎn)如果業(yè)務(wù)鏈路對耗時(shí)敏感可以加入緩存策略見下文。4. 郵箱地址的特殊字符部分郵箱地址包含、-、_等字符例如usertagexample.com。在拼接 URL 時(shí)務(wù)必使用params字典或urlencode處理不要手動(dòng)拼接字符串避免被解析為空格。工程化注意事項(xiàng)超時(shí)與重試網(wǎng)絡(luò)請求必須設(shè)置超時(shí)并按業(yè)務(wù)容忍度配置重試。建議采用指數(shù)退避策略第一次失敗后等待 1 秒、第二次 2 秒、第三次 4 秒最多重試 2 次。對于用戶準(zhǔn)備場景可以在前端先做一次本地格式校驗(yàn)再把完整檢測放到后端異步執(zhí)行避免同步阻塞表單提交。緩存設(shè)計(jì)同一郵箱在短時(shí)間內(nèi)被重復(fù)檢測的場景很常見??梢园脆]箱地址做本地緩存TTL 設(shè)為 10-30 分鐘降低接口調(diào)用量。需要注意MX 記錄和臨時(shí)郵箱域名庫會(huì)變化緩存時(shí)間不宜過長。如果業(yè)務(wù)對準(zhǔn)確性要求極高可以不緩存risk_score只緩存valid_format等幾乎不會(huì)變化的字段。批量場景的速率控制接口 QPS 為 10 / s批量清洗郵件列表時(shí)不能一次性并發(fā)發(fā)出大量請求。建議在本地做令牌桶限流控制請求速率在 8 QPS 左右留出余量。同時(shí)記錄每個(gè)request_id方便對賬。日志與監(jiān)控至少記錄以下信息調(diào)用時(shí)間、目標(biāo)郵箱、接口耗時(shí)HTTP 狀態(tài)碼、業(yè)務(wù) code、request_id返回的 risk_score 和 risk_level異常類型和重試次數(shù)這些數(shù)據(jù)接入監(jiān)控后可以及時(shí)發(fā)現(xiàn)接口調(diào)用異?;驑I(yè)務(wù)異常波動(dòng)例如某個(gè)時(shí)間段risk_score平均值突然升高可能意味著臨時(shí)郵箱域名庫更新或被攻擊者利用。不要做的事不要把接口返回的risk_score直接作為唯一決策依據(jù)建議結(jié)合業(yè)務(wù)規(guī)則如黑名單、準(zhǔn)備頻次綜合判斷。不要用reasons數(shù)組的中文文案直接展示給終端用戶這些內(nèi)容更適合在后臺(tái)風(fēng)控日志里查看。不要忽略匿名額度的限制生產(chǎn)環(huán)境請使用正式 API Key。小結(jié)郵箱地址檢測接口把格式校驗(yàn)、臨時(shí)郵箱識(shí)別、MX 驗(yàn)證、拼寫糾正、服務(wù)商識(shí)別和風(fēng)險(xiǎn)評(píng)分打包成一個(gè)簡單 GET 請求降低了風(fēng)控邏輯的重復(fù)開發(fā)維護(hù)復(fù)雜度。接入時(shí)重點(diǎn)關(guān)注響應(yīng)數(shù)組結(jié)構(gòu)、業(yè)務(wù)碼判斷、超時(shí)重試和速率限制即可穩(wěn)定嵌入到準(zhǔn)備、營銷、KYC 等場景中。參考文檔接口文檔https://apizero.cn/aidocs/email-check原始文檔https://apizero.cn/aidocs/email-check/raw.md