Sign inGet Started

测试邮件投递(邮件沙盒)

邮件沙盒用于测试 Webhook 处理程序、屏蔽逻辑和投递结果,无需发送到真实收件箱。通过常规的 API 发送到 messagebird.dev 下的地址即可。地址的本地部分决定结果:bounce@messagebird.dev 会退信,delivered@messagebird.dev 会成功投递。

沙盒发送使用常规的受理、事件和 Webhook 路径。它返回与生产发送相同的 202 响应,并生成结构相同的逐收件人事件载荷。载荷中没有测试标记。邮件不会到达外部投递基础设施或真实收件箱。模拟的退信和投诉不会影响发件信誉,也不会写入屏蔽列表,因此这些地址可以重复使用。

沙盒无需任何设置:没有开关,没有测试模式,也不需要特殊的 API 密钥。它仅根据收件人地址触发,适用于常规发送端点(POST /v1/email/messages 和 POST /v1/email/batches)以及群发:受众中地址为沙盒地址的联系人只会被模拟,不会真正收到邮件,借此你可以在不给任何人发邮件的情况下演练一次营销活动。模拟收件人仍会计入你的发送额度,因此演练消耗的配额与真实发送相同。

特殊地址

所有地址都在 @messagebird.dev 域下。本地部分决定结果:

地址模拟结果Webhook 顺序说明
delivered@接收方邮件服务器接受该邮件email.accepted → email.processed → email.delivered正常成功路径
bounce@ / hardbounce@硬退信:SMTP 550,5.1.1 Unknown User,退信类别 10email.accepted → email.processed → email.bounced,附带 bounce_type: "hard"不写入屏蔽列表,因此该地址可重复使用
softbounce@软退信:SMTP 451,4.3.0 Temporary failure, please retry,类别 20email.accepted → email.processed → email.bounced,附带 bounce_type: "soft"无论真实还是模拟,软退信都不会触发屏蔽
deferred@ / delay@延迟投递:SMTP 451,4.2.1 Mailbox temporarily unavailable, will retry,类别 21email.accepted → email.processed → email.deferred模拟的延迟投递是最终状态:之后不会有重试,因此收件人保持为 deferred
complaint@ / spam@收件人将邮件举报为垃圾邮件(feedback_type: "abuse")email.accepted → email.processed → email.complained不写入屏蔽列表;可重复使用
suppressed@该收件人被视为已在你的屏蔽列表中email.accepted → email.rejected,附带 rejection_reason: "recipient_suppressed"与真实的被屏蔽收件人完全一样,在处理过程中提前终止:没有 email.processed,也没有投递事件
reject@邮件在任何投递尝试之前被拒绝email.accepted → email.rejected,附带 rejection_reason: "transmission_failed"之后不会产生 email.processed 或投递事件

以上序列是单次发送产生的 webhook。对于群发,请去掉开头的 email.accepted:群发收件人会被单独接受,但我们只记录该事件,不为其发送 webhook,因此每个序列从其后的事件开始,投递路径上是 email.processed,suppressed@ 和 reject@ 则是 email.rejected。之后的内容完全相同,完整规则见事件参考。

一次发送可以同时包含沙盒收件人和真实收件人。每个收件人有各自的生命周期:真实收件人正常投递,沙盒收件人则被模拟。

这些事件同样会出现在邮件日志中该邮件的时间线上,以及事件 API 中,因此无需 webhook 端点也能使用沙盒并读取结果。

地址规则

  • 仅根据本地部分识别,且仅限 messagebird.dev 域名。 bounce@yourdomain.com 是普通地址。
  • 只有特殊地址表中的本地部分才是特殊地址。 messagebird.dev 下的其他任何地址都是普通收件人。从共享的入门域名发送时,该地址必须属于已验证的工作区成员。
  • 匹配不区分大小写:Bounce@messagebird.dev 和 bounce@messagebird.dev 的行为完全相同。
  • 匹配前会去掉 +label 子地址:bounce+signup-flow@messagebird.dev 仍会退信。可用标签关联测试用例;包含标签的完整地址会出现在事件和 webhook 中,因此每次测试运行都能标记自己的收件人。

演练:端到端模拟一次退信

你不需要已验证的发信域名。按照发送第一封邮件中的说明,从 onboarding@messagebird.dev 发送即可。可识别的沙盒地址不受引导域名“仅限已验证成员”限制的约束,但仍计入其每日配额。

先确保你有一个已订阅邮件事件的 webhook 端点(参见 Webhooks),然后发送:

const msg = await bird.email.send({
  from: { email: "onboarding@messagebird.dev", name: "Bird" },
  to: ["bounce+signup-flow@messagebird.dev"],
  subject: "Sandbox bounce test",
  html: "<p>This message will hard-bounce.</p>",
  tags: [{ name: "flow", value: "signup" }],
  metadata: { test_run: "docs-capture-1" },
});
console.log(msg.id, msg.status); // "em_…", "accepted"

如果你的密钥以 bk_eu1_ 开头,请改为调用 https://eu1.platform.bird.com。

API 返回 202 Accepted 和一个 em_* 消息 ID,与生产环境发送没有任何区别。这正是目的所在:你测试的就是真实的代码路径。随后你的 webhook 端点依次收到 email.accepted、email.processed,最后收到 email.bounced。每个事件都会回传该次发送的 tags 和 metadata(发送时未提供则为 null),email.bounced 载荷包含完整的退信分类:

代码示例
{
  "type": "email.bounced",
  "timestamp": "2026-07-23T14:51:00.362Z",
  "data": {
    "email_id": "em_01ky7qanhrejer0bn34v38hrxh",
    "recipient_id": "er_01ky7qanhrejds4decpk83q5qq",
    "workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf",
    "recipient": "bounce+signup-flow@messagebird.dev",
    "recipient_role": "to",
    "bounce_type": "hard",
    "bounce_class": 10,
    "bounce_code": "550",
    "bounce_description": "5.1.1 Unknown User",
    "sending_ip": null,
    "tags": [{ "name": "flow", "value": "signup" }],
    "metadata": { "test_run": "docs-capture-1" },
    "broadcast_id": null
  }
}

各字段的含义见事件参考。载荷中没有任何模拟标记:事件类型和结构与真实硬退信完全相同。唯一能表明它是模拟事件的是收件人地址本身。因此,如果你的处理程序需要对测试流量做特殊处理,请根据 messagebird.dev 收件人域名来判断。

要验证系统绝不会向已被屏蔽的收件人发送邮件,请使用 suppressed@messagebird.dev 重复发送。断言你先收到 email.accepted,然后收到带有 rejection_reason: "recipient_suppressed" 的 email.rejected。你不应收到 email.processed 或任何投递事件。这与真实的被屏蔽收件人完全一致:消息先被接受,然后在处理阶段、实际发送之前被中止。

沙盒会做什么、不会做什么

  • 不写入屏蔽列表。 模拟的硬退信和投诉不会把收件人加入你的屏蔽列表,因此这些地址可以重复使用。你的 webhook 仍会触发(email.bounced、email.complained),所以你自己的屏蔽逻辑会得到完整测试。要测试“已被屏蔽”的拒绝路径,请使用专用的 suppressed@ 地址。
  • 绝不进行真实投递。 沙盒收件人会在消息到达投递基础设施之前被拦截。不会传输任何内容,不涉及任何收件箱,你的发信信誉也不受影响。
  • 请求校验照常进行。 沙盒发送使用常规端点,因此结构校验、大小上限和头部规则会照常拒绝无效请求。沙盒跳过的是移交之后的所有环节:此后的渲染和投递行为不会被测试。
  • 不模拟打开和点击。 魔法地址只模拟传输结果,没有人会打开这封邮件,因此 email.opened 和 email.clicked 只会来自真实邮件。
  • 统计数据包含沙盒流量。 沙盒发送会计入工作区的汇总统计数据以及退信率和投诉率。大量沙盒退信会使仪表板数据失真,但不会改变你的发件信誉。

后续步骤

继续查看此主题的文档、指南和示例。