验证方式大致一分为二。开发者工具和 SaaS 大多发送邮件验证码。凡是涉及资金、身份或与手机号绑定的账号, 都会发短信。只能处理其中一种的智能体,会在半个互联网上卡住。
常见的答案是两家供应商:一个邮件 API,一个短信 API。这意味着两套认证模型、两种响应形态、 两种轮询策略、两种故障模式,外加一堆唯一作用是让它们在智能体眼里看起来一样的胶水代码。 胶水才是问题所在——那是没人愿意负责、却人人都得写的部分。
同样的形态,两个渠道
apumail 让两者都经过同一层。邮件流程:
# provision an inbox — no auth
INBOX=$(curl -sS -X POST https://api.apumail.com/api/v1/inboxes)
ADDR=$(echo "$INBOX" | jq -r .address)
TOK=$(echo "$INBOX" | jq -r .token)
# block until it lands, read the extracted code
curl -sS -H "Authorization: Bearer $TOK" \
"https://api.apumail.com/api/v1/inbox/$ADDR/wait?timeout=120" \
| jq -r '.messages[0].otp'
短信流程:
# buy a real dedicated number, on demand
PHONE=$(curl -sS -X POST https://api.apumail.com/api/v1/phones \
-H "Authorization: Bearer $TOK" \
-d '{"country_code":"US"}')
# same wait, same extract, different channel
开通、等待、提取。同样的动词,同样的认证,同样的 JSON。在 MCP 中,这种对称是字面意义上的——
wait_for_mail / extract_latest_otp 旁边就是
wait_for_sms / extract_latest_sms_otp。学会一个的智能体,也就学会了另一个。
按需号码
在其他地方,让智能体使用短信之所以别扭,在于号码的获取。大多数流程假定操作者是人:从号码池里挑一个、
等待可用、发邮件给客服申请新地区。而这里只需一次带 country_code 的
POST /api/v1/phones,就能当场买下一个真实的专属号码——无需等待号码池,无需给任何人发邮件。
只要付费,这个号码就一直属于该智能体,而不是一个会收到别人验证码的共享号码。
这也是坦诚的取舍:这是付费套餐。在美国/加拿大,号码每年 $20 起,按国家定价(用 $PROWL 支付为 $16),发送费用为每条短信 $0.07,从预付额度中扣除。邮件收件箱免费;电话号码要花钱, 因为运营商要收钱。如果你只需要邮件验证码,就永远不会碰到这部分,也永远不用付费。
不只是接收,还能发送
两个渠道都是双向的,这比听起来更重要。验证并不总是一个验证码——有时是回复确认,有时你在自动化的流程
在验证码之后还会继续通过同一渠道进行。只能接收的智能体,在第一次需要回复时就得交给人类。
send_mail 和 send_sms 让它留在流程中,并且 from 被锁定为
智能体自己的地址或号码,因此泄露的令牌无法被用来冒充任何人。
结论
用一家供应商解决通常需要两家的问题,本身并不是什么优点——只有当两半确实共享同一种形态时才是, 而这里正是如此。从邮件流程开始,它免费,只需一次 POST。 等某个流程需要号码时,再添加一个。