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-notification.ts
202 · 0.4s
import { BirdClient } from "@messagebird/sdk";

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

const { data, error } = await bird.sms.send({
  from:     "Bird",
  to:       "+15005550006",
  text:     "Your order #4821 has shipped. Track it: bird.ly/t/4821x",
  category: "transactional",
}).safe();

if (error) throw error;
console.log(data.id);
// → "sms_4kT01Lq2m..."
Hi Ada, reminder of your appointment tomorrow at 14:30 with Dr. Kowalski.
Your order #4821 has shipped. Track it: bird.ly/t/4821x
Your subscription renews on 3 Sep for €12/mo. Manage it here: bird.ly/account

Lo entrante es solo otro webhook.

La comunicación bidireccional forma parte de la API de SMS de Bird. Cuando alguien envía un mensaje a tu número, recibes un evento sms.received en el mismo endpoint firmado y protegido contra repeticiones que ya transporta tus acuses de entrega. No hay una segunda integración ni polling: verifica la firma una vez y actúa 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 llegó a tu número: incluye 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.",
      category: "transactional",
    }).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.

Los mensajes entrantes requieren un número compatible con comunicación bidireccional: los códigos largos, códigos cortos y números gratuitos pueden recibir; los identificadores alfanuméricos de remitente no. Para interacciones más completas en el mismo dispositivo (indicadores de escritura, acuses de lectura, carruseles), RCS mejora la conversación en los dispositivos compatibles.

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.

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