Ware Send开发者文档
API v1Engine 1.3.3HTTP / SMTP

Developer Documentation

通过 HTTP API v1 或面向旧系统的 SMTP Submission 将应用接入 Ware Send 的公开参考。本页仅说明公开的集成契约,不公开许可、安装或私有基础设施内部细节。

快速开始

第一次发送

使用 Ware Send 部署时提供的 URL 和有效 Bearer credential。

Base URL

示例使用 https://mail.example.cn。请替换为您的安装实际配置的 FQDN。

cURL
curl -X POST "https://mail.seudominio.com.br/api/v1/send" \
  -H "Authorization: Bearer $WARESEND_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from_name": "Minha Empresa",
    "from_email": "notificacoes@seudominio.com.br",
    "to": ["cliente@example.com"],
    "subject": "Pedido confirmado",
    "html": "<h1>Pedido confirmado</h1>",
    "text": "Pedido confirmado"
  }'
202 Accepted
{
  "ok": true,
  "queued": true,
  "status": "accepted",
  "queue_id": "wsq_...",
  "message_id": "<...@mail.seudominio.com.br>",
  "accepted_at": "2026-08-24T03:00:00Z",
  "cost_class": "tiny",
  "version": "1.3.3"
}
accepted 表示什么?

Ware Send 已验证请求、将任务持久化到可靠队列,并承担后续处理责任。这并不代表收件服务器已经确认最终投递。

认证

Bearer token

受保护的 endpoint 要求在 HTTP Authorization 头中提供 credential。

HTTP Header
Authorization: Bearer <TOKEN>
仅在后端使用

不要在公开 JavaScript、分发应用或终端用户可访问的源代码中暴露 credential。

凭据交付

Bearer credential 会在集成部署时,通过安全渠道并以一次性查看方式交付给指定的技术负责人或开发人员。

需要新的 token?

请向 DB Ware 或 Ware Send 安装的授权负责人申请新的 credential。旧 token 无法恢复;完成切换后,应撤销旧 credential。

ENDPOINTS

快速参考

POST/api/v1/send

接收并持久化消息以进行异步处理。

Bearer
GET/api/v1/info

返回已安装 Engine 声明的能力与限制。

Bearer
GET/api/v1/messages/status?message_id=...

查询已接受消息的已知状态。

Bearer
GET/api/v1/engine/status

Engine、队列、资源和活动的运行 snapshot。

Bearer
GET/api/v1/engine/activity

当前活动和最近的 Engine 事件。

Bearer
GET/api/v1/engine/analytics

吞吐量、队列、资源、调度器、域和活动的时间序列与运行聚合数据。

Bearer
GET/health

服务基础健康状态。

公开
GET/ready

许可、队列、Postfix 和 DKIM 的运行就绪状态。

公开

发送消息

发送一条消息

向 /api/v1/send 发送 UTF-8 JSON。API 会验证、持久化并异步响应。

POST/api/v1/sendBearer

PAYLOAD

发送字段

以下字段构成当前 API v1 的公开契约。

字段类型必填说明
from_namestring发件人显示名称。
from_emailstring配置域名允许的发件地址。
tostring | array主收件人。可传入单个邮箱字符串,也可传入邮箱数组。
ccstring | array抄送收件人。支持字符串或数组。
bccstring | array密送收件人。支持字符串或数组,并且绝不会出现在可见邮件头中。
to_visibleboolean控制收件人可见性。可选,默认 false。false 时每个收件人相互隔离;只有 true 才允许共享 To/Cc。Bcc 永远不可见。
reply_tostring可选 Reply-To 地址。
subjectstring消息主题。
htmlstringHTML 正文。
textstring纯文本正文。
tenantstring应用、客户或集成上下文的逻辑标识。
campaign_idstring用于聚合活动运行数据的逻辑标识。
campaign_report_emailstring可选的活动完成报告收件邮箱。填写时必须提供 campaign_id;活动状态存在期间,该地址与活动绑定。
idempotency_keystring用于防止同一请求被意外重复提交的稳定键。
headersobject额外的非保留头。邮件结构头由 Engine 控制。
attachmentsarray普通或 inline/CID 附件。

* to、cc、bcc 中至少需要一个收件人,html、text 中至少需要一个正文。HTTP API 的 to/cc/bcc 支持字符串或数组,并且没有应用层的逻辑收件人数上限;实际仍受请求大小和主机资源约束。SMTP Submission 使用独立的收件人数限制,可通过 GET /api/v1/info 查询。

RECIPIENT PRIVACY

多收件人发送默认保护隐私

API 中的收件人列表只是 Engine 的路由输入。一个 payload 中包含多个地址,并不代表 Ware Send 可以把该列表暴露给收件人。

Default · to_visible=false
{
  "to": [
    "empresa-a@example.com",
    "empresa-b@example.com",
    "empresa-c@example.com"
  ],
  "subject": "Comunicado",
  "html": "<p>Olá</p>"
}
安全默认值:to_visible = false

省略 to_visible 或设为 false 时,Engine 会在内部执行 fan-out,并为每个收件人物化独立邮件。收件人看到的 To: 只包含自己的地址,其他 to、cc、bcc 地址不会暴露。

Explicit opt-in · to_visible=true
{
  "to": ["a@example.com", "b@example.com"],
  "cc": ["c@example.com"],
  "to_visible": true,
  "subject": "Reunião compartilhada",
  "text": "Mensagem"
}
仅在明确 opt-in 时共享可见

只有明确设置 to_visible:true,request 中的 To 和 Cc 列表才允许共同出现在可见邮件头中。仅当所有参与者都允许知道其他地址时使用此模式。

Bcc 永远不可见

Bcc 只作为 envelope 收件人存在。即使 to_visible=true,Engine 也不会输出可见的 Bcc 邮件头。

fan-out 由 Engine 负责

HTTP API 不设置应用层的逻辑收件人数上限。Engine 会在内部拆分并处理已接受的收件人集合。请求大小和主机资源仍是实际约束;SMTP Submission 有独立限制。

Job 与收件人是不同指标

包含大量地址的 request 仍然是一个逻辑 job,但包含多个收件人。收件人数量请看 accepted_recipients_total 和 postfix_queued_recipients_total;accepted_total 和 postfix_queued_total 统计 job。

附件

附件与 inline 图片

API v1 保持对 Base64 附件的兼容。请求接受后,Engine 会将内容持久化为 Blob 并异步处理发送。

普通附件
{
  "filename": "fatura.pdf",
  "content_type": "application/pdf",
  "content_base64": "JVBERi0xLjQK..."
}
Inline 图片 / CID
{
  "html": "<img src=\"cid:logo_empresa\" alt=\"Logo\">",
  "attachments": [{
    "filename": "logo.png",
    "content_type": "image/png",
    "content_base64": "iVBORw0KGgoAAA...",
    "cid": "logo_empresa",
    "inline": true
  }]
}
主要规则

每个附件都必须包含 filename 和 content_base64。inline 附件需要有效 cid 和 HTML 正文。同一消息中的重复 CID 会被拒绝。

可靠性

幂等性与活动

idempotency_key

为每个逻辑事件使用可预测的键。如果相同请求已被接受,Ware Send 可以返回之前的引用和 duplicate: true,而不会创建新的任务。

campaign_id

用于聚合大型活动的运行数据,并在 Engine snapshot 中观察已接受、已处理、retry 和失败情况。

campaign_report_email

将 campaign_report_email 与 campaign_id 关联,可自动接收活动完成摘要和详细 HTML 报告。

幂等性处理中

如果使用相同键的另一个请求仍在合并处理中,API 可能返回 409 Conflict。请等待后查询,或使用相同键重新提交。

活动完成

活动完成报告

同时提供 campaign_report_email 与 campaign_id 后,Ware Send 会跟踪活动直到 Engine 终态,并发送样式化 HTML 摘要与一个自包含的详细 HTML 附件。

POST /api/v1/send
{
  "tenant": "erp-production",
  "campaign_id": "invoice-batch-2026-08-26",
  "campaign_report_email": "mail-ops@example.com",
  "from_email": "billing@example.com",
  "to": ["customer@example.net"],
  "subject": "Invoice",
  "text": "Your invoice is attached."
}
202 Accepted
{
  "ok": true,
  "status": "accepted",
  "message_id": "wsm_...",
  "campaign_report_requested": true,
  "version": "1.3.3"
}
字段规则

该字段可选;填写后 campaign_id 必填。同一 campaign_id 在状态存在期间不能静默更换报告地址;每个逻辑活动应使用唯一 ID。

报告何时发出

所有已接受 job 均为 POSTFIX_QUEUED 或 Engine 终态失败,且在配置的静默期(默认 60 秒)内没有新 job 被接受后发出。后续 job 可产生新 revision。

它证明什么

证明 Ware Send 完成处理并将消息交给本地 Postfix,能够取得时包含 Queue-ID。它不是 inbox 回执;远端 delivery/defer/bounce 需要 MTA/DSN 证据。

客户收到的内容

邮件正文为可视化摘要,HTML 附件包含活动/tenant、job、收件人、字节、Postfix handoff、失败、retry、Queue-ID、域分布与 revision。不会包含 token、密码、许可密钥或邮件正文。

可观测性

消息与 Engine 状态

以下 endpoint 可让您无需直接登录 VPS 即可观察执行情况。

GET/api/v1/messages/status?message_id=...Bearer

返回指定消息的最新已知状态。

示例
{
  "ok": true,
  "message_id": "<...@mail.seudominio.com.br>",
  "queue_id": "wsq_...",
  "state": "POSTFIX_QUEUED",
  "stage": "POSTFIX_OWNS_MESSAGE",
  "postfix_queue_id": "4ABC123DEF",
  "cost_class": "tiny",
  "recipients": 1,
  "attempts": 0,
  "version": "1.3.3"
}
GET/api/v1/engine/statusBearer

Engine 全局 snapshot:backlog、worker、输入输出速率、资源、Postfix 队列、Adaptive 状态、最近活动和活动聚合。

GET/api/v1/engine/activityBearer

用于高频观察的精简视图:Adaptive 状态、待处理任务、活动 job、最近事件和 throughput。

GET/api/v1/engine/analyticsBearer

吞吐量、队列、资源、调度器、域和活动的时间序列与运行聚合数据。

ACCEPTEDQUEUEDMATERIALIZINGPOSTFIX_QUEUED

当前 API v1 可精确追踪 Ware Send 的责任直到 Postfix 接收。按收件人的最终确认、DSN/bounce 和远程投递状态将在成为公开契约后补充文档。

HTTP

响应与错误

HTTP含义建议处理
202消息已接受并持久化。需要跟踪处理时,请保存 message_id 和 queue_id。
200查询成功,或幂等发送已被接受。重复请求请检查 duplicate: true。
400JSON 或字段无效。修正 payload。未知字段也会被拒绝。
401Credential 缺失、无效或已撤销。检查应用配置的 Bearer token。
403安装没有可用的运行许可。联系 Ware Send 安装负责人。
409幂等性键正在处理中。等待后使用相同键重试。
503队列不可用或临时 backpressure。如存在 Retry-After 请遵守,并使用 backoff 重试。
认证错误
{
  "ok": false,
  "error": "unauthorized"
}

旧系统

SMTP Submission

对于无法使用 HTTP API 的旧系统,Ware Send 提供认证 SMTP Submission。SMTP 与 API 使用同一个 Engine、队列、scheduler、worker 和 Postfix 路径,不存在独立的投递 pipeline。

Engine 1.0.0 已提供

SMTP Submission 仅用于经过认证的应用提交。它不是入站 MX、邮箱、POP3、IMAP 或 webmail;端口 25 仍属于 MTA/Postfix 的职责。

SMTPmail.seudominio.com.br:587 / :465TLS + AUTH

使用安装实例的 FQDN,可选择端口 587 + STARTTLS 或端口 465 + 隐式 TLS。必须认证,并使用与 API 分离的安装级全局 SMTP 密码。从客户域名派生的规范地址(例如 example@example.cn)只是默认身份;同一密码可以认证该域名中的任意完整邮箱地址,例如 contact@example.cn、billing@example.cn 或 nfe@example.cn。规范身份的短别名(example)仍仅用于 AUTH 兼容。其他域名会被拒绝,MAIL FROM 仍受已授权发件域名限制。API Bearer token 不能用于 SMTP 认证。

服务器mail.seudominio.com.br
端口587 / 465
安全STARTTLS / implicit TLS
认证AUTH PLAIN / AUTH LOGIN
用户名example@example.com
密码部署或轮换时单独交付的 SMTP 密码;不要使用 API 的 ws_live_ Bearer token。
两个端口都必须使用 TLS

端口 587 先建立 SMTP 连接,并在 AUTH 之前协商 STARTTLS。端口 465 从连接开始即使用 TLS。Ware Send 不接受未加密的 SMTP 认证。

SMTP 流程
# Porta 587 / STARTTLS
S: 220 mail.seudominio.com.br ESMTP Ware Send 1.0.0
C: EHLO legado.local
S: 250-STARTTLS
C: STARTTLS
   ... TLS handshake ...
C: EHLO legado.local
S: 250-AUTH PLAIN LOGIN
C: AUTH ...
S: 235 2.7.0 Authentication successful
C: MAIL FROM:<notificacoes@seudominio.com.br>
S: 250 2.1.0 Sender OK
C: RCPT TO:<cliente@example.com>
S: 250 2.1.5 Recipient OK
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: ... RFC 5322 / MIME ...
C: .
S: 250 2.0.0 Message accepted for delivery; queue_id=wsq_...
250 表示什么?

DATA 结束后,Ware Send 只有在任务已经持久化到可靠队列后才返回 250。它表示已承担处理责任,与 HTTP 202 Accepted 等价;不代表收件人已经最终收到邮件。

限制与收件人

SMTP 使用 Engine 中配置的相同消息大小和收件人数限制。可通过 GET /api/v1/info 查询。支持多个 RCPT TO,也支持在同一会话中连续提交多封消息。

BCC 与 MIME

RFC 5322/MIME 内容会被保留。密送收件人应位于 RCPT TO envelope 中;如果旧客户端还在 header 中发送 Bcc 或 Resent-Bcc,Ware Send 会在投递前删除这些 header 以防止泄露。

可选元数据

SMTP 客户端可以发送 X-WareSend-Tenant 和 X-WareSend-Campaign-ID header,将消息关联到运行上下文和活动。

SMTP 幂等性

API 的 idempotency_key 语义在 SMTP 1.0.0 中不可用。如果连接在 DATA 之后、客户端收到 250 之前断开,客户端可能无法确认消息是否已被接受;不要假设会按 Message-ID 自动去重。

与 API 使用同一 dataplane

消息被接受后,API 与 SMTP 使用同一队列和投递路径。SMTP 没有单独的 egress 上限。具体 throughput 取决于安装环境 benchmark 和 SMTP 客户端行为。

GET/api/v1/infoBearer

GET /api/v1/info 会显示 SMTP Submission 是否启用、主机、默认用户名、auth_domain、username_policy、是否已配置密码、587/STARTTLS、465/隐式 TLS 以及 AUTH 机制。

查询配置
{
  "supports_smtp_submission": true,
  "smtp_submission": {
    "enabled": true,
    "host": "mail.seudominio.com.br",
    "username": "seudominio@seudominio.com.br",
    "auth_domain": "seudominio.com.br",
    "username_policy": "any-mailbox-in-auth-domain",
    "auth_configured": true,
    "auth_mechanisms": ["PLAIN", "LOGIN"],
    "starttls": {"enabled": true, "port": 587, "required": true},
    "implicit_tls": {"enabled": true, "port": 465}
  }
}

WARE SEND

集成简单,运行由 Engine 控制。

应用提交消息后,Ware Send 负责持久化、队列、Adaptive 控制,并根据基础设施容量交给 MTA。

返回 Ware Send