指南 · Postmark API
产品团队应如何安全地接入 Postmark API?
通过经授权的服务端工作进程接入 Postmark API。验证发信域名或发件人签名,将每个环境和工作负载隔离到合适的 Postmark 服务器和消息流中,把服务器令牌保存在机密管理器中,并在调用 POST /email 之前持久化一个应用发送任务。只提交经过批准的字段,保留 Postmark 的 MessageID 和确切的 ErrorCode,并把 API 受理视为处理中的证据,而不是投递结果。保护投递和退信 Webhook 并对其去重,在每次发送前执行收件人抑制,核对结果不明确的超时,并在投入生产之前测试令牌轮换、部分失败、重试和导出。
在接入 Postmark 之前先定义应用边界
从一个经过授权的业务事件开始,例如收据、验证、用户请求的提醒或安全通知。持久化一个出站任务,包含稳定的事件键、租户、邮件类别、模板版本、经过批准的发件人和收件人、许可或必要性依据、当前的抑制判定以及初始状态。浏览器、移动端、模板和用户输入都不得选择 Postmark 服务器令牌、任意 From 身份、消息流、Webhook、不受限制的收件人或服务商元数据。把所有服务商调用都放在一个服务端适配层之后。根据产品的许可和信誉模型,将事务性流量与广播或营销流量分开。Postmark 的 API 负责传输邮件,它并不确立租户授权、收件人许可或业务层面的幂等性。每个内部任务只认领一次,记录每一次服务商尝试,并把服务商标识符作为与应用事件关联的证据保存,而不是把它们当作唯一的记录来源。
使用运维范围较窄的服务器令牌
Postmark 的邮件 API 文档说明使用 X-Postmark-Server-Token 请求头进行服务器级的 API 访问。将每个令牌保存在托管的机密服务中,只提供给需要该服务器和该环境的后台任务。绝不要把令牌放在客户端代码、源代码管理、URL、日志、分析数据、模板、截图、工单、提示词或测试数据中。将生产环境与开发环境以及不相关的产品分开,这样吊销或滥用的影响范围是有限的。演练令牌轮换:通过经过批准的管理流程创建替换令牌,更新后台任务,发送受控邮件,确认 API 和事件证据,然后吊销旧令牌。把意外的身份验证错误视为暂停条件,而不是快速重试凭据的理由。使用强身份验证和角色来限制控制台管理权限。服务器令牌授权的是针对其所属服务器的 Postmark API 操作;应用仍然必须对租户、发件人、收件人、模板和邮件类别进行授权。
验证确切的发件人身份
使用由组织控制的发件人签名或已验证域名,并确认每条消息流使用的确切 From 地址。在实际收到的原始样本上盘点可见的 From 域名、SMTP Return-Path、DKIM d= 域名和选择器、回复地址以及发送所用的消息流。在审查现有的 SPF、DKIM 和 DMARC 归属之后,只发布 Postmark 当前针对所选配置要求的 DNS 记录。保存原有的值和回滚说明。服务商的验证只是证明其配置检查通过了;它并不能证明每条应用路径都使用了该身份、DMARC 已对齐、收件人已许可或邮件能进入收件箱。在应用中保留租户级的发件人授权,并阻止跨租户的 From 值。测试子域名、回复、退信、低级别环境和模板路径。不要仅仅为了让控制台上的某个指示变绿,就放宽组织的 SPF 或 DMARC 策略。
构建一个明确的 POST email 请求
Postmark 的文档说明 POST /email 使用 JSON 字段来表示发件人、收件人、主题、纯文本或 HTML 正文、ReplyTo、邮件头、标签或元数据、消息流、附件以及追踪选项。只开放产品需要的字段。校验并规范化地址,限制收件人和附件的数量,拒绝邮件头注入,根据输出上下文对模板值进行转义,并从同一个经过批准的版本生成纯文本和 HTML。不要在标签、元数据、邮件头、主题或附件名称中放入机密信息或不必要的个人数据,因为它们可能出现在服务商的活动记录和事件中。从可信配置中选择 MessageStream,绝不要取自任意的请求输入。将服务商的负载放在一个适配层中,这样业务代码就不会依赖 Postmark 的每一个字段。当审计需要时,存储内容版本或保护隐私的哈希值,而不是记录完整的邮件正文。
对即时响应作严格的解读
Postmark 的单封邮件端点文档列出了 ErrorCode、Message、MessageID、SubmittedAt 以及收件人信息等响应字段。将确切的 HTTP 状态码和结构化的服务商响应与应用的发送尝试一起持久化保存。成功的响应和 MessageID 表明 Postmark 按其文档语义受理了该 API 请求;它们并不表明目标服务器已受理邮件,也不表明邮件已进入收件箱。在重试之前,先对校验、发件人签名、身份验证、负载格式错误、配额和策略错误进行分类。请求超时的结果是不明确的,因为 Postmark 可能已经受理了该操作,而客户端没有收到响应。请将该尝试标记为未知状态,使用安全的关联数据查询服务商的活动记录或之后的事件,并在重新发送之前应用针对该邮件类别的核对规则。绝不要承诺“恰好一次”的投递,也不要仅仅因为一次 HTTP 请求失败就创建一个新的逻辑事件。
依据服务商和传输层的证据设计重试
只对符合条件的网络故障、速率限制和服务商服务器错误进行重试,并使用指数退避、随机抖动、有限的尝试次数和队列时长上限。对于永久性的请求、发件人、收件人、令牌、模板和策略错误,应当修正问题,而不是重放请求。保持同一个应用事件键,并记录相互关联的各次尝试。在每次重试之前立即重新检查抑制列表和授权,因为在排队期间收件人或业务状态可能已经变化。按服务器、租户、消息流、发件域名和目标收件人群体限制并发和速率,这样一次故障不会占满全部容量。遇到事件已过期、发件人身份已被吊销、投诉、退订、永久性收件人失败或事故暂停时,停止重试。监控重试时长、未知结果、响应类别、令牌失败和服务商延迟。如果 Postmark 在受理后已经会在下游进行 SMTP 重试,就不要在这一传输行为之上再叠加一个激进的、会造成重复的应用重试循环。
保护投递和退信 Webhook
只配置应用需要的 Postmark Webhook 类型,并使用 HTTPS。应用当前文档中的 Webhook 安全控制,将端点限定于预期的服务器或消息流,强制执行请求大小和内容类型的限制,并且绝不能仅仅因为 JSON 能够解析就信任其中的消息标识符、收件人、标签、元数据或诊断信息。在返回成功之前,先持久化或入队经过身份验证(或以其他方式安全接收)的事件。在有稳定的服务商事件标识符时据此去重,否则使用保守的组合键,确保不会合并不同的收件人、事件类型或尝试。分别保存事件发生时间和处理时间。要预期会出现延迟、重试、重复和乱序投递。在更改状态之前,先将 MessageID 和可信的元数据关联到内部租户和任务。独立于 API 令牌轮换 Webhook 凭据或 URL,监控未授权请求和处理延迟,原始负载的保留时间以运维和政策需要为限。
为投递、退信和抑制状态建模
将 Postmark 的投递和退信证据映射到内部的收件人级模型,同时保留原始的服务商类型、MessageID、时间戳、状态或退信分类以及诊断信息。API 受理、Postmark 处理、目标服务器受理、之后的未送达、邮箱文件夹位置以及互动,都是不同的状态。delivered 事件通常反映的是服务商文档所述的对目标服务器的观察,而不能看到邮件最终所在的文件夹。暂时性失败可以采用有上限的传输层处理;经确认的永久性地址失败应当在收件人范围内创建抑制记录。投诉和退订必须在后续任务执行之前更新收件人安全状态。人工重新启用需要授权、原因和审计历史。在产品侧保存许可和抑制状态,这样迁移时不会丢失对收件人的保护。不要从打开或点击追踪推断邮件被人阅读,它们只是互动统计,可能会受到隐私保护技术的影响。
测试沙盒、生产环境和各种失败路径
使用 Postmark 文档中的测试或沙盒功能以及专门的受控收件人(而不是真实的客户地址)来测试确定性的失败。测试有效和无效的令牌、未授权的 From 身份、已批准和被阻止的收件人、纯文本和 HTML、Unicode、附件、元数据最小化、消息流、受理之前和之后的请求超时、限流响应、Webhook 身份验证、重复投递、事件乱序、退信分类、抑制列表以及令牌轮换。核实实际收到的原始邮件头、DKIM 和 DMARC 对齐、Reply-To、追踪配置以及 MessageID 关联。确认低级别环境无法触达生产环境的收件人。对抑制列表和运维证据进行导出和迁移测试。如果存在跨租户的发件人或事件访问、无法执行抑制、Webhook 接收规则不明确、日志中出现机密信息、重试没有上限,或无法安全地暂停受影响的服务器或消息流,则判定上线失败。
SendHQ 的适用场景
SendHQ 是一个限定工作区作用域、用于符合预期的产品通信的邮件 API。其公开文档涵盖已验证域名发送、入站邮件、托管模板、投递事件、抑制记录和 Web 控制台。
常见问题
通过 Postmark 发送单封邮件使用哪个端点?
Postmark 当前的邮件 API 文档说明,POST /email 使用服务器令牌和结构化的 JSON 邮件字段。只能从经授权的服务端代码中调用该端点。
Postmark 服务器令牌应该存放在哪里?
存放在托管的服务端机密系统中,限定较窄的环境和工作负载范围,访问有审计,轮换经过测试,并且绝不暴露给客户端。
Postmark API 返回成功响应是否证明已送达?
不能。它只记录了服务商按即时 API 约定受理了请求。目标服务器受理、退信、邮件所在位置和互动都需要之后的、有明确范围的证据。
Postmark 请求超时后应如何重试?
将可能已经提交之后发生的超时视为结果不明确。在重新发送之前,先核对服务商的活动记录或之后的事件,并使用同一个持久化的业务事件键。
可以假定 Postmark Webhook 是唯一且有序的吗?
不可以。设计时要考虑延迟、重试、重复和乱序到达。安全地接收、持久化保存事件、去重,并在收件人级别只做单调向前的状态转换。
Postmark 元数据中可以包含客户的机密信息吗?
不可以。请使用有长度限制、保护隐私的关联值。元数据、标签、邮件头、活动视图、事件、日志和导出数据都可能在运维过程中暴露这些字段。
delivered 事件是否能证明邮件进入了收件箱?
不能。它是有明确范围的服务商证据,通常表示目标服务器已受理。收件方的过滤、邮箱规则、最终所在的文件夹以及收件人的互动都是彼此独立的结果。
在哪里可以找到 SendHQ 的 API 文档?
有关其邮件 API、已验证域名发送、入站邮件、模板、投递事件和抑制记录,请参阅 SendHQ 的公开文档。
参考来源
- Postmark Email API — Postmark
- Postmark API 概览 — Postmark
- Postmark Webhook 概览 — Postmark
- Postmark 退信 Webhook — Postmark
- RFC 5321:简单邮件传输协议(SMTP) — RFC Editor