面向开发者和 QA
用真实的美国号码接收短信,直接送进你的代码。
一条真实的美国手机线路,不是 VoIP,把每条收到的短信交给你的代码。短信一存储,签名 Webhook 立即触发。REST API 负责列出和轮询。团队里的其他人照样能用实时收件箱、邮件和 Telegram。一条线路,每月 US$24.99,随时取消。
为什么不用电信平台的号码?
电信平台的可编程号码,按分类通常属于 VoIP。Twilio 自己有一篇讲发送验证码前过滤 VoIP 的文章,文中它的 Lookup 把一个 Twilio 号码标记为 nonFixedVoip(Twilio)。如果某个服务过滤 VoIP,它的验证码就永远到不了平台号码。Cleat 线路是手机线路,选它的理由就在这里。进一步了解号码类型。
快速开始
- 获取线路。注册并订阅。列出线路随时可用;读取某条线路的短信则在账号所有者完成身份验证之前返回
403。 - 在 Settings(设置)中创建 API 密钥。密钥以
clt_开头,只显示一次。如果你更想自动生成客户端,完整接口定义以 OpenAPI 格式提供。 - 在 Settings 中添加 Webhook 端点(如果你需要推送):填一个公开的 HTTPS URL。端点的签名密钥以
whsec_开头,只显示一次。 - 列出你的线路,然后轮询短信或等待 Webhook。
curl https://cleat.so/api/v1/lines \
-H "Authorization: Bearer $CLEAT_API_KEY"{
"data": [
{
"id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10",
"phone": "13055550100",
"label": "Staging sign-ups",
"status": "active",
"createdAt": "2026-09-11T10:00:00.000Z"
}
]
}curl "https://cleat.so/api/v1/lines/$LINE_ID/messages?after=2026-09-11T10:00:00Z&limit=50" \
-H "Authorization: Bearer $CLEAT_API_KEY"{
"data": [
{
"id": "c9a7e0d2-5b1f-4e8a-9f3c-6d2b1a0e4f77",
"line": { "id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10", "phone": "13055550100", "label": "Staging sign-ups" },
"from": "32665",
"body": "704118 is your Facebook confirmation code",
"code": "704118",
"receivedAt": "2026-09-11T10:02:41.000Z",
"service": { "id": "facebook", "name": "Facebook", "color": "#0866FF" },
"contact": null,
"label": "Facebook"
}
]
}Webhook
短信到达时,Cleat 会向你的每个端点发送 POST 请求,带上下面的 JSON 请求体、cleat-signature 请求头,User-Agent 为 Cleat-Webhooks/1.0:
{
"type": "message.received",
"data": {
"id": "c9a7e0d2-5b1f-4e8a-9f3c-6d2b1a0e4f77",
"line": { "id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10", "phone": "13055550100", "label": "Staging sign-ups" },
"from": "32665",
"body": "704118 is your Facebook confirmation code",
"code": "704118",
"receivedAt": "2026-09-11T10:02:41.000Z",
"service": { "id": "facebook", "name": "Facebook", "color": "#0866FF" },
"contact": null,
"label": "Facebook"
}
}签名请求头形如 t=1789120961,v1=5d41…。v1 是以端点签名密钥为密钥,对“时间戳 + 一个点 + 原始请求体”计算出的 HMAC-SHA256 十六进制值。先用原始字节校验签名,再解析。拒绝过旧的时间戳,防止重放攻击。
import crypto from "node:crypto";
import express from "express";
const app = express();
const secret = process.env.CLEAT_WEBHOOK_SECRET; // whsec_…
// cleat-signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "t.body">
function verified(header, body) {
const parts = Object.fromEntries(String(header).split(",").map((part) => part.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${body}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && parts.v1?.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}
app.post("/cleat-webhook", express.raw({ type: "application/json" }), (req, res) => {
const body = req.body.toString("utf8");
if (!verified(req.get("cleat-signature"), body)) return res.sendStatus(401);
const { type, data } = JSON.parse(body);
if (type === "message.received") {
// data.code is Cleat's best guess at a one-time code; data.body is the full text.
console.log(data.line.phone, data.from, data.code ?? data.body);
}
res.sendStatus(200);
});
app.listen(3000);投递细节
- 端点必须是公开的
https://URL。Cleat 不跟随重定向。 - 请在 10 秒内返回任意 2xx 状态码。
- 投递是至少一次。失败或超时的投递会重试:一共五次,第一次立即发出,之后分别再等 30 秒、2 分钟、10 分钟和 1 小时,每次都发送同样的字节并附上新的签名。请让你的处理逻辑对
data.id幂等;短信的id永不改变。Settings 页面保留每一次尝试,也可以重放任意一次投递。 - 如果五次都失败,可以用 API 的
?after=加上你最后处理的那条短信的receivedAt补齐。 - 线路处于暂停状态,或所有者尚未完成身份验证时,什么都不会推送。这些短信仍会保存,原因解除后即可读取,但之后也不会为它们补发 Webhook:请用
?after=读取。 - 每个工作区最多五个端点。Settings 页面会显示每个端点最近一次的状态,以及已经连续失败了多少次投递。
type是message.received;从 Settings 发出的测试投递则是test,data结构相同,只是 id 是它自己的。遇到不认识的类型请返回 200,以后可能会新增。- 如果填的不是你自己的 URL,而是 Slack 的 incoming webhook 或 Microsoft Teams 的 workflow 链接,那个端点收到的就是对应聊天应用自己的消息格式,并且没有
cleat-signature:和聊天应用之间没有共享密钥。 code是 Cleat 识别出的最可能的一次性验证码,也可能是null。完整的body始终都在。label用文字说明这条短信来自谁:优先是你的团队保存的联系人,其次是 Cleat 根据短信内容识别出的服务,背后还有contact和service。无法确定时三者都是null。它们是后来新增的字段,不会改动原有内容:from、body和code都保持不变。- 自动语音来电里念出的验证码也以同样方式送达。来电会被转成文字,作为
message.received投递:转写文字在body中,来电号码在from中,code也会填好。载荷里没有任何字段能区分这是来电还是短信。
API 参考
| 端点 | 返回内容 |
|---|---|
GET /api/v1/lines | API 密钥所属工作区中的线路,从新到旧:id、phone、label、status(active、grace 或 released)和 createdAt。 |
GET /api/v1/lines/{lineId}/messages | 某条线路上的短信。after(ISO 8601)返回该时刻之后收到的短信,从旧到新,用于轮询。before 向前翻页,从新到旧。limit 取值 1 到 200,默认 50。 |
Authorization: Bearer clt_…。limit 超出 1–200 会被收进区间,而不是报错。错误码:400 表示时间戳格式错误,401 表示密钥缺失、已撤销或已过期(code 为 key_expired),402 表示线路处于暂停状态,403 表示工作区所有者尚未验证身份(code 为 verify_first),404 表示线路不在该密钥的工作区内,或不在该密钥的授权范围内——这两种情况故意返回同样的结果,429 表示超出速率限制,503 表示无法确认该密钥的授权范围。限制与权限
每个 API 密钥每分钟 120 次请求;超出后 API 返回 429,且不带 Retry-After 头,退避策略要你自己定。只有工作区所有者可以创建 API 密钥和 Webhook 端点,密钥一经撤销立即失效。创建密钥时还可以收窄权限:限定到指定线路,并设置一个失效日期——正因如此才可以放心把它交给 AI 代理、CI 任务或外部协作者。授权范围之外的线路返回 404,过期的密钥返回 401,code 为 key_expired。
适合的用途
- 你们公司自己的账户,例如云控制台、域名注册商和支付服务商,验证码推送到值班工程师盯着的频道。
- 在预发布环境中对你们自己的注册和登录流程做 QA,用的号码表现得和客户的手机一样。
- 需要登记美国手机号码的个人项目。
不适合的用途
- 发送短信。Cleat Line 只能接收:不能发送短信、拨打电话,也无法拨通 911。
- 压力测试或号码池。每条线路都是独立订阅,各有一位已验证身份的持有人。Cleat 不是为号码池设计的。
- 不属于你或你公司的账户。
- 任何需要实时语音的场景。API 不能拨出电话。没有来电铃声可接,没有音频流,也没有录音可下载。通话结束后,你会收到这通电话的转写文字。Cleat Full 的通话在网页应用里接听和拨打,不经过 API。
对比
| 电信平台号码 | MailSlurp 电话号码 | Cleat Line | |
|---|---|---|---|
| 号码类型 | 按分类通常属于 VoIP;Twilio 的 Lookup 把一个 Twilio 号码标记为 nonFixedVoip | “dedicated, non-VoIP mobile numbers”(专用的非 VoIP 手机号码,MailSlurp) | 真实的美国手机线路,不是 VoIP |
| 面向 | 大规模收发 | QA 和开发测试 | 你自己的账户、QA 和小团队 |
| 持有人验证 | 企业 KYC 和 10DLC 注册 | 未说明 | 政府签发的证件和自拍,或仅证件验证(人工审核) |
| 把短信接入代码 | Webhook 和 API | API 和 Webhook | 签名 Webhook 和 REST API,外加 Telegram、邮件和收件箱 |
| 价格 | 按号码收费,另按消息收费 | 页面上未显示 | 每月 US$24.99,含接收短信 |
要和不写代码的同事共享验证码?请看团队共享 2FA。为什么 Google Voice 和其他网络号码会收不到验证码:Google Voice 与验证码。我们如何处理身份验证:信任与安全。完整计费规则:价格。
继续阅读
常见问题
有免费套餐或沙盒吗?
没有。一条线路每月 US$24.99,随时取消;线路持有人完成身份验证之前,线路上的短信都处于锁定状态。
可以通过 API 发送短信吗?
不可以。Cleat Line 只接收,从不发送。
如果服务打电话念验证码,而不是发短信呢?
来电会被转成文字,作为普通消息送到你的 Webhook 和 API:验证码已提取,来电号码在 from 中。没有字段标明它是来电。
有速率限制吗?
有:每个 API 密钥每分钟 120 次请求。Webhook 投递不计入。
Webhook 多快触发?
Cleat 存储短信后立即推送到你的端点,与实时收件箱、邮件和 Telegram 同步进行。我们没有公布实测延迟,所以不给出具体数字。
可以有多个号码吗?
你可以在工作区中添加线路,每条线路都是单独的 US$24.99 订阅。Cleat 不是为号码池设计的。
你们会保存我的消息吗?
短信会一直保存,直到你删除工作区或账户。详情见隐私政策。
资料来源
其他公司的信息来自其官方页面,核实于 2026年9月。
- Twilio, filtering VoIP numbers before sending codes https://www.twilio.com/en-us/blog/filter-voip-before-otp-verification
- MailSlurp, phone numbers https://www.mailslurp.com/product/phone-number-sms-service/