Saltar al contenido principal

Webhook SMS

Recibe los SMS de tu móvil
como webhook, en tu propio número.

Las API para recibir SMS suelen empezar por alquilar un número nuevo. Instala en cambio una app Android gratis: cada SMS que recibe tu SIM llega a tu URL como JSON firmado, y respondes desde ese mismo número.

¿Con prisa? Resume este artículo con una IA

La respuesta corta

¿Se pueden recibir los SMS de tu propio número por webhook?

Sí, con un móvil Android. La app gratis de Unlimited Messaging vincula la SIM de tu móvil a tu cuenta, y cada SMS que recibe después de iniciar sesión se envía a tu URL como un evento JSON firmado, message.received. Tus clientes siguen escribiendo al número que conocen y no pagas nada por SMS recibido. A diferencia de Twilio, no hay número que alquilar. Los webhooks están en los planes de pago Medium y Max.

La vía clásica para recibir SMS por API es un proveedor A2P. Con Twilio alquilas un número (1,15 $ al mes por un número local de EE. UU.), apuntas su webhook a tu servidor y pagas 0,0083 $ por segmento recibido más una tarifa del operador, 0,0035 $ desde AT&T o 0,0025 $ desde T-Mobile. El número es nuevo, así que tus clientes tienen que aprendérselo, y Twilio envía parámetros form-encoded firmados con HMAC-SHA1.

Una pasarela Android evita el alquiler. Unlimited Messaging para Android es gratis y de código abierto (MIT): instalas el APK, inicias sesión y cada SIM se convierte en una cuenta SMS (doble SIM, dos cuentas). El móvil mantiene una conexión con la API, sube cada SMS que recibe, y la API lo anuncia a tu webhook en el mismo sobre JSON que usa para WhatsApp y email. Una subida repetida del mismo SMS se reconoce y nunca se anuncia dos veces.

El precio es físico: el móvil tiene que estar encendido, conectado y con permiso para funcionar en segundo plano. Gestiona los SMS de un negocio a ritmo humano, no el tráfico entrante de un número corto nacional.

Compara primero: las cuatro apps de pasarela SMS para Android y lo que cuesta de verdad una API SMS gratis.

Ilustración: un teléfono con burbujas de SMS y una etiqueta SMS, con el titular «Los SMS recibidos, directo a tu código».

Los eventos

¿Qué eventos SMS envía el webhook?

El SMS usa los mismos tipos de evento que los demás canales. Un endpoint solo recibe los tipos de su lista eventTypes.

  1. message.received

    Llegó un SMS a una de tus SIM. data.channel.type es SMS, content lleva el texto y sender el número en +E.164. Un remitente que el operador muestra con un nombre (un banco, una empresa de envíos) llega con sender a null y ese nombre en senderId.

  2. message.sent

    Un SMS que enviaste por la API salió del móvil. Lleva el texto y el destinatario, se emite una vez, para que tu bandeja muestre los dos lados.

  3. message.status

    Un SMS que enviaste pasó a SENT, DELIVERED (cuando el operador envía acuses de entrega), FAILED o UNDELIVERABLE, con error indicando el motivo. El SMS no tiene acuse de lectura: nunca READ.

  4. account.status_changed

    Una cuenta SIM cambió de estado, por ejemplo desconectada al cerrar sesión en la app. Suscríbete para saber cuándo el móvil deja de reenviar.

POST https://example.com/webhooks/umJSON
{
  "type": "message.received",
  "eventId": "whd_2b9e7c41-0d3a-4f6e-8c52-91a7d4e0b6f3",
  "occurredAt": "2026-11-09T08:42:06.000Z",
  "data": {
    "message": {
      "id": "msg_7d2c9a10-5e4b-4b8f-a1c3-0f6e2d9b8a47",
      "externalId": "c1f4a9e27b3d4e6f9a0b",
      "direction": "IN",
      "fromMe": false,
      "content": "Running 10 min late for my 9:00, sorry!",
      "sentAt": "2026-11-09T08:42:03.000Z",
      "receivedAt": "2026-11-09T08:42:06.000Z",
      "sender": "+447700900456",
      "senderId": "+447700900456",
      "senderName": null,
      "participant": null,
      "replyTo": null,
      "transcript": null
    },
    "channel": {
      "type": "SMS",
      "account": { "id": "acc_5e8d1f2a-3c4b-4d6e-9f70-1a2b3c4d5e6f", "name": "Front desk SIM" },
      "conversation": { "id": null, "isGroup": false, "address": "+447700900456" }
    }
  }
}
Un cuerpo message.received real para un SMS, construido a partir del esquema publicado. conversation.id es null en SMS: agrupa el hilo por sender. Solo se suben los SMS recibidos después de iniciar sesión en la app; los que ya estaban en el móvil nunca se leen.

Puesta en marcha

¿Cómo recibir SMS entrantes en Node.js?

Instala la app, registra un endpoint, verifica cada POST. El mismo handler servirá luego para WhatsApp y email.

  1. 01

    Instala la app Android

    Descarga el APK desde GitHub (Android 8.0 o posterior), inicia sesión, concede acceso a los SMS y batería sin restricciones. Cada SIM aparece como una cuenta SMS.

  2. 02

    Registra el endpoint

    POST /webhooks con tu URL y tus eventTypes, o añádelo en la página Webhooks del panel. El secreto (whsec_...) se muestra una sola vez.

  3. 03

    Verifica, confirma, actúa

    Comprueba la cabecera webhook-signature, devuelve un 2xx en menos de 10 segundos, deduplica por eventId y luego responde o guarda.

POST /webhookscurl
curl https://api.unlimitedmessaging.app/webhooks \
  -H "Authorization: Bearer $UM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/um",
    "eventTypes": ["message.received", "message.status"],
    "description": "Incoming SMS"
  }'

# The response carries "secret": "whsec_..." once. Store it as UM_WEBHOOK_SECRET.
Añade accountIds para limitar el endpoint a una SIM; sin él, cubre todas tus cuentas, incluidas las SIM que añadas más adelante.
handler del webhookNode.js / Express
import crypto from 'node:crypto';
import express from 'express';
import { UnlimitedMessagingApiClient } from '@unlimited-messaging/sdk';

const um = new UnlimitedMessagingApiClient({ token: process.env.UM_API_KEY! });
const key = Buffer.from(process.env.UM_WEBHOOK_SECRET!.replace(/^whsec_/, ''), 'base64');
const seen = new Set<string>(); // use your database in production

// Standard Webhooks: HMAC-SHA256 of "id.timestamp.rawBody", base64.
function verify(raw: string, id: string, ts: string, header: string) {
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const expected = crypto.createHmac('sha256', key).update(`${id}.${ts}.${raw}`).digest('base64');
  return header.split(' ').some((entry) => {
    const sig = entry.startsWith('v1,') ? entry.slice(3) : '';
    return sig.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  });
}

const app = express();
app.post('/webhooks/um', express.raw({ type: 'application/json' }), async (req, res) => {
  const raw = req.body.toString('utf8');
  const ok = verify(raw, req.get('webhook-id') ?? '', req.get('webhook-timestamp') ?? '',
    req.get('webhook-signature') ?? '');
  if (!ok) return res.sendStatus(401);
  res.sendStatus(200); // answer within 10 s, work afterwards

  const event = JSON.parse(raw);
  if (seen.has(event.eventId)) return; // at-least-once delivery
  seen.add(event.eventId);

  if (event.type === 'message.received' && event.data.channel.type === 'SMS') {
    const { sender, content } = event.data.message;
    if (content?.trim().toUpperCase() === 'C') {
      // Texts back from the same SIM that received the SMS.
      await um.messages.messageSend({
        to: { phone: sender },
        channels: [{ channel: 'SMS', accountId: event.data.channel.account.id }],
        text: 'Thanks, your appointment is confirmed.',
      });
    }
  }
});
app.listen(3000);
La verificación sigue el esquema Standard Webhooks documentado (HMAC-SHA256 sobre id.timestamp.rawBody). La respuesta indica la SIM que recibió el SMS, así que sale desde el mismo número.

Vibe coding

¿Programas con Cursor, Claude Code, Lovable o Bolt? Pega esto

Tu editor con IA recibe la ruta, el esquema de firma y la forma del evento SMS de una vez.

Prompt para copiar
Add an Unlimited Messaging webhook to this app so it receives the SMS my own Android phone receives.

1. Create a POST route at /webhooks/um that reads the RAW request body.
2. Verify the Standard Webhooks signature: key = base64-decode(UM_WEBHOOK_SECRET without "whsec_"); expected = base64(HMAC-SHA256(key, `${webhook-id}.${webhook-timestamp}.${rawBody}`)); accept if any space-separated entry of the webhook-signature header equals `v1,${expected}` (constant-time compare); reject timestamps more than 5 minutes off; return 401 otherwise.
3. Return 200 at once, then process. Deduplicate on body.eventId.
4. On type "message.received" with data.channel.type "SMS", save data.message.sender (+E164, or null with the name in senderId), data.message.content and data.message.sentAt. conversation.id is null for SMS: group by sender.
5. To reply by SMS, install @unlimited-messaging/sdk, read UM_API_KEY from env, and call `client.messages.messageSend({ to: { phone: sender }, channels: [{ channel: 'SMS', accountId: data.channel.account.id }], text })`.
6. Put UM_API_KEY and UM_WEBHOOK_SECRET in .env and .env.example, never in code.

Docs: https://docs.unlimitedmessaging.app (Webhooks). Register the URL with POST https://api.unlimitedmessaging.app/webhooks and eventTypes ["message.received", "message.status"].

Lo que se construye

¿Qué puedes hacer con los SMS que recibe tu propio número?

Todo lo que empieza con un cliente que escribe al número de tu furgoneta, tu folleto o tu factura.

Recordatorios con confirmación por respuesta

Envía un recordatorio por SMS, lee la C o la R que vuelve, actualiza la cita y confirma, todo desde tu número de siempre.

Los SMS en tu CRM

Asocia cada SMS recibido al contacto por sender, junto a su WhatsApp y su email: los tres llegan en el mismo sobre.

  1. Gestión de BAJA

    Detecta STOP o BAJA en content y marca el contacto antes de tu próximo envío.

  2. Primera respuesta con IA

    Pasa el texto a un LLM para un borrador, devuélvelo por SMS o pásalo a una persona.

  3. Alertas de máquinas y servicios

    Reenvía los SMS de una alarma, una SIM de sensor o un proveedor a Slack o por email.

  4. Flujos sin código

    Apunta el webhook a n8n, Make o Zapier y ramifica según content, sin servidor.

La tabla

Recibir SMS por webhook: Twilio, pasarelas Android y Unlimited Messaging

Un número alquilado a un proveedor, o la SIM que ya está en tu móvil.

Recibir SMS por webhook: Twilio, pasarelas Android y Unlimited Messaging
TwilioNúmero alquilado (EE. UU.)SMSGate / httpSMSPasarelas Android de código abiertoUnlimited MessagingApp Android, planes de pago
Número que recibeUn número alquilado a TwilioLa SIM de tu móvilLa SIM de tu móvil
Coste mensual del número1,15 $ local, 2,15 $ gratuito (toll-free)Nada aparte de tu tarifaNada aparte de tu tarifa; webhooks con Medium o Max
Coste por SMS recibido0,0083 $ por segmento más tarifa del operadorNingunoNinguno por parte de Unlimited Messaging
PayloadForm-encoded, X-Twilio-Signature (HMAC-SHA1)Webhook o URL de callback (SMSGate: evento sms:received)JSON, firma Standard Webhooks (HMAC-SHA256)
HardwareNingunoUn móvil Android encendidoUn móvil Android 8.0+ encendido
WhatsApp y email en el mismo webhookWhatsApp con un remitente registrado; email con SendGrid, por separadoSolo SMSSí, mismo sobre, misma firma
VolumenPensado para gran volumenEl ritmo de un móvilEl ritmo de un móvil

Comprobado el 9 de noviembre de 2026 en los precios de SMS de Twilio para EE. UU., su documentación de mensajes entrantes y de seguridad de webhooks, y los repositorios de SMSGate y httpSMS (enlaces en las fuentes). Las tarifas del operador varían según el operador del remitente.

La letra pequeña

¿Qué límites tiene un webhook SMS desde tu móvil?

Sin número alquilado ni coste por SMS, pero un móvil sigue siendo un móvil.

  1. Los webhooks son de pago

    En el plan Free, los SMS recibidos aparecen en la bandeja de la aplicación web. Enviarlos a tu servidor requiere Medium (19 € al mes, o 17 € al mes con pago anual) o Max.

  2. El móvil tiene que estar encendido y conectado

    Apagado, sin cobertura o cerrado por el ahorro de batería, no reenvía nada hasta que vuelve. Deja la batería de la app sin restricciones y permite el inicio automático en Samsung, Xiaomi, Huawei, Oppo y Vivo.

  3. Solo Android, fuera de Google Play

    Google Play solo concede permisos de SMS a la app de SMS predeterminada, así que la app se distribuye como APK firmado en GitHub. No hay versión para iPhone.

  4. Solo texto, desde el inicio de sesión

    El SMS es solo texto (sin MMS). Solo se suben los mensajes recibidos después de iniciar sesión en la app: los SMS que ya estaban en el móvil nunca se leen.

  5. Una línea personal, un ritmo personal

    Las tarifas de consumo se venden para uso entre personas, y tus respuestas cuentan en tu tarifa. Para miles de SMS entrantes por hora o un número corto, usa un proveedor A2P.

FAQ

Preguntas sobre los webhooks SMS

Ilian, ingeniero de software senior

Escrito por

· Ingeniero de software senior

Ingeniero de software senior, funda y dirige varias empresas tecnológicas. Diseña productos en torno a las API de mensajería, la automatización y la integración de la IA, y comparte aquí lo que aprende construyendo.

Ver el perfil de LinkedInActualizado el

Tu propio número, conectado a tu código.

Crea una cuenta, instala la app Android gratis y activa los webhooks con Medium o Max. Enviar SMS sigue siendo gratis en todos los planes.