MoeMail

一次性邮箱检测

输入一个域名,看它是否属于一次性邮箱服务商。免费、免注册 —— 我们连自己的域名也一起标出来。

可以直接粘贴完整地址(name@example.com),只取域名部分,不做任何保存。

20 个常见域名的现成结论

表格里的结论由检测器所用的同一份数据生成,因此永远不可能和检测结果不一致。说明栏讲的是「这是什么服务」,结论栏讲的是「黑名单怎么说它」。

域名结论这是什么
gmail.com未被列为一次性邮箱Google 的个人邮箱服务。
outlook.com未被列为一次性邮箱微软的个人邮箱服务。
yahoo.com未被列为一次性邮箱雅虎邮箱。
icloud.com未被列为一次性邮箱苹果的邮箱服务,绑定 Apple 账号。
proton.me未被列为一次性邮箱注重隐私的邮箱服务商,有免费和付费方案。
qq.com未被列为一次性邮箱腾讯 QQ 邮箱,中国使用最广的邮箱之一。
163.com未被列为一次性邮箱网易邮箱,在中国使用广泛。
gmx.com未被列为一次性邮箱GMX,运营多年的免费邮箱服务商。
zoho.com未被列为一次性邮箱Zoho Mail,面向企业和自有域名。
simplelogin.io未被列为一次性邮箱别名转发服务,转发到你真实的收件箱。
duck.com未被列为一次性邮箱DuckDuckGo Email Protection,别名转发服务。
mailinator.com已被列为一次性邮箱公开的一次性收件箱,任何人无需注册即可打开。
yopmail.com已被列为一次性邮箱一次性收件箱服务商。
guerrillamail.com已被列为一次性邮箱一次性收件箱服务商,仍在运营的最老牌之一。
sharklasers.com已被列为一次性邮箱Guerrilla Mail 的备用域名之一。
10minutemail.com已被列为一次性邮箱短时间后自动过期的一次性收件箱。
temp-mail.org已被列为一次性邮箱一次性收件箱服务商,拥有多个地区域名。
1secmail.com已被列为一次性邮箱一次性收件箱服务商,同时提供公开 API。
trashmail.com已被列为一次性邮箱基于转发、带有效期的一次性地址。
moemail.app这是我们自己的域名就是本站。一次性邮箱服务商 —— 见下方说明。

为什么给两级,而不是「是」或「否」

大多数免费检测器只回答 true 或 false,这恰好隐藏了你真正需要知道的东西:这个答案有多确定。我们用两份审核标准不同的列表,并告诉你命中的是哪一份。

已列入

域名在严格审核的黑名单里,条目经过人工复核,误报很少。如果你要做自动拦截或标记,这一级才是可以直接行动的依据。

可能

只在覆盖更广的那份列表里,那份列表牺牲精确度换覆盖率。适合作为多个信号中的一个。只凭这一级就拦截,偶尔会误伤真实用户。

未列入

两份都没有。请注意它意味着什么、不意味着什么:没有任何黑名单是完整的,一个全新的一次性域名会在一段时间内一直通过这项检测。

黑名单命中是证据,不是铁证。任何有实际后果的判断,都该结合你自己掌握的信号 —— MX 记录、域名注册时间、账号行为,或者一封确认邮件。

别名服务和一次性邮箱不是一回事

SimpleLogin、DuckDuckGo Email Protection,以及 Gmail 自带的加号地址,给你的是一个转发到你长期收件箱的地址。地址是可丢弃的,后面的收件箱不是。用户照样会读信、照样会回复、日后照样能找回账号。

各家黑名单对它们的处理并不一致,所以你可能会看到某个别名域名被标记。这一点在你决定拦截之前值得知道:拦掉别名用户,赶走的是注重隐私但完全真实的客户。一次性收件箱几分钟后就被丢弃,而别名可能比它服务的那个账号活得更久。

数据本身就有自相矛盾的地方,值得一看。`addy.io` 被列入了,而同一家公司的旧域名 `anonaddy.com` 没有;`relay.firefox.com` 被列入了,但 Firefox Relay 实际发放的别名地址用的是 `mozmail.com`,而后者根本不在列表里。这两个标记都落在「可能」这一级、而不是「已列入」—— 这正是那一级存在的意义。

我们把自己的域名也标为一次性

MoeMail 提供的就是一次性邮箱服务。我们的域名做的事情和黑名单描述的完全一致,所以诚实的答案是:它们本就该在那些列表上 —— 这个检测器也照实这么说。

我们本可以悄悄把自己排除掉。没有这么做,理由很简单:任何人花五秒钟就能拿自家域名试出来,而一个被抓到偏袒自己的工具毫无价值。如果你在运营网站、想挡掉一次性注册,你应该能用这个工具把我们也挡在外面。

网站实际上是怎么识别一次性邮箱的

像这样的黑名单查询只是第一层。真实系统会叠加好几道检查:拿域名去比对公开和商业列表、解析 MX 记录看它到底收不收信、看域名注册了多久、以及观察账号注册之后的行为。

这也是为什么有些地址明明不在任何名单上却仍被拒绝,而有些一次性地址反而能顺利通过。想看更完整的版本,我们另外写过一篇。

为什么网站会拦截一次性邮箱

数据来自哪里

检测器查询两份由社区维护的开源黑名单。其中第二份是聚合器,所以下面把喂给它的仓库也一并署名,每一个都回链原始出处。我们从上游重新构建自己的副本,而不是手工改条目,所以你在这里看到的和维护者发布的一致。

这不是数据来源的完整清单。那个聚合器还会直接抓取一次性邮箱网站,那些没有仓库、也没有许可可以署名。它的源码是公开的,你可以自己查全量: generator.py

下载这份列表

合并去重后的列表以纯文本提供 —— 每行一个域名,无需密钥、无限流。可以直接用在你自己的项目里。

disposable-domains.txt

两份列表都不声称自己是最新或完整的,维护者自己也明说了这一点。域名会转手,服务会关停,新的每天都在出现。请把这里得到的结果当作社区维护的一份快照,而不是实时权威。

免费一次性邮箱检测 API

这个页面跑的就是这个查询,只是换成 JSON 接口。不需要 API key、不需要注册、没有配额要充值 —— 在注册表单里调、在 Worker 里调、在 shell 脚本里调都可以。它读的是上面写明的同两份列表,所以接口给出的答案和你在这个页面看到的完全一致。

试一下
curl "https://moemail.app/api/tools/v1/disposable-email/check?domain=mailinator.com"

端点

GEThttps://moemail.app/api/tools/v1/disposable-email/check?domain=…

查一个域名,或者一个完整邮箱地址 —— 地址前半段会被丢弃。返回归一化后域名的判定结果。

GEThttps://moemail.app/api/tools/v1/disposable-email/dataset

当前回答问题的是列表的哪一份快照:各层规模、构建时间,以及每个上游文件下载时的 SHA-256。如果你需要记录某个决定是由哪份数据做出的,在启动时调一次就够了。

响应字段

domainstring
判定所针对的归一化域名:已转小写、去掉地址前半段和结尾的点。请拿它来做比对,而不是拿你发过去的原始字符串。
disposableboolean
域名出现在任意一份列表里(包括我们自己的域名)时为 true。这是粗粒度的答案 —— 在用它拦注册之前,请先读下面那段警告。
verdict"high" | "medium" | "none" | "ours"
命中的是哪一层。high 是人工严格维护的那份列表。medium 只出现在那份广泛聚合的列表里。none 是两份都没有。ours 是 MoeMail 自己的收件域名 —— 它确实是一次性邮箱,而且没有任何第三方列表收录它。

不要只看 disposable 就拦人

我们知道的约 75,000 个域名里,medium 占了大约 66,000 个,而它来自一份没有人手工审核的广泛聚合列表。把它们全部拦掉,一定会误伤真实用户。如果一次误判会让你丢掉一个客户,那就只对 verdict === "high" 做拦截,把 medium 当成「要求二次验证」的理由,而不是「拒绝」的理由。disposable 这个字段的存在,是为了让原本对接布尔型接口的代码能直接换过来,不是因为布尔值是正确的决策边界。

错误

每个错误都同时带一个机器可读的 code 和一段给人看的 error。请对 code 做分支判断:文案随时可能改写,而这些 code 在 API 版本不变的前提下不会变。

400missing_domain没有传 domain 参数,或者传了空值。
400invalid_domain不是一个像样的域名。domain 被重复传入时、以及传入 Unicode 域名时也返回这个 —— Unicode 域名请先转成 punycode(xn--…)。
400input_too_long参数超过 320 个字符,而这已经是一个真实地址可能达到的最大长度。

限流、缓存与稳定性

每个 IP 每 10 秒 17 次,由 Cloudflare 在边缘执行,不是在这个 API 内部。没有任何 key 能提高这个上限,也没有付费档 —— 如果你需要的量超过它,请直接下载全量列表,在本地查。

超过之后,Cloudflare 会在边缘直接拦掉,请求根本到不了这个 API:429Retry-After: 10,以及一小段 text/plain 正文 —— 不是上面那个 JSON 结构。有两个后果需要提前考虑。拦截响应**不带** Access-Control-Allow-Origin,所以浏览器看到的是一个不透明的网络错误,而不是一个能读的 429;而且因为请求从未到达这里,也就没有 code 字段可以分支。请把「突发之后立刻失败的请求」当作被限流处理。

响应可缓存一天(s-maxage=86400),并带一个由上游文件哈希推导出来的 ETag,所以在数据没变的期间,条件请求几乎不花任何成本。列表是构建时编译进去的,因此在下一次部署之前答案不会改变。有一个后果值得知道:命中缓存的请求根本到不了限流器,所以这个限额是在塑造流量,而不是在做硬保证。

所有响应都带 Access-Control-Allow-Origin: *,因此浏览器可以直接从你的注册表单调用它,中间不需要任何代理。

v1 承诺的是形状,不是数据:字段不会被删除或改名,状态码的含义也不会变 —— 除非路径里出现新的版本段。至于判定结果本身,只要上游列表变了它就会变。

代码示例

每一段都是对 verdict 做判断,而不是对布尔值做判断,因为后者并不是你真正想做的那个决策。

cURL
curl "https://moemail.app/api/tools/v1/disposable-email/check?domain=mailinator.com"
# {"domain":"mailinator.com","disposable":true,"verdict":"high"}

curl "https://moemail.app/api/tools/v1/disposable-email/dataset"
# {"high":8742,"medium":66885,"total":75627,"builtAt":"…","status":"upstream",…}
Node.js
const ENDPOINT = "https://moemail.app/api/tools/v1/disposable-email/check"

async function verdictFor(domain) {
  const res = await fetch(`${ENDPOINT}?domain=${encodeURIComponent(domain)}`)
  const body = await res.json()
  if (!res.ok) throw new Error(body.code)   // branch on `code`, never on `error`
  return body.verdict
}

// "medium" means "only in the broad aggregator list" — a signal, not a verdict.
// Gate signups on the tier you are willing to defend to a real user.
const verdict = await verdictFor("mailinator.com")
const reject = verdict === "high" || verdict === "ours"
Python
import requests

ENDPOINT = "https://moemail.app/api/tools/v1/disposable-email/check"

def verdict_for(domain: str) -> str:
    r = requests.get(ENDPOINT, params={"domain": domain}, timeout=5)
    r.raise_for_status()
    return r.json()["verdict"]

# Note: use requests (or set an explicit User-Agent). Cloudflare's managed bot
# rules block the default "Python-urllib/3.x" agent with a 403 before the
# request ever reaches this API.

if verdict_for("mailinator.com") in ("high", "ours"):
    ...  # reject the signup
PHP
<?php
function verdict_for(string $domain): string {
    $url = 'https://moemail.app/api/tools/v1/disposable-email/check?domain=' . urlencode($domain);
    $ctx = stream_context_create(['http' => [
        'timeout' => 5,
        // Send a real User-Agent: identify your app, and stay clear of any
        // bot rule that keys on a default library agent.
        'header'  => "User-Agent: my-app/1.0\r\n",
    ]]);
    $body = json_decode(file_get_contents($url, false, $ctx), true);
    return $body['verdict'];
}

if (in_array(verdict_for('mailinator.com'), ['high', 'ours'], true)) {
    // reject the signup
}
Cloudflare Worker
export default {
  async fetch(request) {
    const email = new URL(request.url).searchParams.get("email") ?? ""
    const domain = email.split("@").pop()

    // Responses are cacheable (s-maxage=86400), so the Cache API turns a
    // repeated lookup into zero subrequests.
    const res = await fetch(
      `https://moemail.app/api/tools/v1/disposable-email/check?domain=${encodeURIComponent(domain)}`,
      { cf: { cacheTtl: 86400, cacheEverything: true } },
    )
    const { verdict } = await res.json()

    return Response.json({ allow: verdict !== "high" && verdict !== "ours" })
  },
}

这些列表由公开的上游数据编译而成,其中一部分的许可证要求署名信息随数据一起传递。因此每个响应都带一个 Link: rel="license" 头指回上面的署名清单,而完整的许可证文本随可下载数据集的文件头一起分发。

和其它免费查询 API 的对比

免费、不需要 key 的一次性域名查询接口有那么几个。下面是这一个和它们的区别 —— 也包括它做得更少的地方。

对比项MoeMailKickbox OpenDeBounce Freevalidator.pizza
不需要 API key 或注册
浏览器可直接调用(CORS)
置信度粒度两层,另加自有域名单一布尔单一布尔,但以字符串返回单一布尔
公开数据来源,并给出校验和
可下载全量列表
数据版本可查询
实时 MX / 域名年龄查询
明示的限流每 10 秒 17 次,有文档未标明未标明x-ratelimit-limit: 1

表中每一格都是在 2026-08-22 通过实际调用对方端点核实的,请求形状与上面那段 cURL 示例一致 —— 你可以自己复跑。这里没有一条取自厂商的宣传页面:曾有一条搜索结果声称 Kickbox 那个端点支持 CORS,实际上并不支持。

这四个都是黑名单查询。它们回答的只是「这个域名是否已知为一次性邮箱」,仅此而已;包括本接口在内,没有一个能告诉你某个邮箱是否真实存在。validator.pizza 走得最远,它会实时解析 MX 记录和域名年龄 —— 如果你要的是这个,就用它。

付费的邮箱验证服务 —— ZeroBounce、Kickbox 自家的验证 API、Bouncer —— 做的事比这里任何一个都多得多,包括邮箱是否真实存在、以及 catch-all 检测,并且按次收费。它们没有进这张表,因为拿一个免费黑名单自己挑的维度去衡量它们,是一张作弊的表。

常见问题

不是。Gmail 是 Google 的个人邮箱服务,不出现在任何一次性邮箱黑名单中。它上面的地址属于长期存在的账号,所以不是用完即丢的地址。Gmail 的加号地址(name+tag@gmail.com)看起来像一次性地址,但邮件仍然落进同一个长期收件箱。

不会。查询是在构建时编译进站点的列表上进行的,你输入的域名不会被写进我们任何日志或数据库。

可以。粘贴完整地址即可,只会取 @ 后面的部分。@ 前面的内容会被立即丢弃,不会离开这次请求。

黑名单总是滞后于现实。新的一次性域名不断上线,需要时间被上报和复核。「未列入」只说明目前还没有列表收录它,不代表这个域名可信。

如果你要清掉一次性注册,按「已列入」这一级拦是合适的。「可能」这一级要谨慎 —— 那份列表用精确度换了覆盖率,只凭它拦截偶尔会赶走真实客户。别名转发服务尤其需要小心。

我们会定期从上游重新构建。因为列表随站点一起发布、而不是请求时才去拉取,所以你查询的是我们最近一次部署时的版本。

有 —— 一个免费的 JSON 接口,不需要 key 也不需要注册:GET /api/tools/v1/disposable-email/check?domain=example.com。每个 IP 每 10 秒 17 次,响应带 Access-Control-Allow-Origin: *,所以可以直接从浏览器调。完整的接口说明,以及 Node、Python、PHP 和 Cloudflare Worker 的示例代码,都在上面的 API 章节里。

会一直免费,因为它几乎不花我们什么成本:列表是构建时编译进去的,响应在边缘缓存一天,所以大多数调用根本到不了服务器。没有 key 可买,也没有更高的档位。如果你需要的吞吐超过这个限额,请下载全量列表在本地查 —— 那份文件本来就是为此发布的,而且本地查询比任何网络调用都快。

你自己需要一个一次性邮箱?

MoeMail 可以创建临时邮箱,有效期由你决定 —— 10 分钟到 3 天 —— 到期连邮件一起删除。