Invia SMS

Un'unica API per ogni messaggio che invii.

Configurazione in:
Cursor

Invia un messaggio o un centinaio attraverso la stessa API SMS. L'SDK conta i segmenti prima dell'invio, sceglie GSM-7 o Unicode per te e ogni invio è idempotente con un webhook a ogni stato di consegna.

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

Invia il tuo primo SMS in cinque minuti.

Dal linguaggio che già usi.

L'invio è il cuore dell'API SMS di Bird. Il primo invio va a un destinatario di test autorizzato (+15005550006), così puoi rilasciare un controllo CI e configurare i webhook prima di provisionare un numero.

1
2
3
4
5
6
7
8
9
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: "Hello from Node.",
}).safe();

Cinque cose che non costruisci tu stesso.

Lo stesso contratto su ogni canale di Bird.

  1. 01

    Conteggio dei segmenti prima dell'invio.

    L'SDK misura la lunghezza codificata e ti dice quanti segmenti costa un messaggio, così un carattere di troppo non divide mai silenziosamente un messaggio in tre.

  2. 02

    GSM-7 e Unicode, decisi per te.

    Il testo semplice viaggia su GSM-7; un'emoji o un alfabeto non latino fa passare l'intero messaggio a UCS-2. Bird sceglie la codifica e ti avvisa quando un singolo carattere cambia il costo.

  3. 03

    Batch in un'unica chiamata.

    Invia molti messaggi indipendenti in un'unica richiesta, ciascuno con il proprio destinatario e testo, validati come un'unità così non invii mai a metà.

  4. 04

    Idempotente per contratto.

    Ogni invio accetta un'idempotency key, così una richiesta ritentata dopo un timeout restituisce il risultato originale invece di inviare un SMS a qualcuno due volte.

  5. 05

    Un webhook a ogni cambio di stato.

    In coda, inviato, consegnato, fallito. Ognuno firmato con HMAC, protetto da replay, idempotente, lo stesso envelope su ogni canale.

Invii già da un'altra parte? Cambia il client, mantieni la chiamata.

La forma cambia a malapena: sostituisci il client, mantieni il tuo from, to e text, indirizza i tuoi webhook verso un unico endpoint. Lo stesso modello di auth dei tuoi invii email, voce e WhatsApp.

twilio.ts
Twilio
import twilio from "twilio";

const client = twilio(accountSid, authToken);

await client.messages.create({
  from: "+14155550172",
  to:   "+15005550006",
  body: "Your code is 123456.",
});
bird.ts
Bird
import { BirdClient } from "@messagebird/sdk";

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

await bird.sms.send({
  from: "Bird",
  to:   "+15005550006",
  text: "Your code is 123456.",
});

Conosci il costo prima del carrier.

Un messaggio GSM-7 sta in 160 caratteri per segmento; un singolo carattere emoji o non latino fa passare l'intero messaggio a UCS-2 e abbassa quel limite a 70. L'SDK riporta la codifica e il numero di segmenti a ogni invio, così la fatturazione non è mai una sorpresa e un messaggio concatenato è sempre una scelta deliberata.

segments.ts
200 · 1 segment
const { data } = await bird.sms.send({
  from: "Bird",
  to:   "+15005550006",
  text: "Your code is 123456.",
}).safe();

console.log(data.encoding); // → "GSM-7"
console.log(data.segments); // → 1

Un messaggio o un centinaio, un'unica chiamata.

Raggruppa messaggi indipendenti in un'unica richiesta, ciascuno con il proprio destinatario e testo. Il batch viene validato come un'unità: un singolo numero errato rifiuta la chiamata con un 422, così non invii mai a metà. Un'unica idempotency key rende l'intera richiesta sicura da ritentare.

reminders.ts
202 · batch
const { data: batch, error } = await bird.sms
  .sendBatch(
    users.map((u) => ({
      from: "Bird",
      to:   u.phone,
      text: `Hi ${u.name}, your appointment is tomorrow at ${u.time}.`,
    })),
    { idempotencyKey: `reminders-${runId}` },
  )
  .safe();

if (error) throw error;
console.log(`queued ${batch.data.length} messages`);

Osserva ogni messaggio per tutta la sua vita.

Un invio restituisce subito 202; l'esito arriva come webhook. Verifica un'unica firma, fai lo switch sul type: lo stesso envelope che già gestisci per email, voce e WhatsApp.

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.delivered":
      await markDelivered(event.data.sms_id);
      break;
    case "sms.failed":
      await flag(event.data.to, event.data.reason);
      break;
  }

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

Gli invii falliti e le risposte STOP aggiornano automaticamente la tua lista di soppressione, così un numero errato non ti costa mai due volte.

  • sms.queuedAccettato dall'API e messo in coda per la consegna al carrier.
  • sms.sentSottoposto all'SMSC del carrier di destinazione.
  • sms.deliveredRicevuta di consegna ricevuta dal carrier (DLR).
  • sms.failedFallimento permanente — rifiuto del carrier, numero non valido o soppressione.

Approfondisci nella documentazione.

Configura i webhook, rendi ogni invio sicuro da ritentare con le idempotency key e leggi il riferimento agli errori così gestisci ogni fallimento nel modo giusto.

FAQ sull'invio SMS

Quanto può essere lungo un SMS?+
Un messaggio GSM-7 sta in 160 caratteri per segmento; passando a Unicode (UCS-2) per emoji o alfabeti non latini si scende a 70. I messaggi più lunghi vengono concatenati su più segmenti e l'SDK riporta il conteggio prima dell'invio.
Posso inviare a molti destinatari in un'unica richiesta?+
Sì. Raggruppa messaggi indipendenti in un'unica chiamata, ciascuno con il proprio destinatario e testo. Il batch viene validato come un'unità e un'unica idempotency key copre l'intera richiesta.
Cosa succede se ritento un invio dopo un timeout?+
Passa un'idempotency key e una richiesta ritentata restituisce il risultato originale invece di inviare due volte. Senza, un retry viene trattato come un nuovo messaggio.
Come faccio a sapere se un messaggio è stato consegnato?+
Ogni cambio di stato attiva un webhook firmato con HMAC — in coda, inviato, consegnato o fallito — che trasporta la ricevuta di consegna del carrier e il numero di segmenti.

Circa il 40% degli SMS commerciali del mondo passa già su Bird.

L'invio è una delle funzionalità dell'API SMS di Bird: numeri, bidirezionale in entrata, conformità, routing e analisi arrivano insieme a esso, su un'infrastruttura che gestiamo da un decennio.

Inizia con un canale.
Aggiungi gli altri quando sei pronto.

Una chiave API di test è subito tua. La produzione si sblocca quando aggiungi un metodo di pagamento e verifichi un mittente.

Usi Claude Code, Cursor o Codex? Copia un prompt di configurazione e il tuo agente installerà la CLI e le skill di Bird per te. Scegli il tuo:

Cursor