Para desarrollo y QA
Recibe SMS en un número real de EE. UU., directo en tu código.
Una línea móvil real de EE. UU., no VoIP, que le entrega cada SMS entrante a tu código: un webhook firmado en cuanto se guarda el mensaje, y una API REST para listarlos y consultarlos. Tu equipo sigue viendo la bandeja en vivo, el correo y Telegram. Una línea, USD 24.99 al mes, cancela cuando quieras.
¿Por qué no un número de una plataforma de telecom?
Los números programables de las plataformas de telecom suelen clasificarse como VoIP. El propio artículo de Twilio sobre filtrar VoIP antes de mandar códigos muestra su Lookup marcando un número de Twilio como nonFixedVoip (Twilio). Si el servicio en el que te registras, o contra el que pruebas, filtra VoIP, su código nunca llega a un número de plataforma. Una línea Cleat es una línea móvil. Esa es toda la razón para usarla. Más sobre tipos de línea.
Primeros pasos
- Consigue una línea. Regístrate, verifica tu identidad y suscríbete.
- Crea una API key en Ajustes. Empieza con
clt_y se muestra una sola vez. - Agrega un endpoint de webhook en Ajustes, si quieres recibir pushes: una URL HTTPS pública. Su secreto de firma empieza con
whsec_y se muestra una sola vez. - Lista tus líneas y luego consulta los SMS o espera los webhooks.
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": "55512",
"body": "Your verification code is 704 118",
"code": "704118",
"receivedAt": "2026-09-11T10:02:41.000Z"
}
]
}Webhooks
Cuando llega un SMS, Cleat manda un POST a cada uno de tus endpoints con este cuerpo JSON, un header cleat-signature y el 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": "55512",
"body": "Your verification code is 704 118",
"code": "704118",
"receivedAt": "2026-09-11T10:02:41.000Z"
}
}El header de firma se ve así: t=1789120961,v1=5d41…. v1 es el HMAC-SHA256 en hexadecimal del timestamp, un punto y el cuerpo crudo, con la clave del secreto de firma del endpoint. Verifícalo contra los bytes crudos antes de parsearlos, y rechaza los timestamps viejos para que nadie pueda reenviar una entrega capturada.
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);Detalles de la entrega
- Los endpoints deben ser URLs
https://públicas. Cleat no sigue redirecciones. - Responde con cualquier estado 2xx en menos de 10 segundos.
- Cada SMS se manda una vez. Si tu endpoint estaba caído, ponte al día con la API usando
?after=y elreceivedAtdel último SMS que procesaste. Elidde un SMS nunca cambia, así que úsalo para saltarte duplicados. - Hasta cinco endpoints por espacio de trabajo. Ajustes muestra el último estado de cada endpoint y cuántas entregas seguidas han fallado.
codees la mejor suposición de Cleat sobre el código de un solo uso, onull. Elbodycompleto siempre está.- Un código dictado en una llamada automática llega igual: la llamada se transcribe y se entrega como un
message.received, con la transcripción enbody, el número que llamó enfromycodelleno. Nada en el payload indica que la entrega fue una llamada y no un SMS.
Referencia de la API
| Endpoint | Qué devuelve |
|---|---|
GET /api/v1/lines | Las líneas del espacio de trabajo de la API key, de la más nueva a la más vieja: id, phone, label, status (active, grace o released) y createdAt. |
GET /api/v1/lines/{lineId}/messages | Los SMS de una línea. after (ISO 8601) devuelve los SMS recibidos después de ese momento, del más antiguo al más reciente, para consultar en bucle. before pagina hacia atrás, del más nuevo al más viejo. limit va de 1 a 200, y son 50 por defecto. |
Authorization: Bearer clt_…. Errores: 400 si el timestamp está mal formado, 401 si falta la clave o está revocada, 402 mientras la línea está en pausa, 404 si la línea está fuera del espacio de trabajo de la clave, 429 al pasar el límite.Límites y permisos
120 peticiones por minuto por API key; al pasarte, la API responde 429. Solo el dueño del espacio de trabajo puede crear API keys y endpoints de webhook, y una clave revocada deja de funcionar de inmediato.
Casos que encajan
- Las cuentas propias de tu empresa, como consolas de nube, registradores de dominios y procesadores de pagos, con los códigos publicados en un canal que vigila la persona de guardia.
- Staging y QA de tus propios flujos de registro e inicio de sesión, contra un número que se comporta como el teléfono de un cliente.
- Proyectos personales que necesitan un número de celular de EE. UU. registrado.
Casos que no
- Enviar SMS. Cleat Line solo recibe.
- Pruebas de carga o grupos de números. Cada línea es una suscripción aparte con un dueño verificado. Cleat no está hecho para manejar muchos números.
- Cuentas que no son tuyas ni de tu empresa.
- Cualquier cosa que necesite voz en vivo. Una línea no puede llamar, y no hay timbre que contestar, ni audio que transmitir, ni grabación que descargar: solo la transcripción de una llamada después de que terminó.
Cómo se compara
| Número de plataforma de telecom | Números de MailSlurp | Cleat Line | |
|---|---|---|---|
| Tipo de número | Muchas veces VoIP por clasificación; el Lookup de Twilio marca un número de Twilio como nonFixedVoip | “dedicated, non-VoIP mobile numbers” (MailSlurp) | Línea móvil real de EE. UU., no VoIP |
| Hecho para | Enviar y recibir a gran escala | QA y pruebas de desarrollo | Tus propias cuentas, QA y equipos pequeños |
| Verificación del dueño | KYC de empresa y registro 10DLC | No lo indica | Identificación oficial y selfie, o solo identificación revisada por una persona |
| Llevar los SMS al código | Webhooks y API | API y webhooks | Webhooks firmados y API REST, además de Telegram, correo y la bandeja |
| Precio | Por número más por mensaje | No aparece en la página | USD 24.99 al mes, SMS entrantes incluidos |
¿Compartes códigos con gente que no programa? Mira 2FA compartido para equipos. Por qué a Google Voice y a otros números de internet no les llegan los códigos: Google Voice y los códigos de verificación. Cómo manejamos la identidad: confianza y seguridad. Las reglas completas de cobro: precio.
Preguntas
¿Hay plan gratis o sandbox?
No. Una línea cuesta USD 24.99 al mes, cancelas cuando quieras, y nadie recibe una línea sin verificar su identidad.
¿Puedo enviar SMS por la API?
No. Cleat Line recibe; nunca envía.
¿Y si un servicio dicta el código en una llamada en vez de mandarlo por SMS?
La llamada se transcribe y llega a tu webhook y a la API como un mensaje normal, con el código extraído y el número que llamó en from. No hay ningún campo que te diga que fue una llamada.
¿Hay límites de peticiones?
Sí: 120 peticiones por minuto por API key. Las entregas de webhook no cuentan para ese límite.
¿Qué tan rápido salen los webhooks?
Cleat manda el POST a tus endpoints en cuanto guardó el SMS, junto con la bandeja en vivo, el correo y Telegram. No hemos publicado una latencia medida, así que no damos un número.
¿Puedo tener más de un número?
Puedes agregar líneas a un espacio de trabajo, y cada una es su propia suscripción de USD 24.99. Cleat no está hecho para manejar muchos números.
¿Guardan mis mensajes?
Los SMS se guardan hasta que borras el espacio de trabajo o tu cuenta. La Política de privacidad, en inglés tiene los detalles.
Fuentes
Los datos sobre otras empresas vienen de sus propias páginas, revisadas en septiembre de 2026.
- 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/