Enviar SMS

Uma API para cada texto que envia.

Configure em:
Cursor

Envie uma mensagem ou cem através da mesma API de SMS. O SDK conta os segmentos antes do envio, escolhe GSM-7 ou Unicode por si, e cada envio é idempotente com um webhook em cada estado de entrega.

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

Envie o seu primeiro SMS em cinco minutos.

A partir da linguagem que já usa.

O envio é o núcleo da API de SMS da Bird. O primeiro envio vai para um destinatário de teste autorizado (+15005550006), por isso pode publicar uma verificação de CI e ligar os webhooks antes de aprovisionar um número.

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();

Cinco coisas que não constrói você mesmo.

O mesmo contrato em cada canal da Bird.

  1. 01

    Contagem de segmentos antes do envio.

    O SDK mede o comprimento codificado e diz-lhe quantos segmentos uma mensagem custa, para que um caractere perdido nunca divida silenciosamente um texto em três.

  2. 02

    GSM-7 e Unicode, decididos por si.

    Texto simples viaja em GSM-7; um emoji ou alfabeto não latino vira toda a mensagem para UCS-2. A Bird escolhe a codificação e avisa-o quando um único caractere muda o custo.

  3. 03

    Agrupe numa chamada.

    Envie muitas mensagens independentes num pedido, cada uma com o seu destinatário e texto, validadas como uma unidade para que nunca envie pela metade.

  4. 04

    Idempotente por contrato.

    Cada envio aceita uma chave de idempotência, por isso um pedido repetido após um timeout devolve o resultado original em vez de enviar mensagem a alguém duas vezes.

  5. 05

    Um webhook em cada mudança de estado.

    Em fila, enviada, entregue, falhada. Cada uma assinada com HMAC, protegida contra repetição, idempotente, o mesmo envelope em cada canal.

Já envia noutro lado? Troque o cliente, mantenha a chamada.

A forma quase não muda: troque o cliente, mantenha o seu from, to e text, aponte os seus webhooks para um endpoint. O mesmo modelo de autenticação que os seus envios de email, voz 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.",
});

Conheça o custo antes do operador.

Uma mensagem GSM-7 cabe em 160 caracteres por segmento; um único emoji ou caractere não latino vira toda a mensagem para UCS-2 e baixa isso para 70. O SDK reporta a codificação e a contagem de segmentos em cada envio, por isso a faturação nunca é uma surpresa e uma mensagem concatenada é sempre uma escolha deliberada.

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

Uma mensagem ou cem, uma chamada.

Agrupe mensagens independentes num pedido, cada uma com o seu destinatário e texto. O lote valida-se como uma unidade: um número errado rejeita a chamada com um 422, por isso nunca envia pela metade. Uma única chave de idempotência torna todo o pedido seguro para repetir.

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`);

Acompanhe cada mensagem ao longo de toda a sua vida.

Um envio devolve 202 de imediato; o resultado chega como webhook. Verifique uma assinatura, ramifique conforme o tipo: o mesmo envelope que já trata para email, voz 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 });
}

Os envios falhados e as respostas STOP atualizam automaticamente a sua lista de supressão, para que um número errado nunca lhe custe duas vezes.

  • sms.queuedAceite pela API e em fila para a entrega ao operador.
  • sms.sentSubmetida ao SMSC do operador de destino.
  • sms.deliveredRecibo de entrega recebido do operador (DLR).
  • sms.failedFalha permanente — rejeição do operador, número inválido ou supressão atingida.

Aprofunde na documentação.

Ligue os webhooks, torne cada envio seguro para repetir com chaves de idempotência, e leia a referência de erros para tratar cada falha da forma certa.

Perguntas frequentes sobre envio de SMS

Que comprimento pode ter um SMS?+
Uma mensagem GSM-7 cabe em 160 caracteres por segmento; mudar para Unicode (UCS-2) para emoji ou alfabetos não latinos baixa isso para 70. Mensagens mais longas são concatenadas em vários segmentos, e o SDK reporta a contagem antes de enviar.
Posso enviar para muitos destinatários num único pedido?+
Sim. Agrupe mensagens independentes numa única chamada, cada uma com o seu destinatário e texto. O lote valida-se como uma unidade, e uma chave de idempotência cobre todo o pedido.
O que acontece se repetir um envio após um timeout?+
Passe uma chave de idempotência e um pedido repetido devolve o resultado original em vez de enviar duas vezes. Sem ela, uma repetição é tratada como uma nova mensagem.
Como sei se uma mensagem foi entregue?+
Cada mudança de estado dispara um webhook assinado com HMAC — em fila, enviada, entregue ou falhada — transportando o recibo de entrega do operador e a contagem de segmentos.

Cerca de 40% do SMS comercial do mundo já corre na Bird.

O envio é uma das capacidades da API de SMS da Bird: números, receção bidirecional, conformidade, encaminhamento e analítica vêm incluídos, sobre infraestrutura que operamos há uma década.

Comece com um canal.
Adicione os outros quando estiver pronto.

Uma chave API de teste é sua imediatamente. A produção é desbloqueada quando você adiciona um método de pagamento e verifica um remetente.

Usa Claude Code, Cursor ou Codex? Copie um prompt de configuração e o seu agente instala o Bird CLI e as skills por si. Escolha o seu:

Cursor