Sign inGet Started

Envio de SMS

Este guia trata do endpoint de envio único, POST /v1/sms/messages. Monte um payload JSON com destinatário, remetente, corpo e categoria. O Bird retorna 202 Accepted com um ID de mensagem e faz a entrega de forma assíncrona. Cada solicitação envia uma mensagem para um destinatário. Para enviar muitas mensagens de uma vez, use o envio em lote. Para enviar um modelo em vez do seu próprio texto, informe um objeto template no lugar de text e category. Os modelos integrados rejeitam from; os modelos do espaço de trabalho exigem esse campo.

Antes de enviar: habilite o país de destino

Seu espaço de trabalho envia SMS apenas para os países da sua lista de destinos permitidos. O país de origem da sua organização é o país do endereço de registro no perfil comercial ou, se esse endereço não tiver país, o do endereço de cobrança. Seu espaço de trabalho começa com a lista de permitidos vazia. Sempre que o país de origem é definido ou alterado, o Bird adiciona esse país à lista. O Bird rejeita um envio para um país fora da lista com 422 SMSDestinationNotEnabled antes de resolver o remetente. Habilite os países que você atende em SMS > Destinations no painel.

Na mesma página, você pode definir um limite diário de gastos para cada país, na moeda da sua carteira. Para definir um limite, é preciso ter uma carteira da organização e permissão para consultá-la; para removê-lo, não. O limite vale com o país habilitado ou não. Quando o gasto do dia com esse país atinge o limite, o Bird recusa novas mensagens para lá com 422 SMSDestinationDailySpendExceeded até a meia-noite UTC. As mensagens de verificação também são recusadas. O gasto é contabilizado quando a mensagem é cobrada, então mensagens já aceitas podem ultrapassar o limite no valor que custam. Uma alteração de limite leva até um minuto para valer nos envios.

Um envio mínimo

O menor payload de texto livre válido tem um destinatário to, um remetente from, um corpo text e um category.

const msg = await bird.sms.send({
  from: "+15557654321",
  to: "+14155550100",
  text: "Your verification code is 123456.",
  category: "authentication",
});
console.log(msg.id, msg.status);

Use o host da sua região (https://us1.platform.bird.com ou https://eu1.platform.bird.com) com uma chave bk_{region}_... correspondente. A resposta é a mensagem aceita:

Exemplo de código
{
  "id": "sms_01ky7qmwgpfkybj9ecrnwjx714",
  "direction": "outbound",
  "status": "accepted",
  "to": "+31612345678",
  "from": "Bird",
  "text": "Your Bird verification code is 481920. It expires in 10 minutes.",
  "category": "authentication",
  "segments": { "count": 1, "encoding": "GSM_7BIT", "characters": 64 },
  "cost": null,
  "carrier": null,
  "mcc_mnc": null,
  "sent_at": null,
  "delivered_at": null,
  "created_at": "2026-07-23T14:56:34.326Z"
}

status: accepted significa que o Bird recebeu a mensagem e está processando-a; cost é null porque o preço é calculado durante o processamento. O que acontece em seguida está descrito em o modelo assíncrono.

Montagem do payload

Destinatário

to é um destinatário no formato E.164: um + inicial, o código do país e o número do assinante, como +31612345678. Cada mensagem vai para um destinatário, sem cc, bcc nem array de destinatários. Para alcançar muitas pessoas, envie um lote.

Remetente

from é o remetente que o destinatário vê. Ele é obrigatório em um envio de texto livre, a menos que messaging_profile_id indique um perfil de mensagens com um remetente para o país de destino ou um remetente padrão. Ele aceita um de dois formatos, e quais funcionam depende do país de destino:

  • Um ID de remetente alfanumérico: de 3 a 11 letras, dígitos, espaços, hifens, sublinhados ou pontos, com pelo menos uma letra e sem separador em nenhuma das pontas, como Bird ou Acme-Co. Ele precisa conter uma letra, por isso uma sequência de dígitos com pontuação, como 555 555, é rejeitada. Alguns países exigem registro, e outros, incluindo os EUA, não aceitam remetentes alfanuméricos. Os destinatários não conseguem responder a eles.
  • Um número do seu espaço de trabalho, em E.164 ou só com dígitos. Qualquer from composto só de dígitos é lido como numérico e procurado entre os seus remetentes, por isso um número qualquer que não seja seu é rejeitado. Se ele funciona como long code, número gratuito ou short code depende do próprio número, não de quantos dígitos você escreveu. Um from de 6 dígitos não é short code por ter 6 dígitos; ele é short code se o número que você possui for um.

Um remetente que não é válido para o destino é rejeitado com um 422 que informa o motivo (por exemplo, SMSAlphaNotSupported onde remetentes alfanuméricos não estão disponíveis). Em um envio de template integrado, from não é aceito: Bird escolhe um remetente de acordo com o destino e a categoria. Um template do espaço de trabalho exige o seu próprio remetente from ou um perfil de mensagens que forneça um.

Como reivindicar um ID de remetente, consultar o que cada país exige dele e registrá-lo por país está em IDs de remetente SMS.

Para manter os remetentes e os padrões de um programa em um só lugar, crie um perfil de mensagens e indique-o em messaging_profile_id. Quando from é omitido, Bird envia pelo remetente do perfil para o país de destino ou pelo remetente padrão dele. Um category omitido assume a categoria padrão do perfil, e options.smart_encoding, cost_center, validity_period e options.callback_url assumem as configurações do perfil. Os valores definidos na mensagem têm prioridade.

Corpo e categoria

text é o corpo da mensagem, com pelo menos um caractere. Ele é cobrado e entregue em segmentos; um envio tem limite de 12 segmentos (cerca de 1.836 caracteres GSM-7, ou 804 se o corpo usar a codificação estendida UCS-2). Um corpo acima do limite é rejeitado com um 422, em vez de ser truncado.

category é obrigatório em um envio de texto livre, a menos que o perfil de mensagens em messaging_profile_id defina uma categoria padrão. Ele classifica a mensagem como transactional, marketing, authentication ou service, o que informa à Bird e às operadoras por que você está enviando. Um código de verificação de uso único usa authentication; uma promoção usa marketing. Escolha a categoria que corresponde à finalidade da mensagem.

Tags e metadados

Esses campos anexam seus próprios dados a um envio, mas cada um tem uma função diferente:

  • tags são pares {name, value} estruturados (máximo de 20 por envio; nome de 1 a 32 caracteres, valor de 1 a 64, somente ASCII [A-Za-z0-9_-], com distinção entre maiúsculas e minúsculas, e nomes únicos dentro de um envio). Eles são dimensões de filtro nativas: filtre a lista de mensagens por tag. Use-os para rótulos de baixa cardinalidade, como campaign ou experiment_variant.
  • metadata é um objeto JSON arbitrário (máximo de 2 KB serializado). Ele é armazenado, retornado nas leituras de API e repetido em todo evento de webhook, mas não é uma dimensão de filtro. Use-o para contexto de ida e volta: IDs internos, chaves estrangeiras e qualquer dado que você queira receber de volta com cada evento.
  • reference é uma string de 1 a 255 caracteres pela qual você quer encontrar a mensagem, como um número de pedido ou de chamado. ?reference= na lista de mensagens corresponde a ela exatamente, com distinção entre maiúsculas e minúsculas, e várias mensagens podem compartilhar o mesmo valor. Ela é retornada nas leituras e repetida em todo evento de webhook. Defina-a somente quando precisar pesquisar por ela e coloque os demais dados em metadata.
Exemplo de código
{
  "tags": [{ "name": "campaign", "value": "spring-2026" }],
  "metadata": { "user_id": "usr_12345", "order_id": "ord_98765" },
  "reference": "ord_98765"
}

Referência de campos

CampoTipoObrigatórioLimites / observações
tostring (E.164)simUm destinatário por mensagem
fromstringsim*Número E.164 próprio, sender ID alfanumérico (3–11 caracteres, com pelo menos uma letra) ou short code (5–6 dígitos)
textstringsim*Pelo menos 1 caractere; limitado a 12 segmentos
categorystringsim*transactional, marketing, authentication ou service
templateobjetosim*{slug, parameters?, language?} para um modelo integrado ou do espaço de trabalho
tags{name, value}[]nãoMáx. 20; nome com 1–32 caracteres, valor com 1–64 caracteres; somente [A-Za-z0-9_-]
metadataobjetonãoJSON arbitrário, máximo de 2 KB serializado
referencestringnão1–255 caracteres; correspondência exata para ?reference= na lista de mensagens
messaging_profile_idstringnãoUm perfil de mensagens que fornece o remetente e os padrões; os valores definidos na mensagem têm precedência
validity_periodintegernão60 a 172800 segundos a partir da aceitação; omita para usar o valor do perfil de mensagens ou as regras da própria operadora
optionsobjetonãoConfigurações de processamento por mensagem, como smart_encoding (consulte segmentos e codificação) e callback_url (consulte URLs de callback)

* Envios de texto livre exigem from, text e category, exceto que um perfil de mensagens pode fornecer from e category. Envios com template exigem template em vez de text e category (e rejeitam ambos). Templates integrados rejeitam from; templates do espaço de trabalho o exigem.

Enviar com um template

Defina template para enviar um template integrado ou um template publicado do espaço de trabalho. A criação de templates do espaço de trabalho está em prévia no API. O catálogo, as variáveis e as regras de remetente estão em Templates de SMS.

Segmentos e codificação

O SMS é cobrado por segmento. Uma mensagem que cabe na codificação GSM-7 tem 160 caracteres em um único segmento; com UCS-2 (acionada por emoji, caracteres CJK ou outros caracteres fora do GSM), o limite cai para 70. Mensagens mais longas são divididas em vários segmentos, com limites um pouco menores por segmento. Toda resposta informa o segments resolvido: o count cobrável, o encoding e a contagem de caracteres. Os segmentos são a unidade de cobrança; consulte custo.

Quando caracteres tipográficos são o único motivo para um corpo ficar fora do GSM-7, a codificação inteligente pode reduzir a quantidade de segmentos. Defina options.smart_encoding como true e o Bird substitui aspas curvas, travessões, reticências e caracteres semelhantes por equivalentes em GSM-7 antes do envio. Ela vem desativada por padrão porque altera o corpo que você escreveu.

Para conhecer o conjunto completo de caracteres, os caracteres da tabela de extensão que ocupam duas posições, o tamanho dos emojis, o que a codificação inteligente substitui e o cálculo de segmentos, consulte Limites de caracteres.

Envio em lote

POST /v1/sms/batches envia até 100 mensagens independentes em uma única solicitação, no padrão de envio em massa de SMS com uma chamada API para muitos destinatários. As solicitações em lote usam a política de limite de taxa sms_batch, separada da política sms_send para envios individuais. O corpo é um objeto JSON cujo array messages contém os objetos de mensagem descritos em Montando o payload:

const result = await bird.sms.sendBatch({
  messages: [
    {
      from: "+15557654321",
      to: "+15551111111",
      text: "Hi Alice!",
      category: "marketing",
    },
    {
      from: "+15557654321",
      to: "+15552222222",
      text: "Hi Bob!",
      category: "marketing",
    },
  ],
});

A validação é tudo ou nada: se qualquer mensagem do lote for inválida, a solicitação inteira é rejeitada com 422 e nada é enviado, então um lote nunca é aplicado parcialmente. Em caso de sucesso, a resposta 202 traz cada mensagem aceita na ordem de envio em data, além de um summary com o accepted_count. A partir daí, cada mensagem é independente: a falha de um destinatário nunca afeta os demais.

O modelo assíncrono: o que significa o 202

Um envio bem-sucedido retorna 202 Accepted com um ID de mensagem e status: accepted. Falhas na solicitação retornam imediatamente: um campo inválido, um corpo acima do limite de segmentos, um país de destino que você não ativou ou um remetente inválido retornam 422. Um espaço de trabalho sem saldo na carteira recebe 402.

A entrega acontece de forma assíncrona. A mensagem passa para sent quando Bird a entrega à operadora. Em seguida, um recibo de entrega define delivered, undelivered, failed ou expired por meio de eventos e webhooks e dos endpoints de leitura. Esse design tem três consequências:

  • O custo é calculado depois da aceitação. O cost de uma mensagem é null no momento da aceitação e é preenchido quando Bird calcula o preço do envio durante o processamento. Leia a mensagem novamente ou aguarde o evento de entrega para ver a cobrança calculada até o momento; custo e cobrança explica os componentes e quando um deles fica sem preço.
  • Uma mensagem pode ser rejeitada depois do 202. Se a cobrança falhar durante o processamento, a mensagem termina como rejected com um webhook sms.rejected e você não é cobrado; uma carteira sem saldo aparece como last_error.code: insufficient_balance.
  • As leituras podem ficar brevemente atrás do 202. A mensagem fica visível nos endpoints de leitura pouco depois do 202, então um 404 logo após um envio se resolve em instantes.

Campos reservados

Bird rejeita os seguintes campos de solicitação com 422 SMSUnsupportedFeature:

scheduled_at, media_urls, broadcast_id, campaign_id, audience_id, contact_id, topic_id, personalization, options.max_price_per_segment, options.track_clicks (quando true)

Não inclua esses campos em um envio.

Como tentar novamente com segurança

Envie o cabeçalho Idempotency-Key com um valor único para cada envio lógico. Se uma solicitação for bem-sucedida sem retornar resposta, repita a mesma solicitação com a mesma chave. A Bird retorna o resultado original em vez de enviar uma mensagem duplicada. Consulte idempotência para ver o formato da chave e o período de retenção.

Custo e cobrança

O SMS de saída é cobrado por segmento. O valor depende do país de destino e da operadora. Algumas rotas acrescentam uma sobretaxa de terceiros, como as taxas de operadora do 10DLC nos EUA.

O cost de uma mensagem divide a cobrança em componentes nomeados. transaction_amount é o que a Bird cobrou para transportar a mensagem, passthrough_amount é qualquer taxa de terceiros repassada e amount é a soma dos componentes já precificados, expressa em currency_code. Um componente ainda não precificado fica como null em vez de "0.00000". Assim, uma mensagem cuja sobretaxa nunca foi resolvida informa em amount apenas a cobrança de transporte. A referência de mensagens documenta cada campo.

A sobretaxa é calculada sem garantia. A Bird a resolve ao registrar o recibo de entrega, dentro de um prazo limitado. Se ela não for resolvida nesse prazo, passthrough_amount permanece null para sempre: a Bird não tenta novamente, e amount continua igual à cobrança de transporte.

O SMS de entrada é cobrado em duas linhas: a tarifa de entrada por segmento e, quando aplicável, uma sobretaxa de operadora de entrada. As duas aparecem no próprio cost da mensagem recebida: a tarifa como transaction_amount e a sobretaxa como passthrough_amount. Ao contrário da sobretaxa de saída, a sobretaxa de entrada é precificada quando a mensagem é aceita, e não na entrega, por isso nunca é preenchida depois.

Confira o custo e os segmentos de cada mensagem no log de SMS.

Próximos passos

  • Templates de SMS: envie um template integrado e deixe a Bird escolher o remetente.
  • Log de SMS: encontre uma mensagem e examine seu ciclo de vida, seus segmentos e seu custo.
  • Eventos: receba eventos de entrega nos seus sistemas.
  • URLs de callback de SMS: envie os eventos de uma mensagem ou de um perfil para um endpoint HTTPS próprio.
  • Métricas de SMS: monitore a taxa de entrega, a taxa de falha e o volume aceito.
  • Idempotência: tente novamente com segurança usando o cabeçalho Idempotency-Key.
  • Enviar o seu primeiro SMS: um vídeo que mostra a mesma configuração passo a passo no dashboard