Sign inGet Started

Eventos de SMS

Toda mensagem percorre um ciclo de vida, e Bird emite um evento em cada etapa. Esta página é o vocabulário completo de eventos; como os eventos são entregues ao seu endpoint (assinaturas, novas tentativas, replay) está no Guia de webhooks.
O ciclo de vida da entrega, como um caminho pelos tipos de evento:
  1. sms.accepted: Bird recebeu a mensagem e está preparando para entregá-la a uma operadora.
  2. sms.sent: Bird entregou a mensagem à operadora e aguarda um recibo de entrega.
  3. Um evento terminal:
    • sms.delivered: A operadora confirmou a entrega ao aparelho.
    • sms.undelivered: A operadora reportou uma não entrega temporária, como um aparelho indisponível.
    • sms.failed: Uma falha permanente impediu a entrega.
    • sms.expired: A operadora parou de tentar e reportou a mensagem como expirada.
Os eventos terminais expõem o recibo de entrega da operadora, o que plataformas SMS chamam de relatório de entrega ou DLR.
A exceção é sms.rejected: a mensagem foi recusada (por uma verificação de política, uma cobrança que não pôde ser concluída ou uma operadora que a rejeitou) em vez de tentada e perdida. Uma mensagem rejeitada durante o processamento carrega sms.rejected como seu único evento.
Bird também recebe respostas. Quando um assinante envia uma mensagem para um dos seus números, Bird armazena a mensagem e emite sms.received, para que você possa agir sem polling. O payload carrega o corpo, a divisão em segmentos, ambos os números e a operadora quando reportada.
Bird avalia a resposta com base nas regras de palavras-chave daquele número. Uma palavra-chave de parada aceita, como STOP, registra uma supressão de remetente-e-assinante e ainda assim emite sms.received.
O evento type é um enum aberto: Bird pode adicionar novos tipos de evento ao longo do tempo, então trate um type não reconhecido como um evento futuro, não como um erro. Trate os tipos que você suporta e ignore o restante.

O envelope do evento

Os eventos chegam ao seu endpoint de webhook no envelope aninhado do Standard Webhooks descrito no Guia de webhooks: três campos, type, timestamp e um objeto data específico do tipo. A identidade do evento não está no corpo: ela está no header webhook-id HTTP, que é estável entre novas tentativas da mesma entrega e é a sua chave de deduplicação.
CampoDescrição
typeUm dos tipos de evento desta página, como sms.delivered
timestampQuando o evento ocorreu (RFC 3339); ordene por este campo, nunca pela ordem de chegada, pois as entregas não são ordenadas
dataPayload específico do evento
O data de todo evento SMS contém sms_id, workspace_id e os endereços to e from. Ele também repete o tags e o metadata do envio, para que você possa rotear e correlacionar eventos sem outra consulta. Cada um é null quando o envio não os incluiu.
O mesmo objeto carrega cost, a cobrança da mensagem até aquele evento, dividida em transaction_amount e passthrough_amount com a soma em amount. É null em um evento que não precificou nada. Como as entregas não são ordenadas, faça merge de cost um componente por vez em vez de substituir o objeto inteiro: para cada componente, mantenha o valor do evento com o timestamp mais recente. Um amount soma apenas os componentes do seu próprio payload, então leia-o como a cobrança parcial, não como um total definitivo. Custo e cobrança explica o que cada componente significa.
Exemplo de código
{
  "type": "sms.delivered",
  "timestamp": "2026-06-10T14:30:00Z",
  "data": {
    "sms_id": "sms_01krdgeqcxet5s7t44vh8rt9mg",
    "workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
    "to": "+15551234567",
    "from": "+12025550188",
    "carrier": "Example Wireless",
    "mcc_mnc": "310260",
    "cost": {
      "amount": "0.00990",
      "currency_code": "USD",
      "transaction_amount": "0.00790",
      "passthrough_amount": "0.00200"
    },
    "tags": [{ "name": "campaign", "value": "spring-2026" }],
    "metadata": { "order_id": "ord_123" }
  }
}

Eventos do ciclo de vida

sms.accepted

Dispara quando Bird aceita o envio e começa a preparar a entrega a uma operadora. O payload adiciona segments, a divisão Bird contada no momento da aceitação; o count é o que é cobrado pelo envio.

sms.sent

Dispara quando Bird entregou a mensagem à operadora e aguarda um recibo de entrega. O payload adiciona carrier e mcc_mnc (a rede que processou e seu código de país/rede móvel). Cada um é ausente em vez de null quando a operadora não o reporta. Para medir a latência de processamento, compare o timestamp deste evento com o de sms.accepted.

sms.delivered

A operadora confirmou que a mensagem chegou ao aparelho. O payload adiciona carrier e mcc_mnc, cada um ausente quando o recibo não os identificou.

Eventos de falha

O payload de cada evento de falha adiciona um objeto error: um code estável entre Bird (por exemplo unreachable ou blocked_by_carrier), um description legível, o carrier_error_code bruto quando fornecido, e occurred_at.

sms.undelivered

Uma não entrega não permanente: o aparelho estava desligado ou inacessível.

sms.failed

Uma falha permanente de entrega impediu a mensagem.

sms.rejected

A mensagem foi recusada pelas verificações de Bird durante o processamento, por uma cobrança que não pôde ser concluída ou por uma operadora que a rejeitou. Uma rejeição interrompe a mensagem antes que uma tentativa de entrega seja bem-sucedida. Uma carteira esgotada termina aqui com o código de erro insufficient_balance, e uma mensagem cuja cobrança não pôde ser concluída não é cobrada.

sms.expired

A operadora parou de tentar entregar e reportou a mensagem como expirada. A expiração vem do recibo de entrega da operadora: Bird não define nenhuma janela de validade própria e não executa nenhum temporizador que encerre uma mensagem. O error descreve por que a mensagem ainda não havia sido entregue quando a operadora desistiu, geralmente unreachable: o aparelho permaneceu desligado ou fora de cobertura durante todo o período.

Eventos de supressão

Além do ciclo de vida por mensagem, um evento reporta uma alteração na lista de supressão do espaço de trabalho: sms_suppression.created dispara quando uma supressão é criada, seja porque um assinante enviou uma palavra-chave de parada, a operadora reportou um opt-out ou alguém a adicionou manualmente. O payload carrega o suppression_id, o número do assinante como destination, o originator ao qual o bloqueio se aplica (uma supressão SMS é o par exato de remetente e assinante), o reason e o workspace_id, para que seu próprio sistema possa espelhar a lista sem polling:
Exemplo de código
{
  "type": "sms_suppression.created",
  "timestamp": "2026-08-25T14:52:03.192524705Z",
  "data": {
    "suppression_id": "ssu_01krdgeqcxet5s7t44vh8rt9mg",
    "destination": "+15550001234",
    "originator": "+15557654321",
    "reason": "keyword_stop",
    "workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf"
  }
}
Um opt-out em todo o espaço de trabalho registrado na aba Preferências é uma preferência declarada, não uma supressão, e não dispara este evento.

Lendo a timeline de uma mensagem

Webhooks entregam eventos aos seus sistemas. Para uma revisão pontual, o log de SMS renderiza o mesmo fluxo como uma timeline com timestamps, detalhes da operadora e erros. Para recuperar a timeline programaticamente, chame GET /v1/sms/messages/{message_id}/events. Para ler apenas o estado mais recente, chame GET /v1/sms/messages/{message_id}.

Próximos passos

  • Webhooks e eventos: configure um endpoint, verifique assinaturas e lide com novas tentativas e replay.
  • Log de SMS: inspecione a timeline por mensagem que esses eventos alimentam.
  • Enviando SMS: defina o tags e o metadata repetidos em cada evento.

Recursos relacionados

Continue com a documentação, guias e exemplos sobre este tópico. Os recursos estão em inglês.

Obtenha um resumo de implementação