cleat.

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

  1. Consigue una línea. Regístrate, verifica tu identidad y suscríbete.
  2. Crea una API key en Ajustes. Empieza con clt_ y se muestra una sola vez.
  3. 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.
  4. Lista tus líneas y luego consulta los SMS o espera los webhooks.
Listar las líneas de tu espacio de trabajo
curl https://cleat.so/api/v1/lines \
  -H "Authorization: Bearer $CLEAT_API_KEY"
Respuesta
{
  "data": [
    {
      "id": "8f14e45f-ceea-4b6b-9d3c-2a1f0e7c5b10",
      "phone": "13055550100",
      "label": "Staging sign-ups",
      "status": "active",
      "createdAt": "2026-09-11T10:00:00.000Z"
    }
  ]
}
SMS recibidos después de un momento, del más antiguo al más reciente
curl "https://cleat.so/api/v1/lines/$LINE_ID/messages?after=2026-09-11T10:00:00Z&limit=50" \
  -H "Authorization: Bearer $CLEAT_API_KEY"
Respuesta
{
  "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:

Cuerpo de la petición
{
  "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.

Verificar y procesar una entrega (Node.js, Express)
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 el receivedAt del último SMS que procesaste. El id de 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.
  • code es la mejor suposición de Cleat sobre el código de un solo uso, o null. El body completo 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 en body, el número que llamó en from y code lleno. Nada en el payload indica que la entrega fue una llamada y no un SMS.

Referencia de la API

EndpointQué devuelve
GET /api/v1/linesLas 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}/messagesLos 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.
URL base https://cleat.so. Autentica con 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 telecomNúmeros de MailSlurpCleat Line
Tipo de númeroMuchas 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 paraEnviar y recibir a gran escalaQA y pruebas de desarrolloTus propias cuentas, QA y equipos pequeños
Verificación del dueñoKYC de empresa y registro 10DLCNo lo indicaIdentificación oficial y selfie, o solo identificación revisada por una persona
Llevar los SMS al códigoWebhooks y APIAPI y webhooksWebhooks firmados y API REST, además de Telegram, correo y la bandeja
PrecioPor número más por mensajeNo aparece en la páginaUSD 24.99 al mes, SMS entrantes incluidos
Los datos de otras empresas vienen de sus propias páginas, revisadas en septiembre de 2026.

¿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.

  1. Twilio, filtering VoIP numbers before sending codes https://www.twilio.com/en-us/blog/filter-voip-before-otp-verification
  2. MailSlurp, phone numbers https://www.mailslurp.com/product/phone-number-sms-service/

Consigue una línea y una API key.

USD 24.99 al mes, cancela cuando quieras.