← 返回博客

入站与出站 Email API(2026):用 Rovela 发送并接收邮件

用同一个 Rovela 账号,既通过 POST /emails 发送,又通过入站 MX 或 ingress、email.received webhook 以及 GET /inbound/:id 接收。

更新于 2026年11月10日
入站与出站 Email API(2026):用 Rovela 发送并接收邮件

一个 API 里同时做出站和入站

入站 + 出站 Email API 指同一套产品既能发送事务邮件,又能在你的域名上接收邮件,并把到达的消息交给应用。Rovela 的出站是POST /emails(以及 batch)。入站则是:「为已验证域名打开入站、发布 MX(或转发到 ingress URL)、订阅 email.received,再用 GET /inbound/:id 取正文。」

这是两者合在一起的产品图。入站逐步实现(含完整 handler)已经写在入站邮件 API 与 Webhook和接收邮件示例。出站邮件的投递事件见事务邮件 Webhook。给人用的收件箱见事务邮件 API + 托管邮箱。

可以从Email API产品页、快速开始、发送邮件 API和身份认证入手。 另见Webhooks和事件目录。

本系列相关产品指南:

出站:应用发出去的

出站就是事务邮件 API和HTTP 邮件 API里的那条路:sending_access Key、已验证的 from、HTML + text(或模板),以及凡会重试的请求都带 Idempotency-Key。200 表示入队。结果以 email.sent、email.delivered、email.bounced 等事件到来——或用 full_access 调用 GET /emails/:id。

若希望对话回到你接收邮件的同一域名,请设置 reply_to(或直接用一个别人能回复的地址发送)。

入站:域名收下的

根据入站示例(需要 full_access,以及已经验证过的域名):

curl -X POST https://api.rovela.dev/domains/<domain_id>/inbound   -H "Authorization: Bearer re_your_full_access_key"   -H "Content-Type: application/json"   -d '{"catch_all": false}'

响应里有 enabled、catch_all、ingress_url(请当作密钥;再次调用该端点会签发新的,旧的失效),以及要发布在域名上的 mx 记录。MX 生效之前,发件人仍会投递到旧的 MX。

  • 若省略 catch_all,或使用文档中的默认值 true,该域名下任何地址都会被接受。
  • catch_all: false 时,只接受你列出的地址(减少随机本地部分的垃圾邮件进入应用)。用 POST /domains/<domain_id>/inbound/recipients 添加。未列出的地址会在门口被拒绝。地址必须属于该域名,否则是 400。

订阅 email.received:

curl -X POST https://api.rovela.dev/webhooks   -H "Authorization: Bearer re_your_full_access_key"   -H "Content-Type: application/json"   -d '{"endpoint": "https://app.acme.com/webhooks/rovela", "events": ["email.received"]}'

事件携带信封和主题,不含正文:inbound_message_id、to、from、subject。用 full_access 调用 GET /inbound/:id 获取 text 和 html(任一都可能为 null)。入站 HTML 是陌生人写的——不要未经清洗就插入自己的页面;解析时优先用 text。from 只是发件人自称,不能当作身份证明。

用 GET /inbound?limit=50&offset=0 列出到达的邮件(最新在前,每页最多 100)。若你已经在跑邮件服务器,可以不改 MX,把原始邮件 POST 到 ingress_url(超过 2 MB 会 413),必须带 X-Envelope-To,并用稳定的 X-Provider-Event-Id,避免重试再次触发 email.received。

签名校验和重试规则与其他 webhook 相同(验证 Webhook 签名,Webhook 安全)。

把两边放进同一个应用

一个偏支持场景的闭环可以是:

  1. 应用用 POST /emails 发送「我们已收到订单」,并设置 reply_to: support@mail.acme.com(或 reply+ticket-381@ 这类地址)。
  2. 客户回复。入站接受(收件人名单或 catch-all)、存储,并触发 email.received。
  3. 你的 handler 校验签名,按事件 id 去重,拉取 GET /inbound/:id,把正文追加到工单。
  4. 坐席(或你的代码)再用同一套 API 发出下一封出站邮件,并使用新的幂等键。

不要用发信 Key 去拉入站正文——读取入站需要 full_access。把这把 Key 只放在 webhook Worker 上。

事件目录把 email.received 描述为「托管邮箱接受的入站消息」;入站示例同时展示了带收件人规则的域名级入站。按你实际采用的文档来配置。若只是需要人来读信,使用 webmail 即可(事务邮件 API + 托管邮箱)。

FAQ

这能替代入站 how-to 吗? 不能。写 handler 时请用入站邮件 API 与 Webhook。本文回答的是:为什么发送和接收会想用同一家供应商。

没有 webmail 也能用入站吗? 能——在域名上打开入站并消费 webhook。Webmail 只是给人用的可选项。

打开/点击事件适用于入站吗? 互动事件针对的是出站消息,并且只有在该发信域名开启跟踪时才会触发(事件)。

sending_access 和 full_access 怎么分工? 出站 POST /emails 和 batch:sending_access。打开入站、注册 webhook、GET /inbound/:id:full_access。

整个会话只用一个账号

用 Email API 发送,用入站 webhook 接收,必要时再在同一域名上给人提供 webmail。这就是入站 + 出站 Email API:一个供应商,两个方向,仍然只是 HTTP。