WildDuck 1.46 REST API 详解

WildDuck REST API 全量端点实战指南:认证机制、Users/Mailboxes/Messages/Addresses/Filters/Domains/DKIM/Submit 等 API 域详解与 curl 实测示例,所有端点返回已解析 JSON 邮件结构无需二次开发。

wildduckwildduckIMAP2026/10/27

WildDuck 1.46 REST API 详解

目标:本文档完整拆解 WildDuck REST API 的认证方式、核心端点、请求响应结构与实战 curl 示例,覆盖 Users/Mailboxes/Messages/Addresses/Filters/Domains/DKIM/Submit 等全部 API 域。信息源自官方 API 文档和社区端点对照表(查询日期 2026-10-27),所有 curl 示例可直接复制到部署环境执行。

一、环境信息

  • WildDuck 版本:1.46.1
  • API 协议:HTTP/JSON,默认端口 8080
  • API 基础地址:http://<host>:8080(本地部署)或 https://api.mail.example.com(反代后)
  • 认证方式:Bearer Token(通过 /authenticate 获取)
  • 请求格式:Content-Type: application/json
  • 分页方式:Cursor-based(next/previous 或 page 整数)
  • 限流:默认无强制限流,建议反代层配置
  • OpenAPI 规范:官方提供 Swagger 文档(源码内 /api 端点)

二、前置条件

  1. WildDuck 已安装并运行,API 端口 8080 可达
  2. 已创建至少一个管理员用户(详见部署指南)
  3. 具备 curl 或 Postman 等 HTTP 客户端
  4. 启用 API 访问控制([api.accessControl] enabled = true)后需先获取 token

三、API 总览

3.1 API 架构

WildDuck REST API 按资源域划分,所有请求统一返回 {success: boolean, ...data} 结构:

┌────────────────────────────────────────────────────────────┐
│                    WildDuck API 域拓扑                       │
│                                                              │
│  认证层   POST /authenticate → 获取 access token             │
│                                                              │
│  用户域   GET/POST/PUT/DELETE /users                         │
│  邮箱域   GET/POST/PUT/DELETE /users/:user/mailboxes         │
│  邮件域   GET/POST/PUT/DELETE /users/:user/messages          │
│  地址域   GET/POST/PUT/DELETE /users/:user/addresses         │
│  过滤域   GET/POST/PUT/DELETE /users/:user/filters           │
│  回复域   GET/PUT /users/:user/autoreply                     │
│  ASP域    GET/POST/DELETE /users/:user/asps                  │
│  提交域   POST /users/:user/submit                           │
│  存储域   GET /users/:user/quota                             │
│                                                              │
│  全局管理域                                                   │
│  健康检查 GET /healthz                                       │
│  配置域   GET/PUT /settings                                  │
│  域管理   GET/POST/PUT/DELETE /domains                       │
│  DKIM    GET/POST /domains/:domain/dkim                      │
│  域名别名 GET/POST/PUT/DELETE /domain-aliases                │
│  证书管理 GET/POST/PUT/DELETE /certs                         │
│  Webhooks GET/POST/PUT/DELETE /webhooks                      │
│  审计域   GET /users/:user/audit                             │
│  Elasticsearch GET /search                                   │
└────────────────────────────────────────────────────────────┘

3.2 认证方式

认证方式适用场景说明
X-Access-Token绝大多数 APIPOST /authenticate 获取的短期令牌,通过 header 传递
Scope 限定 token应用专用密码(ASP)token 可带 scope(master/imap/smtp/pop3),限制权限范围
Bootstrap token首次创建管理员日志中生成的一次性 token,用于初始化部署

3.3 通用约定

响应结构:所有 API 统一返回 JSON 对象,核心字段:

{
  "success": true,
  // 业务数据
}

错误响应:

{
  "success": false,
  "error": "错误类型",
  "message": "人类可读的错误描述"
}

请求 ID:所有请求支持可选 sess(会话标识)和 ip(客户端 IP)参数,用于审计日志追踪:

curl -X POST http://127.0.0.1:8080/users \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: YOUR_TOKEN" \
  -d '{"username":"alice","sess":"session-abc123","ip":"192.168.1.50"}'

四、认证与首次调用

4.1 首次获取 Token

# 认证请求:master scope 获取全权限 token
curl -X POST http://127.0.0.1:8080/authenticate \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin",
    "password": "q1w2e3r4",
    "token": true,
    "scope": "master",
    "protocol": "curl-test"
  }'

# 成功响应:
# {
#   "success": true,
#   "id": "69f3e3a1b2c3d4e5f6a7b8c9",
#   "username": "admin",
#   "scope": "master",
#   "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...(截断)",
#   "require2fa": [],
#   "requirePasswordChange": false
# }

4.2 Token 生命周期

  • 默认有效期 14 天(tokenTTL 配置)
  • 每次使用 token 时自动续期
  • 支持四种 scope:master(全权限)、imap(IMAP 专用)、smtp(发信专用)、pop3(POP3 专用)
  • 调用 PUT /users/:user/logout 吊销所有会话

4.3 保存 Token 供后续请求

# 一次性获取并导出
export WILDDUCK_TOKEN=$(curl -s -X POST http://127.0.0.1:8080/authenticate \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"q1w2e3r4","token":true}' | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")

echo "Token: $WILDDUCK_TOKEN"

五、各 API 域详解

5.1 用户域(Users)

5.1.1 创建新用户

curl -X POST http://127.0.0.1:8080/users \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "username": "alice",
    "password": "StrongPass123!",
    "address": "alice@example.com",
    "name": "Alice Wang",
    "language": "zh",
    "quota": 1073741824,
    "tags": ["vip", "engineering"],
    "retention": 0
  }'

# 响应:
# {"success":true,"id":"69f4e3a1b2c3d4e5f6a7b8d0"}
参数类型必填说明
usernamestring✅3-30 字符,系统内唯一
passwordstring✅(或 hashedPassword)≥ 8 字符
hashedPasswordboolean❌true 时 password 为预哈希值
addressstring❌默认邮箱地址,默认 username@emailDomain
quotanumber❌配额字节数,0 表示不限
tagsarray❌用户标签,可用于分组和策略
retentionnumber❌邮件保留时间(毫秒),0 表示不清理
encryptMessagesboolean❌是否自动 GPG 加密存储邮件

5.1.2 查询用户列表

# 列出所有用户(分页)
curl http://127.0.0.1:8080/users \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应:
# {
#   "success": true,
#   "total": 2,
#   "page": 1,
#   "previousCursor": false,
#   "nextCursor": false,
#   "results": [
#     {
#       "id": "69f3e3a1b2c3d4e5f6a7b8c9",
#       "username": "admin",
#       "address": "admin@example.com",
#       "quota": {"allowed": 0, "used": 40960},
#       "enabled2fa": [],
#       "disabled": false,
#       "suspended": false
#     },
#     ...
#   ]
# }

# 搜索 + 过滤参数
curl "http://127.0.0.1:8080/users?query=ali&tags=vip&limit=20" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"
查询参数说明
query模糊匹配用户名或邮箱地址
forward模糊匹配转发目标
tags逗号分隔的标签列表(OR 语义)
requiredTags逗号分隔(AND 语义,用户必须包含所有标签)
limit返回条数,默认 20,最大 250
next / previousCursor 翻页
metaDatatrue 时包含自定义元数据

5.1.3 查询单个用户详情

# 先通过用户名解析 ID(用户 ID 是 24 位十六进制字符串)
curl http://127.0.0.1:8080/users/resolve/alice \
  -H "X-Access-Token: $WILDDUCK_TOKEN"
# 响应:{"success":true,"id":"69f4e3a1b2c3d4e5f6a7b8d0"}

# 再获取详情
curl http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0 \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应节选:
# {
#   "success": true,
#   "id": "69f4e3a1b2c3d4e5f6a7b8d0",
#   "username": "alice",
#   "name": "Alice Wang",
#   "address": "alice@example.com",
#   "limits": {
#     "quota": {"allowed": 1073741824, "used": 52428800},
#     "recipients": {"allowed": 100, "used": 23, "ttl": 86400000}
#   },
#   "targets": [],
#   "enabled2fa": ["totp"],
#   "autoreply": false
# }

5.1.4 更新用户信息

curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0 \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "quota": 2147483648,
    "name": "Alice Wang (Updated)",
    "tags": ["vip", "engineering", "team-lead"],
    "disabled": false
  }'

# 响应:{"success":true}

5.1.5 重置用户密码

# 生成临时密码(24 小时有效)
curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/password/reset \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"
# 响应:
# {
#   "success": true,
#   "password": "T3mP-Pass-48h!",
#   "validAfter": "2026-10-28T10:30:00Z"
# }

5.1.6 删除用户

curl -X DELETE http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0 \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应:{"success":true}
# ⚠️ 不可逆操作:删除用户会级联删除其所有邮箱、邮件、过滤器等
# 建议操作前先备份该用户数据

5.2 邮箱域(Mailboxes)

WildDuck 中的「邮箱」不是传统 IMAP 的邮箱文件夹,而是一个用户下的邮件存储容器。用户默认有 INBOX、Sent、Drafts、Junk、Trash 等特殊邮箱。

5.2.1 列出用户邮箱

curl "http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/mailboxes?counters=true&sizes=true" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应:
# {
#   "success": true,
#   "results": [
#     {
#       "id": "69f4e3a1b2c3d4e5f6a7b8d1",
#       "name": "INBOX",
#       "path": "INBOX",
#       "specialUse": "\\Inbox",
#       "modifyIndex": 1523,
#       "total": 145,
#       "unseen": 3,
#       "size": 10485760
#     },
#     {
#       "id": "69f4e3a1b2c3d4e5f6a7b8d2",
#       "name": "Sent",
#       "path": "Sent",
#       "specialUse": "\\Sent",
#       "total": 28,
#       "unseen": 0
#     }
#   ]
# }
查询参数说明
specialUsetrue 时只返回特殊用途邮箱(INBOX/Sent/Drafts/Junk/Trash)
showHiddentrue 时显示隐藏邮箱
counterstrue 时包含 total/unseen 计数
sizestrue 时包含邮箱大小(字节)

5.2.2 创建自定义邮箱

curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/mailboxes \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "path": "Projects/Project-A",
    "retention": 0
  }'

# 响应:{"success":true,"id":"69f4e3a1b2c3d4e5f6a7b8d5"}

5.2.3 更新邮箱配置

curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/mailboxes/69f4e3a1b2c3d4e5f6a7b8d5 \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"retention": 2592000000, "subscribed": true}'
# 2592000000ms = 30 天

5.2.4 删除邮箱

curl -X DELETE http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/mailboxes/69f4e3a1b2c3d4e5f6a7b8d5 \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

5.3 邮件域(Messages)

WildDuck API 返回的是已解析的 JSON 邮件结构,而非原始 RFC822。这是 WildDuck 相比传统 IMAP 的最大优势之一——无需二次开发解析。

5.3.1 列出邮箱中的邮件

curl "http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/mailboxes/69f4e3a1b2c3d4e5f6a7b8d1/messages?limit=10&order=desc" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应节选:
# {
#   "success": true,
#   "total": 145,
#   "page": 1,
#   "previousCursor": false,
#   "nextCursor": "eyJzdGFydElkIjox...",
#   "results": [
#     {
#       "id": 1048,
#       "mailbox": "69f4e3a1b2c3d4e5f6a7b8d1",
#       "thread": "69f4e3a1b2c3d4e5f6a7b8d1",
#       "from": {"name": "Tech Lead", "address": "tech@example.com"},
#       "to": [{"name": "Alice Wang", "address": "alice@example.com"}],
#       "subject": "[Engineering] Weekly Meeting Agenda",
#       "date": "2026-10-27T09:00:00Z",
#       "intro": "Hi everyone, here's this week's agenda...",
#       "attachments": true,
#       "size": 482931,
#       "seen": true,
#       "flagged": false,
#       "draft": false,
#       "answered": false,
#       "bimi": {"certified": false},
#       "contentType": {"value": "multipart/mixed"}
#     }
#   ]
# }
查询参数说明
unseentrue 时只返回未读邮件
limit返回条数,默认 20,最大 250
orderasc 最旧在前 / desc 最新在前
next / previousCursor 翻页
threadCounterstrue 时返回线程消息数
includeHeaders逗号分隔的 header 列表(如 Date,X-Priority)

5.3.2 搜索邮件

# 基础搜索
curl "http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/search?q=weekly+meeting" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 高级搜索:限定范围
# q 支持:from:xxx to:xxx subject:xxx before:date after:date
curl "http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/search?q=from%3Atech%40example.com+after%3A2026-10-20" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 按 ID/线程/邮箱精确过滤
curl "http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/search?thread=69f4e3a1b2c3d4e5f6a7b8d1" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

5.3.3 获取单封邮件详情

curl "http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/messages/1048" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应包含完整解析内容:
# {
#   "success": true,
#   "id": 1048,
#   "subject": "[Engineering] Weekly Meeting Agenda",
#   "from": {"name": "Tech Lead", "address": "tech@example.com"},
#   "to": [...],
#   "text": {
#     "plain": "Hi everyone, here's this week's agenda:\n1. Sprint review\n2. Next sprint planning...",
#     "html": "<div>Hi everyone, <b>here's</b> this week's agenda...</div>"
#   },
#   "attachmentsList": [
#     {
#       "id": "att_abc123",
#       "filename": "agenda.pdf",
#       "contentType": "application/pdf",
#       "sizeKb": 452
#     }
#   ]
# }

5.3.4 邮件标记(已读/星标/删除)

# 标记已读
curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/messages/1048 \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"seen": true}'

# 加星标
curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/messages/1048 \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"flagged": true}'

# 删除(移到 Trash 或永久删除)
# 先移到 Trash
curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/messages/1048 \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"deleted": true}'

# 永久删除
curl -X DELETE http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/messages/1048 \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

5.4 地址域(Addresses)

用户可以有多个别名地址(address labels),如 alice+work@example.com、alice+personal@example.com,全部投递到同一个用户。

# 列出用户所有地址
curl http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/addresses \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 添加新别名
curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/addresses \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"address": "alice+work@example.com", "main": false}'

# 更新(设为主地址)
curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/addresses/alice%2Bwork%40example.com \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"main": true}'

# 删除别名
curl -X DELETE http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/addresses/alice%2Bwork%40example.com \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

💡 技术拓展:WildDuck 的地址标签(address labels)与 Plus Addressing 的关系——Plus Addressing(user+tag@domain)在 RFC 5233 中定义为「子地址」,MTA 处理时将 +tag 去掉投递到主地址。WildDuck 额外允许通过 API 注册非 Plus 格式的别名(如 support@example.com → alice@example.com),并支持标签作为独立地址出现在邮件头中。

5.5 过滤域(Filters)

过滤器在服务器端自动对入站邮件执行操作(移入指定邮箱、打标签、自动回复、丢弃)。

# 列出过滤器
curl http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/filters \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 创建新过滤器
curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/filters \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "name": "GitHub Notifications",
    "query": "from:github.com",
    "action": {
      "type": "move",
      "mailbox": "Projects/Notifications"
    },
    "active": true
  }'

# 过滤器 action 类型:
# - {"type": "move", "mailbox": "path"}  — 移入指定邮箱
# - {"type": "flagged", "flagged": true} — 加星标
# - {"type": "seen", "seen": true}       — 标记已读
# - {"type": "delete"}                   — 直接删除
# - {"type": "reply", "text": "..."}     — 自动回复

# 更新/删除过滤器
curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/filters/FILTER_ID \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"active": false}'

5.6 自动回复域(Autoreply)

自动回复设置控制用户是否启用「不在办公室」自动回复:

# 查询当前自动回复状态
curl http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/autoreply \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 设置自动回复
curl -X PUT http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/autoreply \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "autoreply": true,
    "startDate": "2026-11-01T00:00:00Z",
    "endDate": "2026-11-07T23:59:59Z",
    "subject": "Out of office - vacation",
    "text": "Hi, I am on vacation from Nov 1-7. I will respond when I return.",
    "html": "<p>Hi, I am on vacation...</p>"
  }'

5.7 应用专用密码(ASPs)

ASP(Application-Specific Password)是一种 scope 限定的一次性密码,便于为第三方客户端(如 Thunderbird、iOS Mail)生成独立密码并可随时吊销。

# 列出已有 ASP
curl http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/asps \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 创建新 ASP(返回生成的密码,仅显示一次)
curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/asps \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "name": "Thunderbird Laptop",
    "scopes": ["imap", "smtp"],
    "expiresAfter": null
  }'

# 响应:
# {
#   "success": true,
#   "id": "asp_abc123",
#   "password": "Abc123Xyz789Def456",  # ⚠️ 仅此一次可见
#   "name": "Thunderbird Laptop",
#   "scopes": ["imap", "smtp"]
# }

# 吊销 ASP
curl -X DELETE http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/asps/asp_abc123 \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

5.8 邮件提交(Submit)

通过 API 直接发信,无需 SMTP 客户端。适合 Web 应用集成、系统通知等场景。

curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/submit \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "from": {"name": "Alice", "address": "alice@example.com"},
    "to": [{"name": "Bob", "address": "bob@external.com"}],
    "cc": [],
    "bcc": [],
    "subject": "Meeting rescheduled",
    "text": "Hi Bob, our Tuesday meeting is rescheduled to Thursday 2pm.",
    "html": "<p>Hi Bob, our <b>Tuesday</b> meeting is rescheduled to <b>Thursday 2pm</b>.</p>",
    "attachments": [
      {
        "filename": "agenda.pdf",
        "contentType": "application/pdf",
        "content": "data:application/pdf;base64,JVBERi0xLjM..."
      }
    ],
    "headers": {
      "X-Custom-Header": "custom-value"
    }
  }'

# 响应:
# {
#   "success": true,
#   "messageId": "<567890123456.abc@example.com>",
#   "queueId": "zmta-queue-xyz",
#   "accepted": ["bob@external.com"],
#   "rejected": []
# }

⚠️ Submit API 需要 ZoneMTA 外发 SMTP 组件正常运行。如果只部署了 WildDuck 核心(无 ZoneMTA),提交请求会失败。

5.9 存储与配额

# 查询用户配额和实际使用
curl http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/quota \
  -H "X-Access-Token: $WILDDUCK_TOKEN"
# 响应:
# {
#   "success": true,
#   "quota": {"allowed": 1073741824, "used": 52428800, "percentage": 4.88},
#   "attachments": {"total": 45, "size": 31457280}
# }

# 强制重新计算配额(大数据量用户可能需要数秒)
curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/quota/reset \
  -H "X-Access-Token: $WILDDUCK_TOKEN"
# 响应:
# {"success":true,"storageUsed":54123000,"previousStorageUsed":52428800}

六、全局管理 API 域

6.1 健康检查

# 极简健康检查(无需认证)
curl http://127.0.0.1:8080/healthz
# 响应:{"status":"ok","uptime":34560,"version":"1.46.1"}

# 详细状态(需认证)
curl http://127.0.0.1:8080/health \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

6.2 Settings 配置运行时修改

# 列出所有可运行时修改的配置
curl http://127.0.0.1:8080/settings \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 修改单个配置
curl -X PUT http://127.0.0.1:8080/settings/log.level \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"value":"warn"}'

# 删除配置(恢复到文件配置)
curl -X DELETE http://127.0.0.1:8080/settings/log.level \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

6.3 域名管理

# 列出所有邮件域名
curl http://127.0.0.1:8080/domains \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 添加新域名
curl -X POST http://127.0.0.1:8080/domains \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "domain": "newcompany.com",
    "aliases": ["newco.com", "newco.io"],
    "dkim": {"enabled": true, "selector": "default"}
  }'

# 更新域名配置
curl -X PUT http://127.0.0.1:8080/domains/newcompany.com \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{"aliases": ["newco.com"]}'

# 删除域名
curl -X DELETE http://127.0.0.1:8080/domains/newcompany.com \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

6.4 DKIM 管理

# 获取域名 DKIM 配置和 DNS 记录指引
curl http://127.0.0.1:8080/domains/example.com/dkim \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应包含 DNS TXT 记录值:
# {
#   "success": true,
#   "domain": "example.com",
#   "selector": "default",
#   "publicKey": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8...",
#   "dnsRecord": "default._domainkey.example.com TXT \"v=DKIM1; k=rsa; p=...\""
# }

# 重新生成密钥(⚠️ 会立即使旧密钥失效)
curl -X POST http://127.0.0.1:8080/domains/example.com/dkim/rotate \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

6.5 Webhooks 配置

# 列出 webhooks
curl http://127.0.0.1:8080/webhooks \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 创建新 webhook
curl -X POST http://127.0.0.1:8080/webhooks \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "url": "https://my-app.example.com/api/mail-events",
    "events": ["new_message", "authentication_success", "authentication_failure"],
    "secret": "whsec_random_string_for_hmac"
  }'

# 支持的事件类型:
# - new_message          新邮件到达
# - authentication_success 登录成功
# - authentication_failure 登录失败
# - account_change       账户变更(改密码、禁用等)
# - quota_exceeded       配额超限

6.6 审计日志

# 查询用户的审计日志(登录尝试、密码修改等)
curl "http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/audit?limit=50" \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 响应:
# {
#   "success": true,
#   "results": [
#     {
#       "event": "authentication_success",
#       "time": "2026-10-27T10:15:00Z",
#       "protocol": "imap",
#       "ip": "192.168.1.100",
#       "scope": "imap"
#     },
#     {
#       "event": "password_changed",
#       "time": "2026-10-26T14:30:00Z",
#       "ip": "192.168.1.100"
#     }
#   ]
# }

6.7 TLS 证书管理

# 列出已安装的证书
curl http://127.0.0.1:8080/certs \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

# 上传自定义证书
curl -X POST http://127.0.0.1:8080/certs \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d '{
    "cert": "-----BEGIN CERTIFICATE-----\nMIIF...",
    "key": "-----BEGIN PRIVATE KEY-----\nMIIE..."
  }'

# 触发 ACME 证书刷新
curl -X POST http://127.0.0.1:8080/certs/acme/refresh \
  -H "X-Access-Token: $WILDDUCK_TOKEN"

七、分页与过滤通用约定

7.1 Cursor-based 分页

WildDuck 采用 cursor 分页(而非传统 offset),适合大数据集:

# 第一次请求
curl "http://127.0.0.1:8080/users?limit=50"

# 响应包含 nextCursor:
# {"nextCursor": "eyJzdGFydElkIjoxMDAsImJhdGNoIjo1MH0="}

# 获取下一页(自动续期 token)
curl "http://127.0.0.1:8080/users?next=eyJzdGFydElkIjoxMDAsImJhdGNoIjo1MH0="

7.2 过滤参数汇总

资源过滤参数说明
Usersquery, forward, tags, requiredTags模糊搜索 + 标签过滤
Messagesq(搜索语法), thread, unseen, mailbox全文/线程/状态过滤
MailboxesspecialUse, showHidden特殊用途/隐藏过滤

7.3 速率限制建议

API 层未强制限流,但反代层(Traefik/Nginx)建议配置:

# Nginx 限流示例
limit_req_zone $binary_remote_addr zone=wildduck:10m rate=10r/s;

location / {
    limit_req zone=wildduck burst=20 nodelay;
    proxy_pass http://127.0.0.1:8080;
}

八、常见问题

Q1:API 返回 401 "Access token required"

检查是否正确设置 X-Access-Token header。如果 token 已过期,重新调用 /authenticate 获取新 token。

Q2:创建用户报 "Duplicate key error"

username 在系统内唯一;address 在所属域名内唯一。先查询 GET /users?query=xxx 确认不存在再创建。

Q3:如何批量导入用户?

# users.json 格式:[{"username":"u1","password":"p1","address":"u1@example.com"}, ...]
cat users.json | python3 -c "
import json, sys, subprocess
users = json.load(sys.stdin)
for u in users:
    result = subprocess.run([
        'curl', '-s', '-X', 'POST', 'http://127.0.0.1:8080/users',
        '-H', 'Content-Type: application/json',
        '-H', f'X-Access-Token: {\"$WILDDUCK_TOKEN\"}',
        '-d', json.dumps(u)
    ], capture_output=True, text=True)
    print(u['username'], '->', result.stdout.strip())
"

Q4:如何用 API 上传附件到服务器再发送?

Submit API 的 attachments[].content 字段支持 base64 编码,小附件直接内联。大附件(>5MB)建议先用 POST /users/:user/messages/attachments 上传,再在 submit 时引用 attachment ID:

# 上传附件
ATTACH_ID=$(curl -s -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/messages/attachments \
  -H "Content-Type: application/octet-stream" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  --data-binary @/path/to/large-file.pdf | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")

# 在 submit 中引用
curl -X POST http://127.0.0.1:8080/users/69f4e3a1b2c3d4e5f6a7b8d0/submit \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: $WILDDUCK_TOKEN" \
  -d "{\"subject\":\"File attached\",\"attachments\":[{\"id\":\"$ATTACH_ID\"}]}"

Q5:API 返回 500 "MongoDB connection error"

WildDuck 与 MongoDB 的连接中断。先检查 MongoDB 健康状态 mongosh --eval "db.runCommand({ping:1})",确认 WildDuck 的 dbs.mongo 连接串配置正确,然后重启 WildDuck。

九、参考链接