iCloud Mail · 接口与接入说明

文档更新:2026-10-16 · v0.2.6。涵盖独立邮箱取码、项目邮箱池、已使用邮箱退役、按需收件与自动创建。HOST、ADMIN_PATH 和凭据均为示例占位符。

直接取码

使用单邮箱 API Key,或访问后台签发的取件链接。两种方式任选一种,不同时携带两种凭据。浏览器访问或刷新同样触发按需取件。

curl -H "Authorization: Bearer MAILBOX_API_KEY" https://HOST/api/v1/otp

https://HOST/api/v1/otp?token=DERIVED_TOKEN

启用 ICLOUD_API_OTP_RETURN_LATEST_ONLY=true 的部署,有记录时返回归属该邮箱的最新有效验证码:

{"otp":"876543","time":"2026-10-14T15:00:00+08:00"}

没有验证码时返回 200 []。未启用最新模式时返回最新优先的数组,最多 100 条;旧变量 ICLOUD_API_OTP_RETURN_LAST_ONLY 是兼容别名,同时配置以正式变量为准。时间使用部署时区,包含 UTC 偏移。

识别主题、纯文本与 HTML 可读文本中独立的六位 ASCII 数字。读取可重复,不消费验证码、不改变邮件已读状态。此接口可包含旧归档;需要区分本次任务的新码时,使用 Pool code 接口的 after 参数。

收件地址先完整精确匹配已登记 alias;未命中时,才剥离本地段第一个 + 及其后 tag,保持域名不变,再精确匹配 root。合法 root+tag 邮件可通过 root 取件;未知 root、其他域名及点号近似地址不匹配。完整登记的 + 地址优先归属自身。

项目邮箱池

项目接口使用 Authorization: Bearer pool_PROJECT_KEY。Pool Key 与单邮箱 Key 用途不同,租约仅在所属项目内可用。

curl -X POST https://HOST/api/v1/pool/claim \
  -H "Authorization: Bearer pool_PROJECT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"request_id":"task-20261014-0001","count":1,"ttl_seconds":1800}'

request_id 必填,8–128 位字母、数字、横线或下划线;count 为 1–50,默认 1;ttl_seconds 为 60–86400,默认 1800。领取前持久化编号和原参数。同项目、同编号、同参数返回原领取;参数变化返回 409 IDEMPOTENCY_CONFLICT。库存不足返回 409 POOL_EMPTY,整批不分配。

成功时 data.leases 中每项包含 lease 和仍有效的 mailbox 凭据包。取件可使用 mailbox.code_path。业务确认使用后提交 commit,避免尚未使用的领取到期回收。

方法与路径用途
GET /api/v1/pool/leases列出本项目租约;支持 state、limit、offset。
GET /api/v1/pool/leases/LEASE_ID读取租约;已关闭租约不再返回凭据。
POST /api/v1/pool/leases/LEASE_ID/commitleased → used,持续保留分配;已使用根邮箱不会被新领取重新分配。
POST /api/v1/pool/leases/LEASE_ID/renew发送 {"ttl_seconds":1800} 续期。
POST /api/v1/pool/leases/LEASE_ID/release释放尚未确认使用的领取,轮换邮箱凭据。

本次任务取码与短等待

curl -H "Authorization: Bearer pool_PROJECT_KEY" \
  'https://HOST/api/v1/pool/leases/LEASE_ID/code?after=2026-10-14T07%3A00%3A00Z&wait_seconds=15'

查询起点取领取时间与 after 中较晚者;after 使用 RFC3339,带 + 的时区偏移需 URL 编码。wait_seconds 为整数 0–15,默认 0。共享模式下新码到达立即返回;正常无新码到期返回 no_code。同 root 的 +tag 邮件聚合到根租约,子任务顺序由调用项目管理。

{"data":{"success":true,"otp":"876543","time":"2026-10-14T07:00:30Z"}}
{"data":{"success":false,"code":"no_code","retryable":true}}

HTTP 超时比等待预算多留网络余量。每次检查和最终响应重新核验 Pool Key、项目、live lease 及主号/alias 状态。retiring、retired 或已关闭租约停止取码。

已使用隐藏邮箱退役

只删除指定项目已领取并已使用的真实隐藏邮箱;不删除 iCloud 主号,不扫描或删除其其他地址。此流程与旧管理批量删除接口独立。

ADMIN_PATH 为部署方提供的管理前缀。三个接口均要求管理员 Session 与原项目 Pool Key;POST 还要求同源 CSRF。这里不公开实际管理前缀。

POST /ADMIN_PATH/api/v1/pool/aliases/batch
GET  /ADMIN_PATH/api/v1/pool/aliases/batch/jobs/OPERATION_ID
POST /ADMIN_PATH/api/v1/pool/aliases/batch/jobs/OPERATION_ID/reconcile
curl -X POST 'https://HOST/ADMIN_PATH/api/v1/pool/aliases/batch' \
  -H 'Cookie: icloud_admin_session=ADMIN_SESSION' \
  -H 'Origin: https://HOST' \
  -H 'X-CSRF-Token: ADMIN_CSRF' \
  -H 'Authorization: Bearer pool_PROJECT_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"operation_id":"retire-20261014-0001","items":[{"alias_id":123,"lease_id":"LEASE_ID"}]}'

operation_id 为 16–128 位 ASCII 字母、数字、横线或下划线;items 为 1–100 项。整批预检要求 alias/lease 精确对应、归属当前项目、为唯一 live lease 且状态 used;主号须启用、已认证,alias 须是已确认的真实隐藏邮箱。

受理返回 202,事务内将租约置为 retiring,关闭取码、renew、release 和再次 claim。Apple 确认成功后事务收口为 retired,删除本地 alias/pool_member,保留 lease 历史。明确失败恢复 used;远端结果未知或重启中断保持 retiring 与 review / interrupted。

同项目、同 operation_id、同顺序 items 重放原作业;内容或项目变化返回 409 IDEMPOTENCY_CONFLICT。GET 与原 POST 重放不重启副作用。GET 返回 200;缺失或其他项目工单返回 404 NOT_FOUND。

{"data":{"operation_id":"retire-20261014-0001","status":"completed","total":1,"processed":1,
  "items":[{"alias_id":123,"lease_id":"LEASE_ID","state":"retired","result_code":"","result_message":""}],
  "created_at":"2026-10-14T07:00:00Z","updated_at":"2026-10-14T07:00:30Z"}}

核验外部退役与显式恢复

向原工单 reconcile 路径 POST 完整原顺序 items 和明确的 resume 值:

{"items":[{"alias_id":123,"lease_id":"LEASE_ID"}],"resume":false}

resume=false 仅读完整权威目录,可靠确认原地址不存在时本地收口;仍存在保持 review,逐项码 APPLE_ALIAS_STILL_PRESENT。resume=true 明确授权对目录确认仍存在的原目标继续删除。目录未知保持 review,不盲目重放。成功受理返回 202。

核验在途时,同 resume 返回当前快照,不同 resume 返回 409 RETIREMENT_ACTION_CONFLICT。一轮结束后再 POST 可开启下一轮核验;响应丢失先 GET 再决定。逐项常见码:APPLE_RATE_LIMITED、APPLE_UPSTREAM_ERROR、APPLE_DELETE_UNCERTAIN、JOB_INTERRUPTED。响应只含工单、alias/lease 状态和稳定错误码,不返回密钥、Cookie 或邮件。

按需收件与退役并行

IMAP 增量批次将匹配正文合并为一次 UID FETCH,服务默认每批最多处理 128 条 UID,失败不推进游标;不支持批量正文读取的服务器使用逐封回退。网页正文重建版仅在 Message-ID、旧文件校验和及来源标记核验一致时升级为完整 MIME,保留归档身份与取码记录。

默认按需接收。共享模式同主号复用一条 IDLE 通知连接及一条串行读取连接;无有效取件 10 分钟后休眠。取件需求到达且观察超过 5 秒时补查;正常增量按持久化 UID 继续。冷启动或久未同步按服务端日期筛选定位时间窗口,正文限最近 15 分钟,不截断为最后 128 封。待处理时间边界与游标同事务保存,分页及重启继续原窗口;旧 IMAP 服务器可能返回较多日期匹配的 UID 元数据。这些是调度规则,并非投递时延承诺。

同主号的 Apple 退役与 IMAP 网络读取可并行。Apple 管理与 IMAP 读取各自按主号串行;保存时用本地事务核验账户配置及每个邮箱身份。退役一个 alias 不再丢弃其他 alias 的整批结果,新加入但未参与本批的地址不会被误标为已同步。

IMAP 密码、服务器、用户名、主号启停或收件通道变化使旧观察失效,包括停用后重启、配置切换后切回。retiring 租约立即停止 Pool 取码,其他邮箱继续收件。归档与 UID 同事务提交,未提交批次不推进游标。

public IMAPS 仅读本地归档。上游 iCloud IMAP 使用主号配置的 imap.mail.me.com:993、TLS 和 Apple App 专用密码;它与网关签发的单邮箱 IMAP 密码是两套凭据。Apple Account 登录供隐藏邮箱管理使用,重新登录不会替换 IMAP App 专用密码。

限流、空结果与重试

同 root 的链接、Bearer Key 与 Pool code 共用容量 2 的令牌桶,每 2 秒恢复 1 次。额度内的并发读者共享同步,普通读取与 Pool 长等待可共存;结束不追加冷却。被拦截刷新不扣额度、不重置恢复时间。旧非共享模式保留独占和完成后 2 秒冷却。

响应处理方式
200 [] / no_code正常读取完成,暂时无符合条件的新码;按任务 deadline 继续等待。
429 RATE_LIMITED按 Retry-After 秒数或 X-Retry-After-Ms 毫秒数重试,不叠加同 root 的多个长等待。
503 SYNC_UNAVAILABLE本次同步未完成或上游异常;按 Retry-After 与总 deadline 重试,区别于空结果。
503 PICKUP_BUSY取件容量不足、队满或排队超时;按 Retry-After 重试,并发本身不返回 429。
409 LEASE_CLOSED租约关闭、到期或退役,停止该租约取件。
401 INVALID_API_KEY / INVALID_POOL_KEY核对凭据类型、有效性及轮换状态。

X-RateLimit-Reason 区分 mailbox_rate、mailbox_cooldown、global_queue、wait_queue、wait_concurrency、global_concurrency、mailbox_capacity;旧非共享路径还可能返回 mailbox_inflight、account_concurrency、global_rate。在途完成时间未知时,只提供建议复查间隔。

共享入口取消每主号 64 与每秒 100 次限制;全站允许 512 个在途、入口总计最多 1024 个请求(含排队),排队预算 2 秒。Pool 长等待最多 384 个在途、总计最多 640 个(含排队),为普通读取预留容量。上游仍共享连接并受全局并发及最短 2 秒启动间隔约束。其他 Pool 路由保留每 IP 每分钟 300 次通用额度。容量按服务进程计数。

Apple 创建/删除限流与取件桶独立。退役沿用每主号串行、已有批量并发预算及 Apple Retry-After;未知结果先核验原工单。

自动创建与通道恢复

手动与批量创建按实际使用的通道确认原候选,已知来自新通道的待确认项不会阻塞旧通道;来源不明的候选继续先核验。同通道不重复生成,容量、身份和转发目标检查保持。

自动创建需在后台主动开启。新通道与旧通道均正常时,每主号每小时最多安排新通道 19 次、旧通道 4 次,共 23 次尝试。

新通道过期或退出、旧通道仍正常时,保留计划,分散执行旧通道每小时最多 5 次。新通道重新登录后,后续时间槽自动恢复 19+4,无需重新开启计划。模式切换和重启均不清空滚动额度或 Apple 冷却。

新通道创建、候选完成或详情读取被限流时,只冷却该通道,旧通道按原时间槽与独立额度继续。候选来源及完成 ID 持久保存,取得 ID 后只读取原详情;重复调度不会延长冷却,Apple 更长的 Retry-After 继续生效。目录暂时遗漏地址时可用原 ID 的详情精确核验;结果未知保留候选,历史来源不明项继续先核验原地址。公共会话或目录请求本身被限流时,仍暂停主号计划。

旧通道目录失效时暂停远端创建,保留已开启计划;重新登录后继续。创建依赖旧通道目录确认归属和结果,新通道登录态仍需配合目录确认。手动关闭的计划保持关闭,历史关闭项不会在升级时批量重开。

次数是本地尝试上限,实际成功数仍取决于 Apple 响应、Retry-After、库存与容量。待确认地址继续核验原候选,未知结果不重复生成。此规则不承诺 Apple 会话长期有效。

只读 IMAPS 与 OAuth

连接部署方提供的 public IMAPS 主机与端口,用户名为登记的隐藏邮箱,密码为网关签发的单邮箱 IMAP 密码。仅提供只读 INBOX,支持 LIST、STATUS、SELECT/EXAMINE、SEARCH、FETCH、UID FETCH 与 IDLE。

用 client ID 与 refresh token 换取一小时有效的 XOAUTH2 令牌:

curl -X POST https://HOST/oauth2/v2.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "client_id=CLIENT_ID" \
  --data-urlencode "refresh_token=REFRESH_TOKEN"
{"access_token":"ACCESS_TOKEN","token_type":"Bearer","expires_in":3600}

轮换邮箱凭据会同时使旧 API Key、链接、IMAP 密码及 OAuth 凭据失效。领取与回收通过事务和唯一 live lease 约束防止重复分配;used 租约保留,退休后的历史 lease 可有空 alias_id。