📧
API 对接文档
邮件发送系统
🔐后台管理

邮件发送接口对接文档

本文档面向需要调用本系统发送邮件的开发者。通过一个 HTTP 接口即可完成邮件发送, 支持 HTML 正文、多个收件人、抄送,以及指定不同的发信账号。

1 快速开始

1
获取 API 密钥
联系系统管理员,在后台「API 密钥」页面创建一个密钥。 密钥形如 mk_xxxxxxxxxxxx,创建后仅完整显示一次,请妥善保存。
2
发送一个请求
向接口地址 POST 一段 JSON,在请求头中带上密钥即可。
3
判断返回结果
返回 JSON 中的 code 为 0 表示发送成功,其他值表示失败, 失败原因见 msg 字段。
💡
最简调用(curl 一行搞定)
curl -X POST 'https://ai.maggiemi.cn/api/send.php' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: 你的密钥' \
  -d '{"to":"someone@example.com","subject":"标题","body":"<p>正文</p>"}'

2 接口地址与认证

接口地址 https://ai.maggiemi.cn/api/send.php
请求方式 POST
Content-Type application/json
认证方式 请求头 X-API-Key: 你的密钥
也兼容在请求体 JSON 中传 api_key 字段,但推荐使用请求头。
字符编码 UTF-8
🔑
认证请求头示例
X-API-Key: mk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

3 请求参数

参数名 类型 必填 说明
to string 必填 收件人邮箱地址。
多个收件人用英文逗号分隔,例如 a@x.com,b@y.com。
注意:多个收件人会互相看到对方地址。如需群发且互不可见,请分多次调用。
subject string 必填 邮件主题,支持中文,最长 200 字符
body string 必填 邮件正文。
支持 HTML 标签(<p>、<strong>、 <a>、<ul> 等), 常用邮箱均能正常渲染。
cc string 选填 抄送地址,多个用英文逗号分隔
account_id int 选填 指定使用哪个发信账号发送。
留空则使用系统配置的默认账号。 账号 ID 请向系统管理员索取。
is_html bool 选填 正文是否为 HTML 格式,默认 true。
传 false 时按纯文本发送,HTML 标签会原样显示。
template bool 选填 是否套用系统内置的邮件模板(带标题栏和发送时间页脚), 默认 false。
开启后会忽略你自己写的 <html> 外层结构。

4 返回格式

所有响应均为 JSON,结构固定为三个字段:

字段 类型 说明
code int 0 表示成功,非 0 表示失败
msg string 结果说明,失败时为具体错误原因
data object 附加数据,失败时可能为 null

成功响应

{
  "code": 0,
  "msg": "发送成功",
  "data": {
    "log_id": 1024,      // 日志编号,可用于对账
    "cost_ms": 428,     // 发送耗时(毫秒)
    "account": "客服邮箱"  // 实际使用的发信账号名
  }
}

失败响应

{
  "code": 1,
  "msg": "收件人邮箱格式不正确",
  "data": {
    "log_id": 0,
    "cost_ms": 12
  }
}
⚠️
注意:HTTP 状态码不一定代表业务结果。 请以响应体中的 code 字段为准。 只有认证失败会返回 HTTP 401,其余情况 HTTP 状态码通常为 200, 但 code 可能非 0。

5 各语言调用示例

PHP(cURL,推荐)

<?php
$payload = [
    'to'      => 'someone@example.com',
    'subject' => '您的订单已发货',
    'body'    => '<p>您好,您的订单 <strong>#12345</strong> 已发货。</p>',
    'template' => true,
];

$ch = curl_init('https://ai.maggiemi.cn/api/send.php');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_HTTPHEADER     => [
        'Content-Type: application/json',
        'X-API-Key: 你的密钥',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
]);

$res  = curl_exec($ch);
$err  = curl_error($ch);
curl_close($ch);

if ($err) {
    exit('请求失败:' . $err);
}

$data = json_decode($res, true);
if (isset($data['code']) && $data['code'] === 0) {
    echo '发送成功,日志编号 ' . $data['data']['log_id'];
} else {
    echo '发送失败:' . ($data['msg'] ?? '未知错误');
}

PHP(file_get_contents)

<?php
$payload = json_encode([
    'to'      => 'someone@example.com',
    'subject' => '测试邮件',
    'body'    => '<p>这是一封测试邮件</p>',
], JSON_UNESCAPED_UNICODE);

$ctx = stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/json\r\n"
                   . "X-API-Key: 你的密钥\r\n",
        'content' => $payload,
        'timeout' => 30,
    ],
]);

$res  = file_get_contents('https://ai.maggiemi.cn/api/send.php', false, $ctx);
$data = json_decode($res, true);
var_dump($data);

Python(requests)

import requests

url = 'https://ai.maggiemi.cn/api/send.php'
headers = {
    'X-API-Key': '你的密钥',
}

payload = {
    'to': 'someone@example.com',
    'subject': '测试邮件',
    'body': '<p>这是一封测试邮件</p>',
    'template': True,
}

try:
    res = requests.post(url, headers=headers, json=payload, timeout=30)
    data = res.json()
    if data.get('code') == 0:
        print('发送成功:', data['data']['log_id'])
    else:
        print('发送失败:', data.get('msg'))
except requests.RequestException as e:
    print('请求异常:', e)

Node.js(原生 fetch,Node 18+)

const res = await fetch('https://ai.maggiemi.cn/api/send.php', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': '你的密钥',
  },
  body: JSON.stringify({
    to: 'someone@example.com',
    subject: '测试邮件',
    body: '<p>这是一封测试邮件</p>',
  }),
});

const data = await res.json();
if (data.code === 0) {
  console.log('发送成功', data.data.log_id);
} else {
  console.error('发送失败', data.msg);
}

Java(OkHttp)

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build();

String json = "{\"to\":\"someone@example.com\","
        + "\"subject\":\"测试邮件\","
        + "\"body\":\"<p>正文</p>\"}";

RequestBody body = RequestBody.create(
        json, MediaType.parse("application/json; charset=utf-8"));

Request request = new Request.Builder()
        .url("https://ai.maggiemi.cn/api/send.php")
        .addHeader("X-API-Key", "你的密钥")
        .post(body)
        .build();

try (Response response = client.newCall(request).execute()) {
    System.out.println(response.body().string());
}

Shell / 定时任务

#!/bin/bash
API_URL="https://ai.maggiemi.cn/api/send.php"
API_KEY="你的密钥"

curl -s -X POST "$API_URL" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{
    "to": "someone@example.com",
    "subject": "每日报表",
    "body": "<p>今日数据已生成</p>"
  }'

6 常见错误与排查

HTTP code msg 内容 原因与处理
401 401 API 密钥无效或已停用 密钥填错、被删除或被管理员停用。请联系管理员确认。
405 1 请使用 POST 请求 用了 GET 请求。本接口只接受 POST。
200 1 请填写收件人邮箱 to 参数为空。
200 1 收件人邮箱格式不正确 邮箱地址写法有误,注意不要包含中文标点或空格。
200 1 请填写邮件主题 subject 参数为空。
200 1 请填写邮件内容 body 参数为空。
200 1 没有可用的发信账号 系统尚未配置发信账号,或账号都被停用了。请联系管理员。
200 1 含「认证失败」「535」 发信账号的授权码错误或已失效。请联系管理员检查账号配置。
200 1 含「无法连接」「timed out」 服务器无法连上 SMTP 服务,通常是网络或端口问题。请联系管理员。
200 1 含「550」「553」 收件人地址被拒绝,可能不存在,或发件人被对方拉黑。
🔍
排错建议
· 先用 curl 命令行测通,再写进代码,能快速区分是接口问题还是代码问题。
· 每个响应都会返回 log_id,把它提供给管理员可直接定位日志详情。
· 如果收到「发送成功」但对方没看到邮件,请让对方检查垃圾邮件文件夹。

7 注意事项

⏱️
请设置足够的超时时间
发信涉及 SMTP 服务器通信,通常耗时 200~2000 毫秒,网络不佳时可能更久。 建议调用方超时设置为 30 秒以上,不要用默认的短超时。
🔁
本接口不是幂等的,请勿自动重试
同一次请求重复提交会发出多封邮件。如果请求超时,不确定是否已发送, 请联系管理员根据日志核对后再决定是否重发。
📊
存在发送频率限制
限制来自底层邮箱服务商(如个人邮箱通常为每小时数十封)。 超限会导致发送失败甚至账号被临时禁用。 如有大批量发送需求,请提前与管理员沟通。
🔒
请妥善保管 API 密钥
· 不要把密钥硬编码在前端页面或公开仓库中。
· 建议通过环境变量或配置文件读取。
· 一旦怀疑泄露,立即联系管理员停用并重新生成。
✉️
关于正文格式
body 支持 HTML,但建议使用简单标签(p、br、 strong、a、ul)。 复杂 CSS、外部样式表、JavaScript 在多数邮箱客户端中会被过滤掉, 请使用内联样式(style="...")而非 <style> 块。
邮件发送系统 · API 对接文档
本页面可公开访问,不包含任何账号或密钥信息
如需获取 API 密钥或有其他疑问,请联系系统管理员