多平台复用路线 API
这一组只给 Cursor/Claude/Poe 等多平台注册机使用,接口统一在 /api/reuse/v1/* 下。
AI 快速接入
你要接入 MailOps 多平台复用 API。
BASE_URL = "http://ops.nanlizz.top"
API_KEY = "mak_xxx"
PLATFORM = "cursor" # 必须显式传平台;例如 cursor/claude/poe/自定义平台
所有请求都带:
Authorization: Bearer API_KEY
Content-Type: application/json
固定流程:
1. 按平台预留邮箱:
POST {BASE_URL}/api/reuse/v1/mail/reserve
body: {"platform":PLATFORM,"request_id":"batch-worker-attempt","lease_seconds":1800}
2. 如果返回 email 为空,表示该平台当前没有可复用邮箱。
3. 用返回的 email 去目标平台注册,并且只轮询这个 email 的验证码。
4. 查询验证码仍然用现有邮件接口:
GET {BASE_URL}/api/mail/code?email={email}&keyword=code,验证码,verification code,{PLATFORM}&limit=10&folders=inbox,junk
5. 注册成功或平台可能已经占用邮箱时,确认平台占用:
POST {BASE_URL}/api/reuse/v1/mail/mark-used
body: {"platform":PLATFORM,"email":email,"lease_token":lease_token,"login_email":"平台登录邮箱","account":{...}}
6. 只有明确没有占用该邮箱时才释放:
POST {BASE_URL}/api/reuse/v1/mail/release
body: {"platform":PLATFORM,"email":email,"lease_token":lease_token,"reason":"register failed before email accepted"}
禁止事项:
- 不要省略 platform。多平台注册机必须显式传平台名。
- 不要用 GET /api/mailboxes 或 GET /api/reuse/v1/summary 来分配邮箱,它们只是查看/诊断。
- 不要丢 lease_token;mark-used/release 必须带 reserve 返回的 token。
- 同一个平台已 success 的邮箱不会再次发给同平台。
机器可读规格:/api-spec-reuse.json
状态流转
| 阶段 | 接口 | 平台状态 | 调用方要求 |
|---|---|---|---|
| 查看平台 | GET /api/reuse/v1/platforms | 不改变 | 启动时可读取支持的平台和策略。 |
| 可视化/排查 | GET /api/reuse/v1/summary | 不改变 | 只用于页面或诊断,不用于分配。 |
| 预留邮箱 | POST /api/reuse/v1/mail/reserve | reserved | 保存 email、lease_token、request_id。 |
| 平台注册成功 | POST /api/reuse/v1/mail/mark-used | success | 必须带正确 lease_token;可带平台账号资料。 |
| 失败且未占用 | POST /api/reuse/v1/mail/release | released | 只有确认目标平台没接受这个邮箱时才释放。 |
| 失败但可能占用 | POST /api/reuse/v1/mail/mark-used | success | 建议 status=needs_review 并写清失败阶段。 |
接口明细
1. 平台列表
GET /api/reuse/v1/platforms
{
"ok": true,
"platforms": [
{"platform_key": "openai", "display_name": "OpenAI", "allow_reuse": 0},
{"platform_key": "cursor", "display_name": "Cursor", "allow_reuse": 1}
]
}
2. 状态汇总
GET /api/reuse/v1/summary?platform=cursor&search=outlook&page=1&limit=50
summary 只用于页面和排查。OpenAI 卡片是旧链路可取口径;Cursor/Claude/Poe 是多平台复用口径。
3. 预留邮箱
POST /api/reuse/v1/mail/reserve
Authorization: Bearer mak_xxx
Content-Type: application/json
{
"platform": "cursor",
"request_id": "batch-20260625-worker-01-attempt-0001",
"lease_seconds": 1800
}
成功:
{
"ok": true,
"platform": "cursor",
"email": "legacy-used@outlook.com",
"lease_token": "lease_xxx",
"lease_expires_at": "2026-06-25T10:30:00.000Z",
"consumed": false
}
没有可用邮箱:
{
"ok": true,
"platform": "cursor",
"email": "",
"mailbox": null,
"reason": "no_available"
}
4. 确认平台已用
POST /api/reuse/v1/mail/mark-used
Authorization: Bearer mak_xxx
Content-Type: application/json
{
"platform": "cursor",
"email": "legacy-used@outlook.com",
"lease_token": "lease_xxx",
"login_email": "cursor-login@example.com",
"status": "available",
"account": {"batch_id": "batch-001"},
"detail": {"stage": "registered", "worker": "worker-01"}
}
5. 释放租约
POST /api/reuse/v1/mail/release
Authorization: Bearer mak_xxx
Content-Type: application/json
{
"platform": "cursor",
"email": "legacy-used@outlook.com",
"lease_token": "lease_xxx",
"reason": "target rejected before email accepted"
}
选号规则
| 规则 | 说明 |
|---|---|
| 同平台不重复 | 同一邮箱在同一 platform 已经 reserved 或 success 时,不会再次发给该平台。 |
| 跨平台可复用 | 邮箱已经是 OpenAI 旧链路已用,只要健康正常,仍可发给 Cursor/Claude/Poe 等其他平台。 |
| OpenAI 保护 | OpenAI 不走复用逻辑,旧 GPT 注册机继续使用 /api/mailboxes/*。 |
| 健康过滤 | 跳过 code_health=no_code/blocked/unhealthy 和 category=no_code/invalid/error。 |
| 租约防串号 | mark-used/release 必须携带正确 lease_token;错误 token 返回 409。 |
Python 示例
import time
import requests
BASE = "http://ops.nanlizz.top"
KEY = "mak_xxx"
PLATFORM = "cursor"
HEADERS = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}
reserved = requests.post(
f"{BASE}/api/reuse/v1/mail/reserve",
headers=HEADERS,
json={"platform": PLATFORM, "request_id": "batch-001-worker-01-attempt-001", "lease_seconds": 1800},
timeout=30,
).json()
if not reserved.get("email"):
raise RuntimeError(f"{PLATFORM} 没有可复用邮箱")
email = reserved["email"]
lease_token = reserved["lease_token"]
# 把 email 提交给目标平台,然后只轮询这个 email。
deadline = time.time() + 180
while time.time() < deadline:
code = requests.get(
f"{BASE}/api/mail/code",
headers=HEADERS,
params={"email": email, "keyword": f"code,验证码,verification code,{PLATFORM}", "limit": 10, "folders": "inbox,junk"},
timeout=30,
).json()
if code.get("found"):
break
time.sleep(8)
else:
requests.post(
f"{BASE}/api/reuse/v1/mail/release",
headers=HEADERS,
json={"platform": PLATFORM, "email": email, "lease_token": lease_token, "reason": "code timeout before account created"},
timeout=30,
)
raise RuntimeError("验证码超时")
requests.post(
f"{BASE}/api/reuse/v1/mail/mark-used",
headers=HEADERS,
json={
"platform": PLATFORM,
"email": email,
"lease_token": lease_token,
"login_email": "cursor-login@example.com",
"status": "available",
"account": {"batch_id": "batch-001"}
},
timeout=30,
).raise_for_status()