邮件

用 CZL Connect 的发件通道给你的用户发邮件,不用自己维护 SMTP、发件域名与退订。三种发法:

发法收件人内容调用方式
验证码任意邮箱固定模板,验证码由 CZL Connect 生成与校验API (email:code)
自定义邮件本应用用户HTML 或 Markdown,自动附退订链接API (email:send)
群发通知本应用用户 + 手动添加的邮箱Markdown,可定时应用详情「邮件」或 API (broadcast:write)

API 调用方式与凭证见应用级 API:在应用详情 → API 接入新建凭证并勾选对应 scope,请求头带 Authorization: Bearer czlc_live_...,接口前缀 https://connect.czl.net/api/v1/app。

开通条件与额度

按应用所有者的套餐开放,三种发法共用账户的月度邮件额度 (账户内所有应用合计,自然月按北京时间):

套餐月度邮件额度每日验证码上限
Lite不支持不支持
Plus5,000 封2,000 封
Pro30,000 封10,000 封
Enterprise不限50,000 封

验证码发送成功才计数;自定义邮件与群发按进入发送队列的收件人数计,发送失败不退还。

发件地址

邮件的显示名为「应用名(经 CZL Connect)」,发件地址默认 [email protected]。在应用详情 → 邮件设置发件别名后,地址变为 czlconnect_<别名>@notify.czl.net,收件人可按地址区分不同应用。

  • 别名 3-20 位小写字母、数字或连字符,全站唯一
  • 套餐支持邮件功能 (Plus 及以上) 才能设置,设置需通行密钥验证
  • 别名只能设置一次,设置后不能自行修改或清除;确需更改请联系客服。改掉的旧别名为原应用保留 90 天,期间其它应用不能使用
  • 改地址后,收件人按旧地址设置的过滤规则与白名单会失效
  • 不能包含冒充官方职能或知名品牌的词 (如 admin、billing、security、apple、paypal)
  • 发件地址不收信,不要引导用户回复邮件

验证码

适合给还不是你用户的人发验证码:临时用户订阅前确认是真人、注册前验证邮箱、注销账号前二次确认。验证码由 CZL Connect 生成、发送并校验,你的后端只拿到一个验证码 id。

发送

POST /api/v1/app/email-codes
Authorization: Bearer czlc_live_...
Content-Type: application/json

{
  "email": "[email protected]",
  "purpose": "subscribe",
  "locale": "zh",
  "clientIp": "203.0.113.9"
}
字段必填说明
email是收件邮箱,任意地址
purpose否用途,决定邮件主题与说明,默认 general,取值见下表
locale否邮件语言 zh / en,默认 zh
clientIp建议发起请求的终端用户 IP,用于按 IP 限频;只认公网地址,不传则不做 IP 维度限频
purpose邮件主题
general「应用名」验证码
signup「应用名」注册验证码
login「应用名」登录验证码
subscribe「应用名」订阅确认验证码
delete_account「应用名」注销账号验证码 (正文提醒操作不可撤销)

邮件同步发送,邮局收下后才返回 (通常一两秒),不排队:

{ "id": "ec_Xh3...", "expiresIn": 600, "expiresAt": "2026-11-14T10:20:00+08:00" }

验证码为 6 位数字,10 分钟内有效。

校验

POST /api/v1/app/email-codes/verify
Content-Type: application/json

{ "id": "ec_Xh3...", "code": "482913" }
{ "verified": true, "email": "[email protected]", "purpose": "subscribe" }

校验通过后验证码立即作废。错误返回 code_mismatch 并带 attemptsRemaining;错满 5 次作废,需重新发送。以返回的 email 为准记录用户邮箱,不要信任前端提交的邮箱。

限频

维度上限
同一应用、同一收件邮箱1 分钟 1 封
同一收件邮箱 (所有应用合计)24 小时 10 封
同一应用、同一 clientIp每小时 20 封
账户 (所有应用合计)每日验证码上限,见套餐表

界面上的「重新发送」按钮建议倒计时 60 秒。少数邮箱服务商会对首次来信做灰名单延迟,几分钟后才到;验证码页面请提示用户检查垃圾箱。

自定义邮件

给本应用用户发通知 (订单状态、账户提醒等),正文由你决定。

POST /api/v1/app/emails
Content-Type: application/json

{
  "userIds": ["1024", "2048"],
  "subject": "你的订单已发货",
  "html": "<p>订单 <b>#1234</b> 已发货。</p>"
}
字段说明
userIds本应用用户 ID (字符串或数字),单次 1-100 个
subject主题,不超过 200 字
html / markdown正文,二选一,不超过 200 KB

HTML 会经过净化:保留内联样式、表格布局与 http(s) 图片和链接,去掉脚本、表单、iframe 与事件属性。邮件外壳由 CZL Connect 添加 (应用名、收件原因、退订链接),并带 List-Unsubscribe 一键退订头。

返回 202,逐个给出受理结果,受理的邮件立即进入发送队列,一般数秒内送出:

{
  "queued": 1,
  "results": [
    { "userId": "1024", "status": "queued" },
    { "userId": "2048", "status": "skipped", "reason": "unsubscribed" }
  ]
}
reason说明
not_app_user不是本应用用户
banned全站封禁或在本应用中停用
unsubscribed已退订本应用通知
email_unavailable没有已验证的真实邮箱 (如 QQ / 微信登录且未补登邮箱)
rate_limited今天给该用户发的自定义邮件已达 20 封

用户退订后,群发与自定义邮件都不再发给他;验证码不受退订影响。服务重启时尚未发出的自定义邮件可能丢失,对必达内容请以你自己的业务状态为准。

群发任务

与应用详情「邮件」里新建群发的规则一致:创建时生成收件人快照,发送时再次排除退订与封禁用户,可定时,未开始的任务可取消。

POST /api/v1/app/broadcasts
Content-Type: application/json

{
  "subject": "11 月更新",
  "markdown": "## 新功能\n\n- ...",
  "audience": "all",
  "groups": ["t1", "t2"],
  "scheduledAt": "2026-11-20T10:00:00+08:00"
}
字段说明
audienceall 全部用户 / single 单个用户 (配 userId) / exclude 排除部分用户 (配 excludeUserIds) / extra_only 只发手动添加的邮箱
groupsall / exclude 时按应用内分组筛选,空为全部
extraEmails额外的外部邮箱 (未经 CZL Connect 登录的用户),单任务最多 1000 个,计入额度
scheduledAtRFC 3339 定时发送时间,空为立即 (由每分钟一次的发送任务拾取)

其它端点:

端点说明
GET /broadcasts?page=&pageSize=任务列表,按创建时间倒序
GET /broadcasts/:broadcastId任务状态与计数 (sentCount / failedCount / skippedCount)
POST /broadcasts/:broadcastId/cancel取消尚未开始发送的任务

额度查询

GET /api/v1/app/mail/quota

需要 email:code、email:send、broadcast:write 任一 scope,返回发件地址、每日验证码上限、本应用今日 / 本月用量与账户月度额度。

错误码

错误响应形如 {"error": "<code>", "message": "<说明>"}:

HTTPerror说明
400invalid_request / invalid_email / invalid_purpose参数不合法
400code_mismatch验证码错误,带 attemptsRemaining
400code_expired验证码不存在、已过期或已使用
400code_attempts_exceeded错误次数过多,验证码已作废
403mail_disabled当前套餐不支持
403quota_exceeded月度邮件额度用完
429rate_limited触发收件邮箱或 IP 限频
429daily_limit_exceeded账户今日验证码已达套餐上限
502send_failed邮件未能送出,可稍后重试
503temporarily_unavailable服务繁忙,稍后重试