文档
Mailera API
通过 REST 全面管理 Microsoft 邮箱(Outlook、Hotmail、Microsoft 365):添加邮箱、检查可用状态、读取邮件、获取 OTP 验证码、发送邮件、将邮件移出垃圾邮件文件夹以及接收 webhook。
简介
所有端点均使用同一基础 URL,接收和返回的数据均为 JSON。
- 1创建账户和自己的工作区(免费)。
- 2打开设置 → API key,创建 API key 并选择其权限范围。
- 3在每个请求的 X-API-Key 请求头中传入 API key。
成功响应包含 data 字段;错误响应包含 error 字段,其中含有 code 和 message。
创建免费工作区https://mailera.app/api/public/v1# 200{ "data": [ ... ], "next_cursor": "..." }# 4xx / 5xx{ "error": { "code": "not_found", "message": "..." } }身份验证
在 X-API-Key 请求头中传入 API key。API key 以 mh_live_ 开头,仅在创建时显示一次;如果丢失,请创建新的 API key 并撤销旧的 API key。
也可在 Authorization 请求头中使用同一 API key 作为 Bearer token。
可为 API key 设置 IP 白名单;来自其他 IP 的请求将返回 403。
curl https://mailera.app/api/public/v1/mailboxes \ -H "X-API-Key: mh_live_..."API key 权限范围
每个 API key 拥有一个或多个权限范围。调用权限范围之外的端点将返回 403 forbidden。
| 权限范围 | 允许操作 |
|---|---|
read | 读取邮箱、邮件、OTP 验证码及邮件投递位置(收件箱或垃圾邮件) |
move | 将邮件移出垃圾邮件文件夹或在文件夹之间移动 |
import | 添加邮箱 |
sync | 请求立即同步 |
send | 发送、回复和转发邮件 |
manage | 暂停、恢复和删除邮箱 |
webhooks | 管理 webhook |
错误
错误始终包含固定的 code 和英文 message。请根据 code 处理错误,不要依赖 message 文本。
| HTTP | 错误码 | 含义 |
|---|---|---|
| 401 | unauthorized | API key 缺失、无效、已过期或已撤销 |
| 403 | forbidden | API key 缺少所需权限,或 IP 不在其白名单中 |
| 404 | not_found | 邮箱或邮件不存在,或不属于 API key 所在的工作区 |
| 409 | mailbox_unavailable | 邮箱需要重新连接、已暂停或仅支持 IMAP(暂不支持) |
| 422 | validation_error | 请求数据格式错误 |
| 429 | rate_limited | 此 API key 每分钟请求数超过 300 次,请按 Retry-After 响应头指定的时长等待 |
| 503 | upstream_error | Microsoft 服务出错或正在限流,请稍后重试 |
| 500 | internal_error | 系统错误 |
限制与分页
每个 API key 每分钟可发起 300 次请求。超出限制将返回 429,并附带 Retry-After 响应头。
列表响应返回 next_cursor;将其作为 cursor 参数传入即可获取下一页。没有更多数据时,next_cursor 为 null。
limit 参数用于设置每页条数。
curl "https://mailera.app/api/public/v1/mailboxes?limit=50&cursor=NEXT_CURSOR" \ -H "X-API-Key: mh_live_..."邮箱
添加、检查、同步、暂停和删除邮箱。
- GET
/mailboxes列出邮箱
- 权限范围:
read- 查询参数:
- status, q, cursor, limit
- POST
/mailboxes/import批量导入邮箱(email:password:refresh_token:client_id,也可用 | 分隔)
- 权限范围:
import- 请求体:
- lines, text, group_id, duplicate_mode
- GET
/mailboxes/import获取导入进度和逐行结果
- 权限范围:
import- 查询参数:
- job_id
- GET
/mailboxes/{id}获取邮箱详情和文件夹邮件计数
- 权限范围:
read
- PATCH
/mailboxes/{id}暂停或恢复邮箱
- 权限范围:
manage- 请求体:
- action (必填)
- DELETE
/mailboxes/{id}删除邮箱
- 权限范围:
manage
- GET
/mailboxes/{id}/status向 Microsoft 实时检查邮箱是否仍可用
- 权限范围:
read
- POST
/mailboxes/{id}/sync立即同步
- 权限范围:
sync- 请求体:
- wait
curl -X POST https://mailera.app/api/public/v1/mailboxes/import \ -H "X-API-Key: mh_live_xxx" -H "content-type: application/json" \ -d '{"lines":["user@hotmail.com:pass:M.C5_refresh...:9e5f94bc-..."]}'# → { "data": { "job_id": "..." } }curl "https://mailera.app/api/public/v1/mailboxes/import?job_id=JOB_ID" -H "X-API-Key: mh_live_xxx"邮件
读取、搜索邮件,获取 OTP 验证码及发送邮件。
- GET
/mailboxes/{id}/messages列出文件夹中的邮件
- 权限范围:
read- 查询参数:
- folder, unread, cursor, limit
- GET
/mailboxes/{id}/messages/{msgId}获取单封邮件及其内容
- 权限范围:
read
- GET
/mailboxes/{id}/otp获取最新 OTP 验证码
- 权限范围:
read- 查询参数:
- from, subject, since_minutes
- POST
/mailboxes/{id}/send发送、回复或转发邮件
- 权限范围:
send- 请求体:
- to, cc, bcc, subject, html, text, importance, reply_to_message_id, mode, attachments
- GET
/messages/search搜索所有邮箱中的邮件
- 权限范围:
read- 查询参数:
- q, folder, limit
curl -X POST https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/send \ -H "X-API-Key: mh_live_xxx" -H "content-type: application/json" \ -d '{"to":["customer@example.com"],"subject":"Hello","text":"Message body"}'垃圾邮件
检查邮件投递至收件箱还是垃圾邮件文件夹,并将邮件移出垃圾邮件文件夹。
- POST
/mailboxes/{id}/messages/{msgId}/move移动邮件(例如从垃圾邮件移至收件箱)
- 权限范围:
move- 请求体:
- destination (必填)
- POST
/mailboxes/{id}/unspam将全部邮件或指定发件人的邮件移出垃圾邮件文件夹
- 权限范围:
move- 请求体:
- filter
- GET
/mailboxes/{id}/placement检查邮件投递至收件箱还是垃圾邮件文件夹
- 权限范围:
read- 查询参数:
- from, subject, since_minutes
curl "https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/placement?from=me@example.com" -H "X-API-Key: mh_live_xxx"curl -X POST https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/unspam -H "X-API-Key: mh_live_xxx" \ -H "content-type: application/json" -d '{"filter":{"type":"sender","value":"me@example.com"}}'webhook
注册用于接收事件的 URL。
每次事件发生时,Mailera 都会向您的 URL 发送 JSON 格式的 POST 请求。如果端点返回错误或未响应,Mailera 会重试,并逐步延长重试间隔。
| 事件 | 触发时机 |
|---|---|
message.received | 新邮件到达收件箱 |
message.junk | 新邮件进入垃圾邮件文件夹 |
mailbox.disconnected | 邮箱连接断开(token 被撤销、密码已更改等) |
验证时,将时间戳、英文句点和请求体依次拼接,使用 webhook 密钥计算 HMAC-SHA256,再与签名请求头中的值比较。
发送的请求头: X-MailHub-Event X-MailHub-Delivery X-MailHub-Timestamp X-MailHub-Signature
- GET
/webhooks列出 webhook
- 权限范围:
webhooks
- POST
/webhooks创建 webhook(签名密钥仅返回一次)
- 权限范围:
webhooks- 请求体:
- url (必填), events, group_id
- PATCH
/webhooks/{id}启用或禁用 webhook,或更改其事件或 URL
- 权限范围:
webhooks
- DELETE
/webhooks/{id}删除 webhook
- 权限范围:
webhooks
import crypto from "node:crypto";// X-MailHub-Signature: sha256=<hex> X-MailHub-Timestamp: <unix seconds>const expected = "sha256=" + crypto.createHmac("sha256", SECRET) .update(timestamp + "." + rawBody).digest("hex");const ok = expected.length === signature.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));示例
请将 MAILBOX_ID 和 API key 替换为您自己的值。
curl -X POST https://mailera.app/api/public/v1/mailboxes/import \ -H "X-API-Key: mh_live_xxx" -H "content-type: application/json" \ -d '{"lines":["user@hotmail.com:pass:M.C5_refresh...:9e5f94bc-..."]}'# → { "data": { "job_id": "..." } }curl "https://mailera.app/api/public/v1/mailboxes/import?job_id=JOB_ID" -H "X-API-Key: mh_live_xxx"curl https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/status -H "X-API-Key: mh_live_xxx"curl "https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/otp?from=noreply@service.com&since_minutes=15" \ -H "X-API-Key: mh_live_xxx"# → { "data": { "code": "482913", "folder": "inbox", ... } } or { "data": { "code": null } }curl -X POST https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/send \ -H "X-API-Key: mh_live_xxx" -H "content-type: application/json" \ -d '{"to":["customer@example.com"],"subject":"Hello","text":"Message body"}'curl "https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/placement?from=me@example.com" -H "X-API-Key: mh_live_xxx"curl -X POST https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/unspam -H "X-API-Key: mh_live_xxx" \ -H "content-type: application/json" -d '{"filter":{"type":"sender","value":"me@example.com"}}'const res = await fetch("https://mailera.app/api/public/v1/mailboxes?limit=50", { headers: { "X-API-Key": process.env.MAILERA_API_KEY },});const { data, next_cursor } = await res.json();import os, requestsr = requests.get( "https://mailera.app/api/public/v1/mailboxes/MAILBOX_ID/messages", params={"folder": "inbox", "limit": 20}, headers={"X-API-Key": os.environ["MAILERA_API_KEY"]},)print(r.json()["data"])import crypto from "node:crypto";// X-MailHub-Signature: sha256=<hex> X-MailHub-Timestamp: <unix seconds>const expected = "sha256=" + crypto.createHmac("sha256", SECRET) .update(timestamp + "." + rawBody).digest("hex");const ok = expected.length === signature.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
