识别一次性、拼写错误和无邮件服务器的注册邮箱
让您的注册表单对每个地址进行早期检查:语法、已知的一次性/临时域名、域名是否有邮件服务器、可能的拼写错误和角色地址——以附带原因的 accept、review 或 reject 结论返回。从表单自身的 JavaScript 调用 POST /v1/email/validate,或从后端或控制台批量检查列表。
请求与身份验证
在 X-Api-Key 请求头中使用来源锁定的公开可用密钥,向 POST /v1/email/validate 发送 JSON 请求体 { "email": "user@example.com" }——与 GET /v1/geo 相同的密钥类型和允许来源模型,因此可以在访问者输入或提交时直接从注册表单安全调用。在服务器端,您的私密密钥可解锁 POST /v1/email/batch(每次请求最多 100 个地址)、最多 100,000 个地址的异步列表任务(通过 API 或控制台的 Email lists 页面,CSV 输入、CSV 输出),以及 POST /v1/signup/check——它将邮箱检查与注册 IP 的网络指标组合为一个评分。
先看结论,再看原因
verdict 是最严重的结果:语法无效、域名不存在、域名无邮件服务器或为一次性域名时为 reject;疑似拼写错误、info@ 之类的角色地址、仅有隐式邮件服务器的域名,或 DNS 查询未完成时为 review;否则为 accept。reasons 列出命中的每个条件,方便表单显示具体提示——当 didYouMean 有值时,请提供纠正建议而不是报错。
何时调用
请在输入框失焦或提交时调用,而不是每次按键都调用——对尚未输入完整的地址逐字检查只会增加请求而没有有用信号,还可能在访问者输入时让错误提示闪烁。每次调用计为一次请求。
如果请求失败
采用失败放行策略:如果网络请求出错或超时,让注册继续进行,而不是因客户端故障阻止所有访问者。在服务器端,DNS 查询失败会以原因 dns_unavailable(结论 review)报告,绝不会作为错误或 reject。保留访问者已输入的内容,确保检查失败时不会让其丢失输入。
如何检测一次性域名
已知的一次性/临时域名合并自三个社区维护的开源列表(参见数据来源),每隔几小时刷新一次,并配有允许列表,确保上游的错误条目永远不会标记主流提供商。列表内域名的子域名同样匹配。尚未被任何列表收录的新一次性域名通常可通过其邮件服务器识别:一次性邮箱服务会将大量域名指向同样的少数几台邮件主机,若某域名的邮件服务器已知为列表内域名提供服务,就会以 disposableSource: mx_host 标记。使用新邮件服务器的非常新的提供商仍可能未被标记。
用量与配额
每个已检查的地址都计为一次请求,计入您套餐的共享每月上限——单个检查、批量中的每个地址、列表任务中的每个不同地址——与您的其他流量合并计算,并适用相同的每分钟速率限制。没有单独的邮箱套餐或价格。每分钟速率限制按 HTTP 调用次数计算,而不是按条目计算:一个最多包含 100 个 IP 或邮箱地址的批量请求只算一次请求,而其中每个条目仍会分别计入每月请求上限。
这无法验证什么
每项检查都在域名或地址层面进行。Watch-IP 从不连接收件人的邮件服务器,因此结果不能证明邮箱存在、邮件能够送达,或邮箱属于正在注册的人。accept 结论表示“未发现问题”,而不是已确认可用的地址——如需确认,请使用确认邮件。
响应字段
- syntaxValid
- 地址在语法上是否有效。
- isDisposable
- 域名是否直接、通过父域名或通过其邮件服务器匹配已知的一次性/临时提供商。当 syntaxValid 为 false 时始终为 false。
- disposableSource
- list、parent_domain 或 mx_host——isDisposable 为 true 的原因;否则为 null。
- mx
- 域名的邮件服务器状态(found、implicit、none、null_mx、no_domain 或 unknown)及其主 MX 主机。
- didYouMean
- 可能的拼写纠正,例如 gmial.com → gmail.com,或 null。
- isRoleAccount / isFreeProvider
- 角色地址(admin@、info@、noreply@…)和面向个人用户的邮箱提供商标记。免费邮箱提供商标记仅供参考。
- normalizedEmail / canonicalEmail
- 小写的地址,以及去除 +标签(和 Gmail 点号)后的同一地址,用于发现重复账户。
- verdict / reasons
- accept、review 或 reject,以及命中的每个原因代码——完整列表请参见参考文档。
根据结论采取行动
注册表单 JavaScript
async function checkEmail(email) {
const response = await fetch('https://api.watch-ip.com/v1/email/validate', {
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_PUBLISHABLE_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
if (!response.ok) return { state: 'unknown' }; // 失败放行——不要因网络错误阻止注册
const result = await response.json();
if (result.didYouMean) return { state: 'suggest', suggestion: result.didYouMean };
if (result.verdict === 'reject') return { state: 'reject', reasons: result.reasons };
return { state: 'ok' }; // accept 或 review:放行注册,并在后端进行标记
}针对每个原因显示不同的提示——invalid_syntax、disposable_domain 和 no_mail_server 需要访问者采取不同的纠正操作——并将 didYouMean 作为一键纠正提供。
常见问题
它会验证邮箱是否真实存在吗?
不会。它检查语法、域名的列表匹配情况和 DNS 邮件服务器记录,以及地址的格式。它从不连接邮件服务器,也不确认单个邮箱是否真实存在——因 no_mail_server 得出的 reject 针对的是整个域名。
accept 能证明邮箱可用吗?
不能。accept 表示所有检查都未发现问题,并不表示该地址一定能收到邮件,或属于正在注册的人。如有需要,请使用确认邮件。
用户能否绕过浏览器端验证?
可以。任何浏览器端检查(包括此检查)都可以通过禁用 JavaScript 或直接调用您的注册端点来绕过。请在后端执行任何重要决策——POST /v1/signup/check 正是为此设计的。
可以清理现有列表吗?
可以。在控制台的 Email lists 页面上传 CSV,或使用私密密钥向 POST /v1/email/jobs 提交最多 100,000 个地址,然后下载每行附有结论和原因的结果 CSV。重复地址只计费一次,上传内容和结果会在 7 天后删除。
请求是如何计数的?
每个已检查的地址计为一次请求,计入您套餐的共享每月上限。列表任务中的重复地址只计一次;一次注册检查计为一次请求。