AutoTeam-F / docs /api.md
ZRainbow's picture
fix: reduce rotation probe interference
be34853
|
Raw
History Blame Contribute Delete
13 kB

HTTP API 文档

启动后访问 http://localhost:8787/docs 查看 Swagger 交互式文档。

所有 /api/* 端点需要:

Authorization: Bearer <API_KEY>

但以下接口例外:

  • /api/auth/check
  • /api/setup/status
  • /api/setup/save
  • /api/version
  • /api/setup/dns/check(setup 阶段免鉴权;API_KEY 已配置时仍要求 Bearer,只读查询)
  • /api/mail-provider/probe(setup 阶段免鉴权;API_KEY 已配置时仍要求 Bearer,见下文)

即时返回接口

这些接口直接返回结果,不创建后台任务。

方法 路径 说明
GET /api/auth/check 验证 API Key
GET /api/setup/status 检查配置是否完整(按 MAIL_PROVIDER 动态切换 optional)
POST /api/setup/save 保存初始配置(provider 互斥写盘)
POST /api/setup/dns/check 只读 DNS 诊断(A/AAAA/CNAME/MX/TXT,不会写 Cloudflare 或 DNS 服务商)
POST /api/mail-provider/probe 邮箱后端 3 步探测(fingerprint / credentials / domain_ownership)
GET /api/version 镜像版本指纹(git_sha + build_time,免鉴权,用于排查 docker 镜像是否过期)
GET /api/status 账号状态 + 实时额度
GET /api/status?fast=true 快速状态快照(跳过实时额度探测,适合前端轮询和轮换任务运行时刷新)
GET /api/accounts 所有账号列表
GET /api/accounts/active 活跃账号
GET /api/accounts/standby 待命账号
GET /api/team/members Team 全部成员(含外部成员与邀请)
POST /api/team/members/remove 移出成员 / 取消邀请
GET /api/logs 最近日志(支持 ?limit=100&since=0
GET /api/cpa/files CPA 认证文件列表
GET /api/config/auto-check 巡检配置
PUT /api/config/auto-check 修改巡检配置(运行时生效)
POST /api/sync 同步 active 认证文件到 CPA
POST /api/sync/from-cpa 从 CPA 反向同步认证文件到本地(含去重)
POST /api/sync/accounts 从 Team / auths 对账到本地账号池
POST /api/accounts/{email}/kick 将 active 账号移出 Team
DELETE /api/accounts/{email} 删除本地管理账号及其资源

Team 成员移除

POST /api/team/members/remove

请求体:

{
  "email": "user@example.com",
  "user_id": "123",
  "type": "member"
}
  • type = member:从 Team 中移出
  • type = invite:取消邀请

后台任务接口

这些接口返回 202 Accepted + task_id

方法 路径 说明
POST /api/tasks/rotate 智能轮转 {"target": 3}
POST /api/tasks/check 检查额度,{"include_standby": false} 追加探测 standby 池(限速 1.5s/号 + 24h 去重)
POST /api/tasks/add 自动注册并添加新账号
POST /api/tasks/fill 补满成员 {"target": 3}
POST /api/tasks/multi-master/fill 多 Team 母号并行补位 {"target": 3, "owner_workers": 2, "direct_parallel": 1, "workspace_ids": null, "dry_run": false}
POST /api/tasks/cleanup 清理成员 {"max_seats": null}
GET /api/tasks 任务列表
GET /api/tasks/{task_id} 任务详情

同一时间只允许一个 Playwright 操作;如果有任务执行中,新请求可能返回 409 Conflict

多 Team 母号并行补位

POST /api/tasks/multi-master/fill 在一个全局后台任务内部调度多个已导入的 Team owner。每个 Team 仍保持 1 owner + 2 managed children = 3 seats,并行只发生在 owner worker 维度,不会提高单 Team seat cap。

请求体:

{
  "target": 3,
  "owner_workers": 2,
  "direct_parallel": 1,
  "workspace_ids": ["ws-..."],
  "dry_run": false
}
  • target 会按现有 Team 上限 clamp 到 1..3
  • owner_workers 会受 MULTI_MASTER_MAX_OWNER_WORKERSMULTI_MASTER_BROWSER_BUDGET 裁剪。
  • direct_parallel 是单 owner direct signup race 的预算参数;当前切片先用于预算和任务可观测,直接注册 race 逻辑仍必须在 manager.py 中安全接入后才会改变单账号注册行为。
  • workspace_ids 可填 workspace id、owner account id 或 owner email;为空时使用所有 parallel=trueenabled=true 的 owner,若没有 parallel owner 则回退当前 active workspace。
  • dry_run=true 不创建后台任务,直接返回 plan,便于确认 owner 列表和预算。

GET /api/status 会额外返回 multi_master 字段,包含 aggregate summary 与 per-owner diagnostics。该字段不会回显 session_token

管理员运维

方法 路径 说明
POST /api/admin/reconcile?dry_run=0 对账修复:扫描 workspace 实际成员 vs 本地 accounts.json,识别残废 / 错位 / 耗尽未抛弃 / ghost / over-cap五类异常并按 RECONCILE_KICK_ORPHAN / RECONCILE_KICK_GHOST 决定 KICK 或打标记。dry_run=1 仅预测不动账户(包含第二轮 over-cap 预测),返回结构化诊断 dict(kicked / orphan_kicked / orphan_marked / misaligned_fixed / exhausted_marked / ghost_kicked / ghost_seen / over_cap_kicked / flipped_to_active

管理员登录

方法 路径 说明
GET /api/admin/status 管理员状态
POST /api/admin/login/start 开始登录 {"email": "admin@example.com"}
POST /api/admin/login/session 手动导入 session_token {"email": "admin@example.com", "session_token": "..."}
POST /api/admin/login/password 提交密码 {"password": "..."}
POST /api/admin/login/code 提交验证码 {"code": "123456"}
POST /api/admin/login/workspace 选择组织 {"option_id": "0"}
POST /api/admin/login/cancel 取消登录
POST /api/admin/logout 清除登录态

主号 Codex 同步

方法 路径 说明
GET /api/main-codex/status 登录/同步状态,包含 action
POST /api/main-codex/start 开始登录并同步到已启用的 CPA/Sub2API 目标;未启用目标时返回 400
POST /api/main-codex/login 只登录并保存本地主号 Codex 认证文件,不同步远端
POST /api/main-codex/password 提交密码
POST /api/main-codex/code 提交验证码
POST /api/main-codex/cancel 取消同步
POST /api/main-codex/delete-remote-files 删除已启用远端中的主号 Codex 认证文件
POST /api/main-codex/delete-cpa 兼容旧接口:同 /api/main-codex/delete-remote-files

手动 OAuth 导入

后端先生成 Codex OAuth 链接,并尝试在 localhost:1455 自动接收回调;如果自动回调不可用,也可以手动提交回调 URL。

方法 路径 说明
GET /api/manual-account/status 当前手动 OAuth 状态
POST /api/manual-account/start 开始流程,返回 auth_url 与状态信息
POST /api/manual-account/callback 提交回调 URL
POST /api/manual-account/cancel 取消流程

/api/manual-account/status 关键字段

字段 说明
status idle / pending_callback / completed / error
auth_url 当前 OAuth 链接
callback_received 是否已收到回调
callback_source automanual
auto_callback_available 本地自动回调服务是否启动成功
account 完成后导入的账号信息

初始配置 API

POST /api/setup/dns/check

只读 DNS 诊断端点,用于检查邮箱域名、OpenAI 域名验证 TXT、SPF、MX 等记录是否已经在公网 DNS 生效。该端点只通过公共 DNS-over-HTTPS 查询,不会读取 Cloudflare token,不会调用 DNS 服务商写接口,也不会创建、更新或删除记录。

鉴权策略与 /api/mail-provider/probe 一致:setup 阶段免 Bearer;一旦 API_KEY 已配置,必须带 Authorization: Bearer <API_KEY>

请求体可以使用内置字段,也可以直接传 records:

{
  "domain": "example.com",
  "mail_host": "mail.example.com",
  "mail_ip": "203.0.113.10",
  "mx_target": "mail.example.com",
  "spf_value": "v=spf1 include:_spf.example.com ~all",
  "openai_domain_verification": "openai-domain-verification=abc",
  "records": [
    {
      "type": "TXT",
      "name": "example.com",
      "expected": "openai-domain-verification=abc"
    }
  ]
}

响应示例:

{
  "ok": false,
  "domain": "example.com",
  "all_ok": false,
  "safe_read_only": true,
  "checks": [
    {
      "type": "TXT",
      "name": "example.com",
      "expected": "openai-domain-verification=abc",
      "observed": [],
      "ok": false,
      "error": null
    }
  ],
  "error_code": null,
  "message": null
}

POST /api/mail-provider/probe

邮箱后端 3 步探测,SetupPage / Settings 用作切换前置校验。setup 阶段免 Bearer(在 _AUTH_SKIP_PATHS 白名单);一旦 API_KEY 已配置,仍要求 Bearer,且按 IP 限速 60 req/min(超限返 error_code=RATE_LIMITED + HTTP 429)。

请求体(共用 schema):

{
  "provider": "cf_temp_email | maillab",
  "step": "fingerprint | credentials | domain_ownership",
  "base_url": "https://example.com/api",
  "username": "admin@example.com",     // 仅 maillab credentials/domain_ownership
  "password": "...",                   // 仅 maillab credentials/domain_ownership
  "admin_password": "...",             // 仅 cf_temp_email credentials/domain_ownership
  "domain": "example.com"              // 仅 domain_ownership
}

响应通用字段:

{
  "ok": true,
  "step": "fingerprint",
  "provider": "maillab",
  "detected_provider": "maillab",
  "domain_list": ["@a.com"],
  "warnings": [],
  "error_code": null,
  "message": null,
  "hint": null,
  "leaked_probe": null,
  "cleaned": null
}

error_code 取值见下表(失败时 ok=false):

error_code HTTP 说明
PROVIDER_MISMATCH 200 base_url 指纹与 provider 不一致(典型 issue#1)
ROUTE_NOT_FOUND 200 base_url 不是任何已知后端
EMPTY_DOMAIN_LIST 200 maillab domainList
UNAUTHORIZED 200 凭据校验失败
CAPTCHA_REQUIRED 200 maillab 启用了登录验证码
DOMAIN_REJECTED 200 创建探测邮箱被后端拒绝(addVerify=1 等)
NETWORK_ERROR / TIMEOUT 200 网络异常
RATE_LIMITED 429 60 req/min 限速触发

示例 1:step=fingerprint(探测后端归属)

curl -X POST http://localhost:8787/api/mail-provider/probe \
  -H "Content-Type: application/json" \
  -d '{"provider":"maillab","step":"fingerprint","base_url":"https://m.example.com"}'

成功响应:

{
  "ok": true,
  "detected_provider": "maillab",
  "domain_list": ["@example.com", "@x.example.com"],
  "warnings": []
}

示例 2:step=credentials(凭据校验)

cf_temp_email:

curl -X POST http://localhost:8787/api/mail-provider/probe \
  -H "Content-Type: application/json" \
  -d '{"provider":"cf_temp_email","step":"credentials","base_url":"https://mail.example.com/api","admin_password":"..."}'

cf_temp_emailbase_url 对应 CLOUDMAIL_BASE_URL,必须包含 /api 前缀;不要只填域名根路径。

maillab:

curl -X POST http://localhost:8787/api/mail-provider/probe \
  -H "Content-Type: application/json" \
  -d '{"provider":"maillab","step":"credentials","base_url":"...","username":"admin@x.com","password":"..."}'

示例 3:step=domain_ownership(域名归属验证)

curl -X POST http://localhost:8787/api/mail-provider/probe \
  -H "Content-Type: application/json" \
  -d '{"provider":"maillab","step":"domain_ownership","base_url":"...","username":"...","password":"...","domain":"example.com"}'

成功响应:

{
  "ok": true,
  "cleaned": true,
  "leaked_probe": null
}

如果探测邮箱删除失败(cleaned=false),leaked_probe{"email":"probe-...","account_id":"..."},需到管理后台手动删除。

内部使用 autoteam.mail.probe.probe_domain_ownership helper,与 /api/config/register-domain(注册域名验证)共用同一份逻辑,语义对齐。

调用示例

# 查看账号状态
curl -H "Authorization: Bearer YOUR_KEY" \
  http://localhost:8787/api/status

# 快速轮询状态(不触发实时额度探测)
curl -H "Authorization: Bearer YOUR_KEY" \
  "http://localhost:8787/api/status?fast=true"

# 触发轮转
curl -X POST -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target": 3}' \
  http://localhost:8787/api/tasks/rotate

# 从 CPA 拉取认证文件到本地
curl -X POST -H "Authorization: Bearer YOUR_KEY" \
  http://localhost:8787/api/sync/from-cpa

# 生成手动 OAuth 链接
curl -X POST -H "Authorization: Bearer YOUR_KEY" \
  http://localhost:8787/api/manual-account/start