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@ 地址。
  • 绝不会真实投递。 沙盒收件人在消息到达投递基础设施之前就被拦截。不会传输任何内容,不涉及任何收件箱,你的发送信誉不受影响。
  • 请求验证仍然生效。 沙盒发送使用正常端点,因此 schema 检查、大小限制和请求头规则会照常拒绝无效请求。沙盒跳过的是交接之后的所有内容:渲染和该点之后的投递行为不会被验证。
  • 打开和点击不会被模拟。 魔术地址模拟的是传输结果,没有人会打开消息,因此 email.opened 和 email.clicked 只来自真实邮件。
  • 统计数据包含沙盒流量。 沙盒发送计入你工作区的汇总统计数据以及退信率和投诉率。大量沙盒退信会使你的仪表盘数据偏差,但不会影响你的信誉。

后续步骤

相关资源

继续查阅此主题的文档、指南和示例。资源为英文。

动手实践并获取实施简报