Enviar SMS
Una API para cada SMS que envías.
Envía un mensaje o cien a través de la misma API de SMS. El SDK cuenta los segmentos antes del envío, elige GSM-7 o Unicode por ti, y cada envío es idempotente con un webhook en cada estado de entrega.
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
Envía tu primer SMS en cinco minutos.
Desde el lenguaje que ya usas.
El envío es el núcleo de la API de SMS de Bird. El primer envío va a un destinatario de prueba autorizado (+15005550006), así que puedes desplegar una comprobación de CI y conectar webhooks antes de aprovisionar un número.
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 cosas que no construyes tú mismo.
El mismo contrato en cada canal de Bird.
- 01
Recuento de segmentos antes del envío.
El SDK mide la longitud codificada y te dice cuántos segmentos cuesta un mensaje, así que un carácter perdido nunca divide en silencio un SMS en tres.
- 02
GSM-7 y Unicode, decididos por ti.
El texto plano viaja en GSM-7; un emoji o un alfabeto no latino convierte todo el mensaje a UCS-2. Bird elige la codificación y te avisa cuando un solo carácter cambia el coste.
- 03
Agrupa en una sola llamada.
Envía muchos mensajes independientes en una petición, cada uno con su propio destinatario y texto, validados como una unidad para que nunca envíes a medias.
- 04
Idempotente por contrato.
Cada envío acepta una clave de idempotencia, así que una petición reintentada tras un timeout devuelve el resultado original en lugar de mandar un SMS a alguien dos veces.
- 05
Un webhook en cada cambio de estado.
En cola, enviado, entregado, fallido. Cada uno firmado con HMAC, protegido contra repetición, idempotente, el mismo sobre en cada canal.
¿Ya envías desde otro sitio? Cambia el cliente, conserva la llamada.
La forma apenas cambia: cambia el cliente, conserva tu from, to y text, apunta tus webhooks a un solo endpoint. El mismo modelo de autenticación que tus envíos de email, voz y WhatsApp.
import twilio from "twilio";
const client = twilio(accountSid, authToken);
await client.messages.create({
from: "+14155550172",
to: "+15005550006",
body: "Your code is 123456.",
});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.",
});Conoce el coste antes que el operador.
Un mensaje GSM-7 cabe en 160 caracteres por segmento; un solo emoji o carácter no latino convierte todo el mensaje a UCS-2 y lo reduce a 70. El SDK informa de la codificación y el recuento de segmentos en cada envío, así que la facturación nunca es una sorpresa y un mensaje concatenado siempre es una decisión deliberada.
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); // → 1Un mensaje o cien, una llamada.
Agrupa mensajes independientes en una petición, cada uno con su propio destinatario y texto. El lote se valida como una unidad: un número incorrecto rechaza la llamada con un 422, así que nunca envías a medias. Una sola clave de idempotencia hace que toda la petición sea segura de reintentar.
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`);Sigue cada mensaje durante toda su vida.
Un envío devuelve 202 de inmediato; el resultado llega como webhook. Verifica una firma, conmuta según el tipo: el mismo sobre que ya gestionas para email, voz y WhatsApp.
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 });
}Los envíos fallidos y las respuestas STOP actualizan tu lista de supresión automáticamente, así que un número incorrecto nunca te cuesta dos veces.
sms.queuedAceptado por la API y en cola para la entrega al operador.sms.sentEnviado al SMSC del operador de destino.sms.deliveredAcuse de recibo recibido del operador (DLR).sms.failedFallo permanente — rechazo del operador, número no válido o supresión activada.
Profundiza en la documentación.
Conecta webhooks, haz que cada envío sea seguro de reintentar con claves de idempotencia, y lee la referencia de errores para gestionar cada fallo de la forma correcta.
Preguntas frecuentes sobre el envío de SMS
¿Cuánto puede medir un SMS?+
¿Puedo enviar a muchos destinatarios en una sola petición?+
¿Qué ocurre si reintento un envío tras un timeout?+
¿Cómo sé si un mensaje se entregó?+
El resto de la plataforma de SMS
Una API, un solo conjunto de claves. Explora las demás capacidades.
Alrededor del 40 % del SMS comercial del mundo ya circula por Bird.
El envío es una capacidad de la API de SMS de Bird: los números, la recepción bidireccional, el cumplimiento, el enrutamiento y la analítica vienen con ella, sobre una infraestructura que llevamos una década operando.