Entrega e leitura
Evento: messages_update · Transporte: POST para o seu receptor
Acompanhe atualizações de estado de mensagens, como recibos de entrega e leitura.
Como correlacionar
event.MessageIDs pode conter vários IDs. Aplique o estado recebido a cada mensagem correspondente da mesma instância/conversa. Não trate o evento como uma mensagem nova.
A grafia dos campos é relevante: MessageIDs, Timestamp, Type, IsFromMe e IsGroup usam maiúsculas. Os campos normalizados chatid, sender_pn e sender_lid usam minúsculas.
event.Timestamp do fluxo de recibos usa segundos Unix. Isso é diferente de message.messageTimestamp, que usa milissegundos. Eventos podem chegar fora da ordem esperada; preserve sua regra de progressão de estado.
Grupos
Em grupos, cada participante confirma separadamente. Em vez de um evento por participante, a API junta as confirmações de cada mensagem durante 60 segundos (contados da primeira, sem renovar) e envia um messages_update com type: "GroupReceipts":
- um evento por mensagem:
MessageIDstem sempre um item; event.Receiptslista quem confirmou, o estado (Delivered,ReadouPlayed) e o horário de cada um;- não há
state,SendernemTimestampúnicos: leia cada item deReceipts; - confirmações que chegam depois da janela saem num próximo evento da mesma mensagem;
IsGroupétrue: quem usa o filtroisGroupYesnão recebe esses eventos.
Confira type antes de processar: ReadReceipt para conversas individuais, GroupReceipts para grupos. A API não grava as confirmações em banco: se precisar do histórico, guarde os eventos. POST /message/status mostra as confirmações de uma mensagem, da memória da API ou do celular da conta. O status da mensagem de grupo segue o participante mais adiantado (pelo menos um recebeu, leu ou ouviu) e muda junto com o GroupReceipts.
Habilitar este evento
Adicione messages_update à lista events do webhook da instância. Preserve os outros eventos de que sua integração precisa.
{
"enabled": true,
"url": "https://seu-sistema.example/hooks/whatsapp",
"events": [
"messages_update"
]
}
Envie essa configuração para POST /webhook, usando o header token. O JSON acima configura a assinatura; os exemplos de entrega abaixo são o que seu servidor recebe.
Campos do payload
O envelope comum vem na raiz. Campos condicionais podem estar ausentes ou nulos conforme o evento; não use a tabela como obrigação de presença de todos os campos.
| Campo | Tipo | Significado |
|---|---|---|
EventType | string | Obrigatório. Tipo de evento, por exemplo connection ou messages. |
owner | string | Obrigatório. Consulte o objeto ou exemplo correspondente. |
token | string | Obrigatório. Token da instância; dado sensível. |
BaseUrl | string | Obrigatório. Consulte o objeto ou exemplo correspondente. |
instanceName | string | Consulte o objeto ou exemplo correspondente. |
type | string | Origem do evento: ReadReceipt nas conversas individuais; GroupReceipts no lote de confirmações de uma mensagem de grupo. |
state | string | Estado normalizado aplicado às mensagens (ReadReceipt). Ausente em GroupReceipts. |
event | object | Recibo e mensagens afetadas. |
event.chatid | string | JID da conversa, quando resolvido. |
event.chatlid | string / null | LID da conversa; pode ser ausente ou null. |
event.sender_pn | string / null | JID por telefone, quando conhecido. |
event.sender_lid | string / null | Identificador LID, quando conhecido. |
event.Chat | string | JID da conversa. |
event.Sender | string | JID do emissor do recibo. Ausente em GroupReceipts. |
event.MessageIDs | array / null | Mensagens afetadas. Em GroupReceipts, sempre uma. |
event.Timestamp | integer | Segundos Unix no fluxo de recibos. Ausente em GroupReceipts; use o timestamp de cada item. |
event.Type | string | Estado do recibo; GroupReceipts no lote de grupo. |
event.IsFromMe | boolean | Origem da mensagem. |
event.IsGroup | boolean | Conversa de grupo. |
event.Receipts | array | Só em GroupReceipts: confirmações dos participantes nesta janela, em ordem de horário. |
Exemplos de entrega
Exemplos ilustrativos com identificadores fictícios. O conteúdo específico e os campos opcionais variam.
Recibo de leitura
{
"EventType": "messages_update",
"owner": "5511999999999",
"token": "INSTANCE_TOKEN",
"BaseUrl": "https://seu-servidor.example",
"instanceName": "Atendimento",
"type": "ReadReceipt",
"state": "Read",
"event": {
"Chat": "5511888888888@s.whatsapp.net",
"chatid": "5511888888888@s.whatsapp.net",
"chatlid": null,
"Sender": "5511888888888@s.whatsapp.net",
"sender_pn": "5511888888888@s.whatsapp.net",
"sender_lid": null,
"MessageIDs": [
"MSG_EXEMPLO"
],
"Timestamp": 1788868800,
"Type": "Read",
"IsFromMe": true,
"IsGroup": false
}
}
Confirmações de grupo (GroupReceipts)
{
"EventType": "messages_update",
"owner": "5511999999999",
"token": "INSTANCE_TOKEN",
"BaseUrl": "https://seu-servidor.example",
"instanceName": "Atendimento",
"type": "GroupReceipts",
"event": {
"Chat": "120363000000001@g.us",
"chatid": "120363000000001@g.us",
"IsFromMe": false,
"IsGroup": true,
"MessageIDs": [
"MSG_EXEMPLO"
],
"Type": "GroupReceipts",
"Receipts": [
{
"participant": "5511911110000@s.whatsapp.net",
"participant_pn": "5511911110000@s.whatsapp.net",
"participant_lid": "300001@lid",
"state": "Delivered",
"timestamp": 1788868801
},
{
"participant": "5511922220000@s.whatsapp.net",
"participant_pn": "5511922220000@s.whatsapp.net",
"participant_lid": "300002@lid",
"state": "Delivered",
"timestamp": 1788868803
},
{
"participant": "5511911110000@s.whatsapp.net",
"participant_pn": "5511911110000@s.whatsapp.net",
"participant_lid": "300001@lid",
"state": "Read",
"timestamp": 1788868820
}
]
}
}
Responder ao webhook
Seu receptor deve aceitar o POST JSON e devolver uma resposta 2xx rapidamente, após validar e registrar o recebimento. O corpo da resposta não é um comando para a API. Processe trabalho demorado separadamente.
O worker não repete automaticamente uma entrega HTTP malsucedida. Consulte diagnóstico de webhooks e implemente a reconciliação necessária. Eventos repetidos ou fora de ordem ainda precisam ser tolerados pelo receptor.