Bidireccional

Los SMS vuelven. Así que gestiónalos.

Configúralo en:
Cursor

Cada mensaje que alguien envía a tu número aprovisionado llega como un webhook firmado con HMAC. Lee el texto, responde desde el mismo número y deja que Bird gestione STOP y HELP por ti. Construye flujos conversacionales y autorrespuestas sobre la API con la que ya envías.

send-otp.ts
200 · 0.4s
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const code = generateOtp();

const { data, error } = await bird.sms.send({
  from: "Bird",
  to:   "+15005550006",
  text: `Your Bird verification code is ${code}. Reply STOP to opt out.`,
}).safe();

if (error) throw error;
console.log(data.id);
// → "sms_4kT01Lq2m..."

Today at 2:14 PM

Hey Ada — your Bird sign-in code is 482917. It'll expire in 10 minutes. Don't share it with anyone.
482917
Delivered

Lo entrante es solo otro webhook.

El bidireccional forma parte de la API de SMS de Bird. Cuando alguien envía un SMS a tu número, recibes un evento sms.received en el mismo endpoint firmado y protegido contra repetición que ya lleva tus acuses de recibo. No hay una segunda integración ni sondeo — verifica la firma una vez y conmuta según el tipo.

Escucha lo que vuelve.

Un mensaje entrante y una cancelación son eventos, igual que un acuse de recibo. Verifica una firma, conmuta según el tipo y gestiona cada uno en el handler que ya escribiste.

app/api/webhooks/bird/route.ts
signed
import { bird } from "@/lib/bird";

export async function POST(req: Request) {
  const event = bird.webhooks.unwrap(
    await req.text(),
    Object.fromEntries(req.headers),
  );

  switch (event.type) {
    case "sms.received":
      await handleInbound(event.data.from, event.data.text);
      break;
    case "sms.opted_out":
      await removeFromCampaigns(event.data.from);
      break;
  }

  return new Response(null, { status: 204 });
}

La carga útil es el mismo sobre en cada canal de Bird: un evt_ id, una firma HMAC y una marca de tiempo protegida contra repetición.

  • sms.receivedUn mensaje entrante aterrizó en tu número — lleva el remitente, tu número y el texto.
  • sms.deliveredUna respuesta que enviaste llegó al dispositivo (DLR del operador).
  • sms.opted_outEl remitente envió STOP — Bird lo suprimió y bloquea los envíos futuros.

Un mensaje entrante firmado, completo.

Así es como se ve un evento sms.received en la red. El from es quien te escribió, el to es tu número aprovisionado, y los segmentos y la codificación se informan igual que en un envío, así que una respuesta entrante larga nunca es una sorpresa.

sms.received
evt_
{
  "id": "evt_7nQ9xLp2aR...",
  "type": "sms.received",
  "created_at": "2026-06-26T14:03:11Z",
  "data": {
    "id": "sms_5hV02Mr3n...",
    "from": "+15005550006",
    "to": "+14155550172",
    "text": "YES book me in for Thursday",
    "encoding": "GSM-7",
    "segments": 1
  }
}

Responde desde el mismo número.

Una respuesta es un envío con from y to intercambiados. Pon from a tu número y to al remitente original, y la conversación se mantiene en un solo número, así que el destinatario ve un hilo en lugar de un remitente nuevo cada vez. Construye encima autorrespuestas, confirmaciones o un flujo conversacional completo.

reply.ts
200 · reply
async function handleInbound(from: string, text: string) {
  if (/^yes\b/i.test(text)) {
    const { error } = await bird.sms.send({
      from: "+14155550172", // your two-way number
      to:   from,           // reply to the sender
      text: "Booked. See you Thursday at 10am.",
    }).safe();

    if (error) throw error;
  }
}

STOP, HELP y START los gestionamos por ti.

Bird reconoce las palabras clave reservadas antes de que lleguen a tu handler: STOP añade al remitente a tu lista de supresión y emite sms.opted_out, HELP devuelve una respuesta de ayuda automática y START vuelve a suscribirlo. Los envíos posteriores a un número suprimido se bloquean automáticamente. Puedes seguir usando tus propias palabras clave para YES, BOOK o lo que tu flujo necesite. Las reglas completas de palabras clave y de exclusión están en gestión de exclusión.

Dos cosas que querrás a continuación.

Lo entrante necesita un número con capacidad bidireccional — los long codes, short codes y toll-free pueden recibir, los IDs de remitente alfanuméricos no. Para un ida y vuelta más rico en el mismo dispositivo (indicadores de escritura, acuses de lectura, carruseles), RCS mejora la conversación allí donde el dispositivo lo admite.

Profundiza en la documentación.

Conecta webhooks para los eventos entrantes, lee la referencia de errores para los fallos que gestionarás, y consulta abuso y cumplimiento para las reglas de palabras clave y consentimiento.

Preguntas frecuentes sobre SMS bidireccional

¿Cómo llega un SMS entrante a mi aplicación?+
Cada mensaje enviado a tu número aprovisionado llega como un webhook sms.received firmado con HMAC. Verificas una firma, lees el from, el to y el text, y lo enrutas hacia tu propia lógica — el mismo sobre que ya gestionas para los acuses de recibo.
¿Puedo responder a un mensaje entrante?+
Sí. Responde enviando desde el mismo número por el que entró el mensaje. Pon from a tu número y to al remitente original, y el hilo se mantiene en un solo número de extremo a extremo.
¿Qué ocurre cuando alguien envía STOP?+
Bird añade al remitente a tu lista de supresión, emite sms.opted_out y bloquea automáticamente los envíos posteriores a ese número. HELP devuelve una respuesta de ayuda y START vuelve a suscribirlo, todo gestionado antes de que llegue a tu código, para que cumplas la normativa sin escribir tú la lógica de palabras clave.
¿Necesito un número especial para el bidireccional?+
Necesitas un número con capacidad bidireccional. Los long codes, short codes y números toll-free admiten entrantes; los IDs de remitente alfanuméricos son solo de envío y no pueden recibir respuestas.

Envía y recibe en un solo número, una sola API.

La recepción bidireccional es una capacidad de la API de SMS de Bird: el envío, los números, el cumplimiento, el enrutamiento y la analítica vienen con ella, sobre una infraestructura que llevamos una década operando.

Empieza con un canal.
Añade los demás cuando estés listo.

Una clave API de prueba es tuya de inmediato. El acceso a producción se desbloquea cuando añades un método de pago y verificas un remitente.

¿Usas Claude Code, Cursor o Codex? Copia un prompt de configuración y tu agente instalará el Bird CLI y las habilidades por ti. Elige el tuyo:

Cursor