Bidirectionnel

Les textos reviennent. Alors gérez-les.

Mise en place en :
Cursor

Chaque message que quelqu'un envoie à votre numéro provisionné arrive sous forme de webhook signé HMAC. Lisez le texte, répondez depuis le même numéro, et laissez Bird gérer STOP et HELP à votre place. Construisez des flux conversationnels et des réponses automatiques sur l'API avec laquelle vous envoyez déjà.

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

L'entrant n'est qu'un webhook de plus.

Le bidirectionnel fait partie de l'API SMS de Bird. Lorsque quelqu'un envoie un texto à votre numéro, vous recevez un événement sms.received sur le même endpoint signé et protégé contre le rejeu qui porte déjà vos accusés de réception. Il n'y a pas de seconde intégration ni d'interrogation en boucle — vérifiez la signature une fois et branchez sur le type.

Écoutez ce qui revient.

Un message entrant et un opt-out sont des événements, au même titre qu'un accusé de réception. Vérifiez une signature, branchez sur le type, et gérez chacun dans le gestionnaire que vous avez déjà écrit.

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 charge utile est la même enveloppe sur chaque canal Bird : un id evt_, une signature HMAC et un horodatage protégé contre le rejeu.

  • sms.receivedUn message entrant a abouti sur votre numéro — il porte l'expéditeur, votre numéro et le texte.
  • sms.deliveredUne réponse que vous avez envoyée a atteint le combiné (DLR de l'opérateur).
  • sms.opted_outL'expéditeur a envoyé STOP — Bird l'a supprimé et bloque les envois futurs.

Un message entrant signé, en intégralité.

Voici à quoi ressemble un événement sms.received sur le réseau. Le from est celui qui vous a envoyé un texto, le to est votre numéro provisionné, et les segments et l'encodage sont indiqués de la même façon que sur un envoi, de sorte qu'une longue réponse entrante n'est jamais une surprise.

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
  }
}

Répondez depuis le même numéro.

Une réponse est un envoi avec from et to inversés. Définissez from sur votre numéro et to sur l'expéditeur d'origine, et la conversation reste sur un seul numéro, de sorte que le destinataire voit un fil plutôt qu'un nouvel expéditeur à chaque fois. Construisez par-dessus des réponses automatiques, des confirmations ou un flux conversationnel complet.

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 et START, nous nous en chargeons pour vous.

Bird reconnaît les mots-clés réservés avant qu'ils n'atteignent votre handler : STOP ajoute l'expéditeur à votre liste de suppression et déclenche sms.opted_out, HELP renvoie une réponse d'aide automatique et START le réabonne. Les envois ultérieurs vers un numéro supprimé sont bloqués automatiquement. Vous pouvez conserver vos propres mots-clés pour YES, BOOK ou ce dont votre flux a besoin. Les règles complètes de mots-clés et de désinscription se trouvent dans la gestion des désinscriptions.

Deux choses que vous voudrez ensuite.

L'entrant nécessite un numéro compatible bidirectionnel — les long codes, short codes et toll-free peuvent recevoir, les sender IDs alphanumériques non. Pour des échanges plus riches sur le même combiné (indicateurs de saisie, accusés de lecture, carrousels), le RCS enrichit la conversation là où l'appareil le prend en charge.

Approfondissez dans la documentation.

Câblez des webhooks pour les événements entrants, lisez la référence des erreurs pour les échecs que vous gérerez, et consultez abus et conformité pour les règles de mots-clés et de consentement.

FAQ sur le SMS bidirectionnel

Comment un SMS entrant atteint-il mon application ?+
Chaque message envoyé à votre numéro provisionné arrive sous forme de webhook sms.received signé HMAC. Vous vérifiez une signature, lisez les from, to et text, et l'acheminez vers votre propre logique — la même enveloppe que vous gérez déjà pour les accusés de réception.
Puis-je répondre à un message entrant ?+
Oui. Répondez en envoyant depuis le même numéro sur lequel le message est arrivé. Définissez from sur votre numéro et to sur l'expéditeur d'origine, et le fil reste sur un seul numéro de bout en bout.
Que se passe-t-il lorsque quelqu'un envoie STOP ?+
Bird ajoute l'expéditeur à votre liste de suppression, déclenche sms.opted_out et bloque automatiquement les envois ultérieurs vers ce numéro. HELP renvoie une réponse d'aide et START le réabonne — le tout traité avant d'atteindre votre code, pour que vous restiez conforme sans écrire vous-même la logique des mots-clés.
Ai-je besoin d'un numéro spécial pour le bidirectionnel ?+
Vous avez besoin d'un numéro compatible bidirectionnel. Les long codes, short codes et numéros toll-free prennent en charge l'entrant ; les sender IDs alphanumériques sont en envoi seul et ne peuvent pas recevoir de réponses.

Envoyez et recevez sur un seul numéro, une seule API.

L'entrant bidirectionnel est l'une des capacités de l'API SMS de Bird : l'envoi, les numéros, la conformité, le routage et l'analyse sont livrés avec lui, sur une infrastructure que nous exploitons depuis une décennie.

Commencez avec un seul canal.
Ajoutez les autres quand vous êtes prêt.

Une clé API de test est disponible immédiatement. L'accès production se débloque dès que vous ajoutez un moyen de paiement et vérifiez un expéditeur.

Vous utilisez Claude Code, Cursor ou Codex ? Copiez un prompt de configuration et votre agent installe la CLI Bird et les compétences pour vous. Choisissez le vôtre :

Cursor