message.status_updated
Enviado toda vez que o status de uma mensagem muda. Cada transição de status gera um evento independente.
{
"event": "message.status_updated",
"timestamp": "2025-01-15T10:30:00.000Z",
"data": {
"dispatchId": "uuid-do-message-delivery",
"campaignId": "uuid-da-campanha",
"campaignName": "Promoção Black Friday 2025",
"uid": "user-001",
"phone": "+5511999999999",
"status": "delivered",
"statusTimestamp": "2025-01-15T10:30:00.000Z",
"channel": "rcs",
"failureReason": null,
"metadata": {}
}
}
Campos do Payload
| Campo | Tipo | Descrição |
|---|
event | string | Tipo do evento. Sempre message.status_updated |
timestamp | string | ISO 8601 — momento em que o evento foi gerado |
data.dispatchId | string | ID único do message delivery |
data.campaignId | string | ID da campanha (mesmo enviado no dispatch) |
data.campaignName | string | Nome da campanha |
data.uid | string | null | ID externo do destinatário (enviado no dispatch via uid) |
data.phone | string | Número do destinatário |
data.status | string | Status atual. Ver tabela abaixo |
data.statusTimestamp | string | ISO 8601 — quando o status ocorreu no provedor |
data.channel | string | Canal de entrega: rcs ou sms |
data.failureReason | string | null | Motivo da falha (somente quando status = "failed") |
data.interaction | object | null | Dados de interação do usuário (somente para clicked e responded) |
data.metadata | object | Reservado para uso futuro |
Status Possíveis
| Status | Canal | Descrição |
|---|
sent | rcs ou sms | Mensagem enviada/confirmada pelo provedor |
carrier-sended | sms | SMS aceito pela operadora para entrega |
delivered | rcs ou sms | Mensagem entregue ao dispositivo |
read | rcs | Mensagem lida pelo destinatário |
clicked | rcs | Destinatário clicou em botão de ação (ACTION) ou URL |
responded | rcs | Destinatário respondeu com texto livre ou botão REPLY |
failed | rcs ou sms | Falha na entrega. Ver failureReason |
O campo failureReason é preenchido apenas quando status = "failed". Em todos os outros eventos (delivered, read, clicked, etc.) o campo é null, independentemente de a mensagem ter falhado anteriormente.
Fluxos de Eventos por Cenário
RCS — Bloqueado por duplicidade
Quando uma mensagem é bloqueada antes de ser enviada (ex: número já recebeu a mesma mensagem recentemente).
{
"data": {
"status": "failed",
"channel": "rcs",
"failureReason": "Bloqueado por duplicidade",
"interaction": null
}
}
RCS — Destinatário clica em botão de ação (openUrl, call)
sent → delivered → read → clicked
{
"data": {
"status": "clicked",
"channel": "rcs",
"failureReason": null,
"interaction": {
"type": "click",
"text": "APROVEITE",
"postbackData": "https://www.puravida.com.br/campanhas/health-monday"
}
}
}
sent → delivered → read → responded
{
"data": {
"status": "responded",
"channel": "rcs",
"failureReason": null,
"interaction": {
"type": "reply",
"text": "Garanta já a sua.",
"postbackData": "Eu quero a webcam"
}
}
}
RCS — Destinatário responde com texto livre
{
"data": {
"status": "responded",
"channel": "rcs",
"failureReason": null,
"interaction": {
"type": "text",
"text": "Olá, quero mais informações"
}
}
}
clicked é acionado por botões do tipo ACTION (openUrl, call). responded é acionado por botões do tipo REPLY ou quando o destinatário digita texto livre. Para todos os demais status (sent, delivered, read, failed), o campo interaction é null.
Campo interaction
Presente somente nos eventos clicked e responded.
| Campo | Tipo | Descrição |
|---|
interaction.type | string | "click" (botão ACTION), "reply" (botão REPLY) ou "text" (texto livre) |
interaction.text | string | Texto do botão clicado ou mensagem digitada |
interaction.postbackData | string | undefined | URL (click) ou valor de postback do botão REPLY |
RCS → Fallback SMS — Dispositivo sem suporte RCS, SMS entregue
Quando o dispositivo não suporta RCS, o provedor automaticamente reenvia via SMS quando o template utilizado na campanha estiver com fallback ativo. O campo channel muda de rcs para sms a partir do evento de fallback.
[rcs] sent
[rcs] failed ← "Aparelho não possui suporte ao RCS."
[sms] sent ← SMS despachado pelo provedor
[sms] carrier-sended ← SMS aceito pela operadora
[sms] delivered ← SMS entregue ao dispositivo
{ "data": { "status": "failed", "channel": "rcs", "failureReason": "Aparelho não possui suporte ao RCS." } }
{ "data": { "status": "sent", "channel": "sms", "failureReason": null } }
{ "data": { "status": "carrier-sended", "channel": "sms", "failureReason": null } }
{ "data": { "status": "delivered", "channel": "sms", "failureReason": null } }
RCS → Fallback SMS — SMS não entregue pela operadora
[rcs] sent
[rcs] failed ← "Aparelho não possui suporte ao RCS."
[sms] sent ← SMS despachado pelo provedor
[sms] carrier-sended ← SMS aceito pela operadora
[sms] failed ← Operadora não conseguiu entregar
{ "data": { "status": "failed", "channel": "rcs", "failureReason": "Aparelho não possui suporte ao RCS." } }
{ "data": { "status": "sent", "channel": "sms", "failureReason": null } }
{ "data": { "status": "carrier-sended", "channel": "sms", "failureReason": null } }
{ "data": { "status": "failed", "channel": "sms", "failureReason": null } }
Diferença entre sent e carrier-sended (canal SMS)
| Status | Momento |
|---|
sent | Confirmação do provedor de que o SMS foi despachado |
carrier-sended | Confirmação da operadora de que o SMS foi recebido para entrega |
delivered | Confirmação de que o SMS chegou ao dispositivo |
Implemente seu handler de webhook de forma idempotente. Uma mesma mensagem pode gerar eventos de sent e carrier-sended em sequência rápida — ambos são válidos e distintos.
Eventos de Resposta do Destinatário
Além de atualizações de status de entrega, eventos responded e clicked indicam que o destinatário interagiu com a mensagem.
| Interação | Status | Descrição |
|---|
| Botão ACTION clicado | clicked | O destinatário clicou em um link ou iniciou uma ligação |
| Botão REPLY clicado | responded | O destinatário escolheu uma resposta rápida |
| Texto digitado | responded | O destinatário enviou uma mensagem de texto livre |