Webhooks
Configuração, entrega e os 41 eventos implementados.
Documentação técnica dos webhooks implementados no código executável atual.
Sumário
- Visão geral
- Configuração
- Mapa de eventos
- Headers HTTP
- Envelope padrão
- Estrutura da instância
- Entrega e tratamento de erros
- Eventos do Message Batch
- Eventos
- Eventos não suportados ou ignorados
Visão geral
Webhooks são requisições HTTP POST assíncronas enviadas pela aplicação para uma URL configurada pelo consumidor. Os 27 eventos por instância usam um envelope com event, instance, data e timestamp. Os 14 eventos globais de Message Batch usam event, data e timestamp, sem o campo instance.
Para eventos por instância, existem dois destinos possíveis. O webhook da instância é configurado pela rota atual PUT /instance/:instance/webhook, fica no cache em memória e só recebe eventos cujas flags estejam habilitadas em events. Os aliases legados PUT /webhook/set/:instanceName e GET /webhook/find/:instanceName permanecem ativos. O webhook global é configurado por WEBHOOK_GLOBAL_URL e WEBHOOK_GLOBAL_ENABLED; quando habilitado, recebe todos esses eventos sem aplicar as flags da instância. Eventos de Message Batch são enviados exclusivamente ao webhook global.
O cache é carregado na inicialização a partir dos webhooks habilitados e é atualizado quando a configuração da instância muda. Se a instância não tiver webhook habilitado e o webhook global estiver desabilitado, o evento é descartado sem erro.
Os eventos por instância entram em uma fila em memória e são processados por múltiplos workers. Nesse fluxo, respostas HTTP 2xx são sucesso; erros de rede, timeout e respostas não 2xx são registrados sem retry automático ou dead-letter queue. Eventos de Message Batch usam uma outbox PostgreSQL e falhas são reagendadas com backoff persistente. Nenhum dos fluxos garante ordenação.
- Versão do documento:
1.0.0. - Eventos oficiais documentados:
41(27por instância e14globais do Message Batch). - Constantes por instância:
internal/database/types/webhook.go. - Dispatcher por instância:
internal/webhook/manager.go. - Constantes e outbox de lote:
internal/messagebatch/webhook.goeinternal/messagebatch/outbox.go. - Versão auditada do whatsmeow:
v0.0.0-20260630180629-b572e5bcb92b.
Configuração
Variáveis de ambiente
| Variável | Tipo | Padrão | Descrição |
|---|---|---|---|
WEBHOOK_GLOBAL_URL | URL | vazio | URL HTTP ou HTTPS do webhook global. Obrigatória quando WEBHOOK_GLOBAL_ENABLED=true. |
WEBHOOK_GLOBAL_ENABLED | boolean | false | Habilita o webhook global. Aceita true, false ou vazio. |
Webhook da instância
Configurar ou atualizar:
PUT /instance/codechat/webhook HTTP/1.1
Authorization: Bearer <token-da-instancia>
Content-Type: application/jsonConsultar:
GET /instance/codechat/webhook HTTP/1.1
Authorization: Bearer <token-da-instancia>Objeto de configuração da instância:
{
"enabled": true,
"events": {
"callUpsert": true,
"chatsDeleted": true,
"chatsUpdated": true,
"connectionUpdated": true,
"contactsUpdated": true,
"contactsUpsert": true,
"groupsParticipantsUpdated": true,
"groupsUpdated": true,
"groupsUpsert": true,
"historySync": true,
"identityUpdated": true,
"labelsAssociation": true,
"labelsEdit": true,
"mediaRetry": true,
"messagesDeleted": true,
"messagesStarred": true,
"messagesUndecryptable": true,
"messagesUpdated": true,
"messagesUpsert": true,
"newsLetter": true,
"presenceUpdated": true,
"profilePictureUpdated": true,
"qrcodeUpdated": true,
"sendMessage": true,
"settingsUpdated": true,
"statusInstance": true,
"userAboutUpdated": true
},
"url": "https://example.com/webhooks/codechat"
}url precisa usar http ou https e ter no máximo 500 caracteres. enabled ausente assume true na criação/atualização. Quando events é omitido, as flags existentes são preservadas; quando events é {}, as flags são removidas. Campos desconhecidos em events são rejeitados.
Mapa de eventos
| Flag | Evento externo | Descrição |
|---|---|---|
callUpsert | call.upsert | Atualizacao de chamada de voz ou video. |
chatsDeleted | chats.delete | Exclusao ou limpeza de conversa. |
chatsUpdated | chats.updated | Atualizacao de propriedades de conversas. |
connectionUpdated | connection.update | Mudanca de estado da conexao da instancia. |
contactsUpdated | contacts.update | Atualizacao parcial em contato existente. |
contactsUpsert | contacts.upsert | Contato criado ou atualizado no cadastro local. |
groupsParticipantsUpdated | groups.participants.update | Mudanca de participantes em grupo. |
groupsUpdated | groups.update | Atualizacao parcial de metadados de grupo. |
groupsUpsert | groups.upsert | Grupo criado, descoberto ou sincronizado. |
historySync | history.sync | Sincronizacao de historico recebida do WhatsApp. |
identityUpdated | identity.update | Mudanca de identidade criptografica de um contato. |
labelsAssociation | labels.association | Associacao ou remocao de label em chat ou mensagem. |
labelsEdit | labels.edit | Criacao, alteracao ou remocao de label. |
mediaRetry | media.retry | Resultado ou erro relacionado a tentativa de retry de midia. |
messagesDeleted | messages.delete | Mensagem removida localmente pelo evento DeleteForMe. |
messagesStarred | messages.star | Marcacao ou desmarcacao de estrela em mensagem. |
messagesUndecryptable | messages.undecryptable | Mensagem recebida sem possibilidade de descriptografia. |
messagesUpdated | messages.update | Atualizacao de recibo/status de uma mensagem ja conhecida. |
messagesUpsert | messages.upsert | Mensagem recebida e persistida pela aplicacao. |
newsLetter | news.letter | Eventos relacionados a newsletters/canais. |
presenceUpdated | presence.updated | Atualizacao de presenca de usuario ou presenca em chat. |
profilePictureUpdated | profile.picture.update | Atualizacao de foto de perfil da propria instancia ou de outro JID. |
qrcodeUpdated | qrcode.updated | Novo QR Code disponivel para pareamento da instancia. |
sendMessage | send.message | Mensagem enviada pela API apos envio e persistencia bem-sucedidos. |
settingsUpdated | settings.update | Atualizacao de configuracoes do usuario/instancia. |
statusInstance | status.instance | Eventos de estado operacional ou avisos da instancia. |
userAboutUpdated | user.about.update | Atualizacao do recado/about de um usuario. |
global only | message.batch.created | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.started | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.progress | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.pause-requested | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.paused | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.waiting-instance | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.resumed | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.stop-requested | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.stopped | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.interrupted | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.completed | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.completed-with-errors | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.item.failed | Evento persistente do Envio em lote; nao possui flag por instancia. |
global only | message.batch.item.unknown | Evento persistente do Envio em lote; nao possui flag por instancia. |
Headers HTTP
| Header | Exemplo | Descrição |
|---|---|---|
Content-Type | application/json | Formato do payload. |
User-Agent | CodeChat-Webhook/1.0 | Identifica o emissor do webhook. |
x-request-id | UUID ou request id do contexto | Id de rastreio da entrega; nao e uma chave de idempotencia garantida. |
x-owner-jid | JID do owner ou string vazia | Owner da instancia quando disponivel. |
x-instance-name | Nome da instancia | Nome publico da instancia. |
x-instance-id | 1 | Identificador numerico interno da instancia. |
x-webhook-event | Nome externo do evento | Mesmo valor do campo event no envelope. |
Exemplo de requisição recebida pelo consumidor:
POST /webhooks/codechat HTTP/1.1
Host: example.com
Content-Type: application/json
User-Agent: CodeChat-Webhook/1.0
x-request-id: 019f0000-0000-7000-8000-000000000000
x-owner-jid: [email protected]
x-instance-name: codechat
x-instance-id: 1
x-webhook-event: messages.upsertx-owner-jid pode ser uma string vazia quando a instância ainda não estiver conectada ou quando o proprietário não estiver salvo no snapshot usado pelo dispatcher.
Envelope padrão
{
"data": {},
"event": "nome.do.evento",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}event é o nome externo do evento. instance contém o snapshot mínimo da instância responsável pelo evento. data contém os dados específicos de cada evento e pode ser objeto ou array. timestamp é gerado quando o envelope é criado, em RFC3339 UTC.
Estrutura da instância
{
"connectionStatus": "online",
"externalAttributes": {
"tenantId": "019f0000-0000-7000-8000-000000000000"
},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
}id é o identificador numérico interno da instância. name é o nome usado nas rotas. connectionStatus usa os valores persistidos da conexão, como offline, connecting, qr_code, pairing_code, pairing, online, reconnecting, disconnected, connection_timeout, logged_out, session_missing, stream_replaced, keepalive_timeout, client_outdated, temporary_ban e connection_error. ownerJid é string ou null no body; no header x-owner-jid, o valor nulo vira string vazia. externalAttributes sempre é um objeto JSON; valores ausentes, null ou inválidos são serializados como {}.
Entrega e tratamento de erros
{
"delivery": {
"allowedSchemes": [
"http",
"https"
],
"concurrentSends": true,
"contentType": "application/json",
"method": "POST",
"ordering": "not_guaranteed",
"queueSize": 1000,
"retryEnabled": false,
"successStatus": "200-299",
"timeoutSeconds": 15,
"workers": 10
}
}- Somente respostas HTTP 2xx sao consideradas sucesso.
- Falhas de rede, timeout e respostas nao 2xx sao registradas em log e nao abortam o fluxo principal.
- Nao existe retry automatico nem dead-letter queue nesta implementacao.
- A fila de entrega e assincrona e processada por multiplos workers.
- A ordem relativa entre eventos nao e garantida entre instancias nem entre eventos diferentes da mesma instancia.
- Alguns eventos dependem de persistencia previa. Quando a persistencia falha, o evento pode nao ser emitido.
- Nao ha assinatura HMAC, header de autenticacao ou segredo compartilhado no emissor atual.
- Use HTTPS, endpoints privados, allowlist de IP ou autenticacao no destino quando houver dados sensiveis.
- O x-request-id serve para rastreio e correlacao; ele nao prova autenticidade e nao garante idempotencia.
- Se a fila estiver cheia,
DispatchretornaErrWebhookQueueFull; os chamadores atuais registram warning e continuam o fluxo principal. - Durante shutdown, a fila é fechada e o processo aguarda os workers terminarem até o contexto de shutdown expirar.
Eventos do Message Batch
Esses eventos sao enviados uma unica vez ao WEBHOOK_GLOBAL_URL; nao sao repetidos por instancia. A linha de outbox e criada no mesmo commit da alteracao do lote/item, e a chamada HTTP acontece depois da transacao.
Mapa de eventos de lote
| Evento | Quando e criado |
|---|---|
message.batch.created | Lote, itens e instancias persistidos. |
message.batch.started | Primeiro claim do lote em QUEUED. |
message.batch.progress | Percentual inteiro mudou ou chegou a 100. |
message.batch.pause-requested | API aceitou a solicitacao de pausa. |
message.batch.paused | Worker chegou a um ponto seguro e pausou. |
message.batch.waiting-instance | Nenhuma instancia do lote esta conectada. |
message.batch.resumed | Lote foi retomado ou uma instancia voltou. |
message.batch.stop-requested | API aceitou a solicitacao de stop. |
message.batch.stopped | Worker concluiu o stop controlado. |
message.batch.interrupted | Lease expirou ou o processo encerrou. |
message.batch.completed | Todos os itens terminaram sem falha ou UNKNOWN. |
message.batch.completed-with-errors | Todos os itens terminaram com falha ou UNKNOWN. |
message.batch.item.failed | Um item terminou em FAILED. |
message.batch.item.unknown | O resultado externo de um item nao pode ser confirmado. |
Headers do Message Batch
| Header | Valor |
|---|---|
Content-Type | application/json |
User-Agent | CodeChat-MessageBatch-Webhook/1.0 |
x-request-id | UUID de rastreio da tentativa HTTP |
x-webhook-event | Mesmo valor de event no body |
Os headers de instancia (x-instance-id, x-instance-name e x-owner-jid) nao sao enviados nesse fluxo global.
Body de progresso
{
"data": {
"batch": {
"counts": {
"failed": 2,
"pending": 64,
"processed": 35,
"sending": 1,
"skipped": 0,
"success": 33,
"total": 100,
"unknown": 0
},
"createdAt": "2026-07-13T15:00:00Z",
"currentItem": {
"id": "01900000-0000-7000-8000-000000000036",
"instanceName": "codechat-01",
"position": 35,
"recipient": "5531999999999"
},
"id": "01900000-0000-7000-8000-000000000001",
"instances": [
{
"connectionStatus": "online",
"id": 1,
"name": "codechat-01",
"selectedCount": 20
},
{
"connectionStatus": "online",
"id": 2,
"name": "codechat-02",
"selectedCount": 15
}
],
"name": "Aviso de manutencao",
"progress": 35,
"startedAt": "2026-07-13T15:01:00Z",
"status": "PROCESSING",
"updatedAt": "2026-07-13T15:10:00Z"
}
},
"event": "message.batch.progress",
"timestamp": "2026-07-13T15:10:00Z"
}message.batch.progress nao e criado novamente quando o percentual inteiro permanece igual.
Body de conclusao com falhas
{
"data": {
"batch": {
"completedAt": "2026-07-13T15:30:00Z",
"counts": {
"failed": 3,
"pending": 0,
"processed": 100,
"sending": 0,
"skipped": 0,
"success": 96,
"total": 100,
"unknown": 1
},
"id": "01900000-0000-7000-8000-000000000001",
"name": "Aviso de manutencao",
"progress": 100,
"status": "COMPLETED_WITH_ERRORS",
"updatedAt": "2026-07-13T15:30:00Z"
}
},
"event": "message.batch.completed-with-errors",
"timestamp": "2026-07-13T15:30:00Z"
}Respostas 2xx confirmam a entrega. Falhas sao reagendadas com backoff persistente; a outbox nao chama HTTP enquanto segura uma transacao do lote.
Eventos
call.upsert
Atualizacao de chamada de voz ou video.
Flag: callUpsert
Eventos internos: *events.CallOffer, *events.CallAccept, *events.CallOfferNotice, *events.CallPreAccept, *events.CallTransport, *events.CallTerminate, *events.CallReject, *events.CallRelayLatency, *events.UnknownCallEvent
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: CallUpsertWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_extended_events.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: call.upsertBody
{
"data": {
"callerPn": "5511999999999",
"chatId": "[email protected]",
"date": "2026-07-04T19:05:00Z",
"from": "[email protected]",
"groupJid": null,
"id": "3EB0C4D0A1",
"isGroup": false,
"isVideo": false,
"latencyMs": null,
"offline": false,
"status": "offer"
},
"event": "call.upsert",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
chatId:string, obrigatório, não aceitanull. JID do chat da chamada.from:string, obrigatório, não aceitanull. JID de origem.callerPn:string | null, obrigatório, aceitanull. Phone number do chamador quando disponivel.isGroup:boolean | null, obrigatório, aceitanull. Indica chamada em grupo quando o normalizador consegue inferir.groupJid:string | null, obrigatório, aceitanull. JID do grupo quando disponivel.id:string, obrigatório, não aceitanull. ID da chamada.date:string, obrigatório, não aceitanull. Timestamp RFC3339 da chamada/processamento.isVideo:boolean | null, obrigatório, aceitanull. Indica chamada de video quando o normalizador consegue inferir.status:string, obrigatório, não aceitanull. Status normalizado da chamada. Valores possíveis:offer,ringing,preaccept,transport,relaylatency,timeout,reject,accept,terminate,unknown.offline:boolean, obrigatório, não aceitanull. Indica se o evento veio como offline.latencyMs:number | null, obrigatório, aceitanull. Latencia em milissegundos quando reportada.
Valores possíveis
status:offer,ringing,preaccept,transport,relaylatency,timeout,reject,accept,terminate,unknown
Observações
- Sem observações adicionais.
chats.delete
Exclusao ou limpeza de conversa.
Flag: chatsDeleted
Eventos internos: *events.DeleteChat
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: ChatDeletedWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: chats.deleteBody
{
"data": {
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"deleteMedia": false
},
"event": "chats.delete",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
chatJid:string, obrigatório, não aceitanull. JID da conversa.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 do processamento.deleteMedia:boolean, opcional, não aceitanull. Indica remocao de midia local quando presente.additionalProperties:object, opcional, não aceitanull. Campos achatados da acao original.
Observações
- Sem observações adicionais.
chats.updated
Atualizacao de propriedades de conversas.
Flag: chatsUpdated
Eventos internos: *events.Blocklist, *events.BlocklistChange, *events.Archive, *events.UnarchiveChatsSetting, *events.ClearChat, *events.Pin, *events.Mute, *events.MarkChatAsRead
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: ChatUpdatedWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: chats.updatedBody
{
"data": {
"archived": true,
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"type": "archive"
},
"event": "chats.updated",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, obrigatório, não aceitanull. Subtipo da atualizacao de chat. Valores possíveis:blocklist,blocklist.change,archive,unarchive.setting,clear,pin,mute,mark.read.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.chatJid:string, opcional, não aceitanull. JID da conversa quando o subtipo tem conversa especifica.fromFullSync:boolean, opcional, não aceitanull. Indica se veio de sincronizacao completa quando disponivel.additionalProperties:object, opcional, não aceitanull. Campos achatados do evento original do whatsmeow.
Valores possíveis
type:blocklist,blocklist.change,archive,unarchive.setting,clear,pin,mute,mark.read
Observações
- Eventos UserStatusMute sao documentados em settings.update, porque o registro atual os roteia para esse evento externo.
connection.update
Mudanca de estado da conexao da instancia.
Flag: connectionUpdated
Eventos internos: *events.PairSuccess, *events.PairError, *events.Connected, *events.Disconnected, *events.LoggedOut, *events.StreamReplaced, *events.KeepAliveTimeout, *events.KeepAliveRestored, *events.ConnectFailure, *events.ManualLoginReconnect, *events.StreamError, *events.CATRefreshError
Persistência: O status da instancia e atualizado pelos fluxos de conexao antes ou junto da entrega conforme o subtipo.
Tipo de data: object
DTO/normalizador: ConnectionUpdateWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: connection.updateBody
{
"data": {
"connection": "open",
"lastConnection": "2026-07-04T18:50:00Z",
"type": "connected"
},
"event": "connection.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, obrigatório, não aceitanull. Subtipo normalizado da conexao. Valores possíveis:pair.success,connected,disconnected,logged.out,stream.replaced,keepalive.timeout,keepalive.restored,connect.failure,manual.reconnect,pair.error,stream.error,cat.refresh.error.connection:string, obrigatório, não aceitanull. Estado externo da conexao. Valores possíveis:connecting,open,close,replaced,timeout.statusReason:number, opcional, não aceitanull. Codigo numerico de motivo quando diferente de zero; omitido quando zero.lastConnection:string, opcional, não aceitanull. Timestamp RFC3339 UTC quando informado; omitido quando ausente.message:string, opcional, não aceitanull. Mensagem tecnica quando informada; omitida quando vazia.
Valores possíveis
type:pair.success,connected,disconnected,logged.out,stream.replaced,keepalive.timeout,keepalive.restored,connect.failure,manual.reconnect,pair.error,stream.error,cat.refresh.errorconnection:connecting,open,close,replaced,timeout
Observações
statusReason,lastConnectionemessageusamomitempty; quando estao zerados ou vazios, nao aparecem no JSON.
contacts.update
Atualizacao parcial em contato existente.
Flag: contactsUpdated
Eventos internos: *events.PushName, *events.BusinessName
Persistência: Requer DATABASE_SAVE_DATA_CONTACTS=true. O contato e atualizado antes da entrega quando aplicavel.
Flag de persistência: DATABASE_SAVE_DATA_CONTACTS
Tipo de data: array
DTO/normalizador: ContactUpdateWebhookData[]
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/event_persistence.go, internal/whatsapp/webhook_extended_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: contacts.updateBody
{
"data": [
{
"action": "updated",
"businessName": null,
"id": 41,
"lid": null,
"pushName": "Cliente Atualizado",
"remoteJid": "[email protected]",
"source": "pushName"
}
],
"event": "contacts.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
id:number, obrigatório, não aceitanull. ID interno do contato persistido.remoteJid:string, obrigatório, não aceitanull. JID remoto do contato.lid:string | null, obrigatório, aceitanull. LID do contato quando conhecido.pushName:string | null, opcional, aceitanull. Push name atualizado quando presente.businessName:string | null, opcional, aceitanull. Nome comercial atualizado quando presente.action:string, obrigatório, não aceitanull. Acao executada. Valores possíveis:updated.source:string, obrigatório, não aceitanull. Origem da alteracao. Valores possíveis:pushName,businessName.
Valores possíveis
action:updatedsource:pushName,businessName
Observações
- O payload e array; o handler atual normalmente envia um item por entrega.
contacts.upsert
Contato criado ou atualizado no cadastro local.
Flag: contactsUpsert
Eventos internos: *events.Contact
Persistência: Requer DATABASE_SAVE_DATA_CONTACTS=true. O contato e salvo antes da entrega.
Flag de persistência: DATABASE_SAVE_DATA_CONTACTS
Tipo de data: object
DTO/normalizador: ContactUpsertWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/event_persistence.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: contacts.upsertBody
{
"data": {
"action": "upserted",
"id": 41,
"lid": "279847268053216@lid",
"profilePicUrl": null,
"pushName": "Cliente",
"remoteJid": "[email protected]"
},
"event": "contacts.upsert",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
id:number, obrigatório, não aceitanull. ID interno do contato persistido.remoteJid:string, obrigatório, não aceitanull. JID remoto do contato.lid:string | null, obrigatório, aceitanull. LID do contato quando conhecido.pushName:string | null, obrigatório, aceitanull. Push name salvo para o contato.profilePicUrl:string | null, obrigatório, aceitanull. URL de foto do perfil quando conhecida.action:string, obrigatório, não aceitanull. Acao executada. Valores possíveis:upserted.
Valores possíveis
action:upserted
Observações
- Sem observações adicionais.
groups.participants.update
Mudanca de participantes em grupo.
Flag: groupsParticipantsUpdated
Eventos internos: *events.GroupInfo
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: GroupParticipantsUpdatedWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_extended_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: groups.participants.updateBody
{
"data": {
"action": "add",
"author": "[email protected]",
"authorPn": "5531999999999",
"id": "[email protected]",
"participants": [
{
"admin": null,
"id": "[email protected]",
"isAdmin": false,
"isSuperAdmin": false
}
]
},
"event": "groups.participants.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
id:string, obrigatório, não aceitanull. JID do grupo.author:string, obrigatório, não aceitanull. JID do autor da alteracao; string vazia quando ausente.authorPn:string, opcional, não aceitanull. Phone number do autor quando disponivel; omitido quando ausente.participants:GroupParticipantWebhookData[], obrigatório, não aceitanull. Participantes afetados.action:string, obrigatório, não aceitanull. Acao aplicada. Valores possíveis:add,remove,promote,demote.
Valores possíveis
action:add,remove,promote,demote
Observações
- Sem observações adicionais.
groups.update
Atualizacao parcial de metadados de grupo.
Flag: groupsUpdated
Eventos internos: *events.GroupInfo
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: array
DTO/normalizador: GroupUpdateWebhookData[]
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_extended_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: groups.updateBody
{
"data": [
{
"partial": {
"announce": true,
"id": "[email protected]",
"subject": "Novo nome do grupo",
"subjectTime": 1783188000
}
}
],
"event": "groups.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
partial:GroupPartialWebhookData, obrigatório, não aceitanull. Metadados parciais alterados no grupo.partial.notify:string, opcional, não aceitanull. Nome de notificacao do grupo quando informado.partial.addressingMode:string, opcional, não aceitanull. Modo de enderecamento do grupo quando informado.partial.owner:string, opcional, não aceitanull. JID do owner quando informado.partial.ownerPn:string, opcional, não aceitanull. Phone number do owner quando informado.partial.ownerUsername:string, opcional, não aceitanull. Username do owner quando informado.partial.ownerCountryCode:string, opcional, não aceitanull. Codigo de pais do owner quando informado.partial.subjectOwner:string, opcional, não aceitanull. JID de quem definiu o subject quando informado.partial.subjectOwnerPn:string, opcional, não aceitanull. Phone number de quem definiu o subject quando informado.partial.subjectOwnerUsername:string, opcional, não aceitanull. Username de quem definiu o subject quando informado.partial.subjectTime:number, opcional, não aceitanull. Timestamp Unix do subject quando informado.partial.creation:number, opcional, não aceitanull. Timestamp Unix de criacao quando informado.partial.desc:string, opcional, não aceitanull. Descricao do grupo quando informada.partial.descOwner:string, opcional, não aceitanull. JID de quem definiu a descricao quando informado.partial.descOwnerPn:string, opcional, não aceitanull. Phone number de quem definiu a descricao quando informado.partial.descOwnerUsername:string, opcional, não aceitanull. Username de quem definiu a descricao quando informado.partial.descId:string, opcional, não aceitanull. ID da descricao quando informado.partial.descTime:number, opcional, não aceitanull. Timestamp Unix da descricao quando informado.partial.linkedParent:string, opcional, não aceitanull. Grupo/comunidade pai quando informado.partial.restrict:boolean, opcional, não aceitanull. Restricao de edicao quando informada.partial.announce:boolean, opcional, não aceitanull. Modo anuncio quando informado.partial.memberAddMode:boolean, opcional, não aceitanull. Modo de adicao por membros quando informado.partial.joinApprovalMode:boolean, opcional, não aceitanull. Modo de aprovacao de entrada quando informado.partial.isCommunity:boolean, opcional, não aceitanull. Indica comunidade quando informado.partial.isCommunityAnnounce:boolean, opcional, não aceitanull. Indica grupo de anuncios da comunidade quando informado.partial.size:number, opcional, não aceitanull. Tamanho do grupo quando informado.partial.ephemeralDuration:number, opcional, não aceitanull. Duracao de mensagens temporarias em segundos quando informada.partial.inviteCode:string, opcional, não aceitanull. Codigo de convite quando informado.partial.author:string, opcional, não aceitanull. Autor da alteracao quando informado.partial.authorPn:string, opcional, não aceitanull. Phone number do autor quando informado.partial.authorUsername:string, opcional, não aceitanull. Username do autor quando informado.
Observações
- O handler atual envia array com um item contendo partial.
groups.upsert
Grupo criado, descoberto ou sincronizado.
Flag: groupsUpsert
Eventos internos: *events.JoinedGroup
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: array
DTO/normalizador: GroupUpsertWebhookData[]
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_extended_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: groups.upsertBody
{
"data": [
{
"addressingMode": "pn",
"creation": 1783187000,
"id": "[email protected]",
"isCommunity": false,
"owner": "[email protected]",
"participants": [
{
"admin": "admin",
"id": "[email protected]",
"isAdmin": true,
"isSuperAdmin": false,
"lid": "279847268053216@lid"
}
],
"subject": "Grupo"
}
],
"event": "groups.upsert",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
id:string, obrigatório, não aceitanull. JID do grupo.subject:string, obrigatório, não aceitanull. Nome do grupo.participants:GroupParticipantWebhookData[], obrigatório, não aceitanull. Participantes conhecidos do grupo.notify:string, opcional, não aceitanull. Nome de notificacao do grupo quando informado.addressingMode:string, opcional, não aceitanull. Modo de enderecamento do grupo quando informado.owner:string, opcional, não aceitanull. JID do owner quando informado.ownerPn:string, opcional, não aceitanull. Phone number do owner quando informado.ownerUsername:string, opcional, não aceitanull. Username do owner quando informado.ownerCountryCode:string, opcional, não aceitanull. Codigo de pais do owner quando informado.subjectOwner:string, opcional, não aceitanull. JID de quem definiu o subject quando informado.subjectOwnerPn:string, opcional, não aceitanull. Phone number de quem definiu o subject quando informado.subjectOwnerUsername:string, opcional, não aceitanull. Username de quem definiu o subject quando informado.subjectTime:number, opcional, não aceitanull. Timestamp Unix do subject quando informado.creation:number, opcional, não aceitanull. Timestamp Unix de criacao quando informado.desc:string, opcional, não aceitanull. Descricao do grupo quando informada.descOwner:string, opcional, não aceitanull. JID de quem definiu a descricao quando informado.descOwnerPn:string, opcional, não aceitanull. Phone number de quem definiu a descricao quando informado.descOwnerUsername:string, opcional, não aceitanull. Username de quem definiu a descricao quando informado.descId:string, opcional, não aceitanull. ID da descricao quando informado.descTime:number, opcional, não aceitanull. Timestamp Unix da descricao quando informado.linkedParent:string, opcional, não aceitanull. Grupo/comunidade pai quando informado.restrict:boolean, opcional, não aceitanull. Restricao de edicao quando informada.announce:boolean, opcional, não aceitanull. Modo anuncio quando informado.memberAddMode:boolean, opcional, não aceitanull. Modo de adicao por membros quando informado.joinApprovalMode:boolean, opcional, não aceitanull. Modo de aprovacao de entrada quando informado.isCommunity:boolean, opcional, não aceitanull. Indica comunidade quando informado.isCommunityAnnounce:boolean, opcional, não aceitanull. Indica grupo de anuncios da comunidade quando informado.size:number, opcional, não aceitanull. Tamanho do grupo quando informado.ephemeralDuration:number, opcional, não aceitanull. Duracao de mensagens temporarias em segundos quando informada.inviteCode:string, opcional, não aceitanull. Codigo de convite quando informado.author:string, opcional, não aceitanull. Autor da alteracao quando informado.authorPn:string, opcional, não aceitanull. Phone number do autor quando informado.authorUsername:string, opcional, não aceitanull. Username do autor quando informado.
Observações
- O payload e array para compatibilidade com contratos de lista, mesmo quando uma entrega contem um grupo.
history.sync
Sincronizacao de historico recebida do WhatsApp.
Flag: historySync
Eventos internos: *events.HistorySync
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: HistorySyncWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_extended_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: history.syncBody
{
"data": {
"data": {
"syncType": "INITIAL_BOOTSTRAP"
},
"dateTime": "2026-07-04T18:00:00Z",
"type": "history.sync"
},
"event": "history.sync",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, obrigatório, não aceitanull. Tipo fixo do payload. Valores possíveis:history.sync.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.data:object, opcional, não aceitanull. Conteudo normalizado do evento de historico quando disponivel.
Valores possíveis
type:history.sync
Observações
- Payload dinamico porque o conteudo vem do proto de historico do whatsmeow.
identity.update
Mudanca de identidade criptografica de um contato.
Flag: identityUpdated
Eventos internos: *events.IdentityChange
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: IdentityUpdatedWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: identity.updateBody
{
"data": {
"dateTime": "2026-07-04T18:00:00Z",
"implicit": true,
"jid": "[email protected]"
},
"event": "identity.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
jid:string, obrigatório, não aceitanull. JID cuja identidade mudou.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.implicit:boolean, obrigatório, não aceitanull. Indica mudanca implicita reportada pelo whatsmeow.
Observações
- Sem observações adicionais.
labels.association
Associacao ou remocao de label em chat ou mensagem.
Flag: labelsAssociation
Eventos internos: *events.LabelAssociationChat, *events.LabelAssociationMessage
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: LabelsAssociationWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: labels.associationBody
{
"data": {
"action": "add",
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"labelId": "7",
"type": "chat"
},
"event": "labels.association",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, obrigatório, não aceitanull. Tipo de associacao. Valores possíveis:chat,message.chatJid:string, obrigatório, não aceitanull. JID da conversa.messageId:string, opcional, não aceitanull. ID da mensagem quando type=message.labelId:string, obrigatório, não aceitanull. ID da label.action:string, opcional, não aceitanull. Acao inferida quando labeled esta presente. Valores possíveis:add,remove.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 do processamento.additionalProperties:object, opcional, não aceitanull. Campos achatados do evento original.
Valores possíveis
type:chat,messageaction:add,remove
Observações
- Sem observações adicionais.
labels.edit
Criacao, alteracao ou remocao de label.
Flag: labelsEdit
Eventos internos: *events.LabelEdit
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: LabelsEditWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_extended_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: labels.editBody
{
"data": {
"color": 3,
"deleted": false,
"id": "12",
"name": "Cliente"
},
"event": "labels.edit",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
id:string, obrigatório, não aceitanull. ID da label, derivado de labelId.name:string, opcional, não aceitanull. Nome da label quando informado.color:number, opcional, não aceitanull. Cor da label quando informada.deleted:boolean, opcional, não aceitanull. Indica label removida quando informado.additionalProperties:object, opcional, não aceitanull. Campos achatados do evento original.
Observações
- O normalizador nao adiciona campo
typenemdateTimepara este evento.
media.retry
Resultado ou erro relacionado a tentativa de retry de midia.
Flag: mediaRetry
Eventos internos: *events.MediaRetry
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: MediaRetryWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: media.retryBody
{
"data": {
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"errorCode": 404,
"hasCiphertext": true,
"keyFromMe": false,
"messageId": "ABC123",
"senderJid": "[email protected]"
},
"event": "media.retry",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
messageId:string, obrigatório, não aceitanull. ID da mensagem.chatJid:string, obrigatório, não aceitanull. JID da conversa.senderJid:string, opcional, não aceitanull. JID do remetente quando disponivel; omitido quando ausente.keyFromMe:boolean, obrigatório, não aceitanull. Indica se a mensagem e da propria instancia.hasCiphertext:boolean, obrigatório, não aceitanull. Indica se o evento carregou ciphertext.errorCode:number, opcional, não aceitanull. Codigo de erro quando informado; omitido quando ausente.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.
Observações
- Ciphertext e IV recebidos pelo whatsmeow nao sao expostos no webhook.
messages.delete
Mensagem removida localmente pelo evento DeleteForMe.
Flag: messagesDeleted
Eventos internos: *events.DeleteForMe
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: MessageDeletedWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: messages.deleteBody
{
"data": {
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"deleteMedia": true,
"fromFullSync": false,
"keyFromMe": false,
"messageId": "ABC123",
"messageTime": "2026-07-04T17:59:00Z",
"senderJid": "[email protected]"
},
"event": "messages.delete",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
chatJid:string, obrigatório, não aceitanull. JID da conversa.senderJid:string, opcional, não aceitanull. JID do remetente quando disponivel; omitido quando ausente.keyFromMe:boolean, obrigatório, não aceitanull. Indica se a mensagem era da propria instancia.messageId:string, obrigatório, não aceitanull. ID da mensagem apagada.deleteMedia:boolean, obrigatório, não aceitanull. Indica se a midia local deve ser removida.fromFullSync:boolean, obrigatório, não aceitanull. Indica se veio de sincronizacao completa.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.messageTime:string, opcional, não aceitanull. Timestamp RFC3339 UTC original da mensagem quando informado; omitido quando ausente.
Observações
- Sem observações adicionais.
messages.star
Marcacao ou desmarcacao de estrela em mensagem.
Flag: messagesStarred
Eventos internos: *events.Star
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: MessageStarredWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: messages.starBody
{
"data": {
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"fromFullSync": false,
"keyFromMe": false,
"messageId": "ABC123",
"senderJid": "[email protected]",
"starred": true
},
"event": "messages.star",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
chatJid:string, obrigatório, não aceitanull. JID da conversa.senderJid:string, opcional, não aceitanull. JID do remetente quando disponivel; omitido quando ausente.keyFromMe:boolean, obrigatório, não aceitanull. Indica se a mensagem e da propria instancia.messageId:string, obrigatório, não aceitanull. ID da mensagem.starred:boolean, obrigatório, não aceitanull. true quando marcada com estrela.fromFullSync:boolean, obrigatório, não aceitanull. Indica se veio de sincronizacao completa.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.
Observações
- Sem observações adicionais.
messages.undecryptable
Mensagem recebida sem possibilidade de descriptografia.
Flag: messagesUndecryptable
Eventos internos: *events.UndecryptableMessage
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: MessageUndecryptableWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: messages.undecryptableBody
{
"data": {
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"decryptFailMode": "hide",
"isUnavailable": true,
"keyFromMe": false,
"keyId": "ABC123",
"senderJid": "[email protected]",
"unavailableType": "view_once"
},
"event": "messages.undecryptable",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
keyId:string, obrigatório, não aceitanull. ID da chave/mensagem que falhou.chatJid:string, obrigatório, não aceitanull. JID da conversa.senderJid:string, opcional, não aceitanull. JID do remetente quando disponivel; omitido quando ausente.keyFromMe:boolean, obrigatório, não aceitanull. Indica se a mensagem e da propria instancia.isUnavailable:boolean, obrigatório, não aceitanull. Indica se o conteudo foi marcado como indisponivel.unavailableType:string, opcional, não aceitanull. Tipo de indisponibilidade. Valores possíveis:view_once.decryptFailMode:string, opcional, não aceitanull. Modo de falha reportado. Valores possíveis:hide.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.
Valores possíveis
unavailableType:view_oncedecryptFailMode:hide
Observações
- Campos vazios sao omitidos por omitempty.
messages.update
Atualizacao de recibo/status de uma mensagem ja conhecida.
Flag: messagesUpdated
Eventos internos: *events.Receipt
Persistência: Requer DATABASE_SAVE_MESSAGE_UPDATE=true. O handler tenta localizar a mensagem, persiste a atualizacao e so entao entrega.
Flag de persistência: DATABASE_SAVE_MESSAGE_UPDATE
Tipo de data: object
DTO/normalizador: MessageUpdateWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/event_persistence.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: messages.updateBody
{
"data": {
"dateTime": "2026-07-04T18:05:00Z",
"messageId": 1024,
"status": "read"
},
"event": "messages.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
messageId:number, obrigatório, não aceitanull. ID interno da mensagem persistida.status:string, obrigatório, não aceitanull. Status normalizado do recibo. Valores possíveis:delivered,sent,read,played,server_error,retry,unknown.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do recibo; usa o timestamp do evento ou o horario do processamento.
Valores possíveis
status:delivered,sent,read,played,server_error,retry,unknown
Observações
- Quando a mensagem referenciada nao e encontrada, o evento e descartado apos as tentativas configuradas no handler.
messages.upsert
Mensagem recebida e persistida pela aplicacao.
Flag: messagesUpsert
Eventos internos: *events.Message, *events.FBMessage
Persistência: Requer DATABASE_SAVE_DATA_NEW_MESSAGE=true. A mensagem e persistida com CreateOrIgnore e relida antes da entrega.
Flag de persistência: DATABASE_SAVE_DATA_NEW_MESSAGE
Tipo de data: object
DTO/normalizador: MessageWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/event_persistence.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: messages.upsertBody
{
"data": {
"content": {
"text": "Ola"
},
"device": "ios",
"id": 1024,
"isGroup": false,
"keyFromMe": false,
"keyLid": null,
"keyParticipant": null,
"keyParticipantLid": null,
"keyRemoteJid": "[email protected]",
"messageTimestamp": 1783188000,
"messageType": "conversation",
"metadata": null,
"pushName": "Cliente"
},
"event": "messages.upsert",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
id:number, obrigatório, não aceitanull. ID interno da mensagem.keyRemoteJid:string | null, obrigatório, aceitanull. JID remoto da mensagem.keyLid:string | null, obrigatório, aceitanull. LID remoto da mensagem.keyFromMe:boolean, obrigatório, não aceitanull. Indica se a mensagem foi enviada pela propria instancia.keyParticipant:string | null, obrigatório, aceitanull. Participante em mensagens de grupo.keyParticipantLid:string | null, obrigatório, aceitanull. LID do participante em mensagens de grupo.pushName:string | null, obrigatório, aceitanull. Nome exibido do remetente quando conhecido.messageType:string, obrigatório, não aceitanull. Tipo normalizado da mensagem.content:object, obrigatório, não aceitanull. Conteudo normalizado da mensagem.messageTimestamp:number, obrigatório, não aceitanull. Timestamp Unix em segundos.device:string | null, obrigatório, aceitanull. Dispositivo/origem inferida da mensagem.isGroup:boolean, obrigatório, não aceitanull. Indica se a mensagem pertence a grupo.metadata:object | null, obrigatório, aceitanull. Metadados adicionais normalizados.
Observações
- Se a persistencia ou a releitura da mensagem falhar, o webhook nao e emitido.
news.letter
Eventos relacionados a newsletters/canais.
Flag: newsLetter
Eventos internos: *events.NewsletterJoin, *events.NewsletterLeave, *events.NewsletterLiveUpdate, *events.NewsletterMessageMeta, *events.NewsletterMuteChange
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: NewsLetterWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_extended_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: news.letterBody
{
"data": {
"dateTime": "2026-07-04T18:00:00Z",
"muted": true,
"newsletterJid": "120363000000000000@newsletter",
"type": "mute.change"
},
"event": "news.letter",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, obrigatório, não aceitanull. Subtipo do evento de newsletter. Valores possíveis:join,leave,live.update,message.meta,mute.change.newsletterJid:string, opcional, não aceitanull. JID da newsletter quando a origem traz id ou jid.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 do processamento.additionalProperties:object, opcional, não aceitanull. Campos achatados do evento original.
Valores possíveis
type:join,leave,live.update,message.meta,mute.change
Observações
- Sem observações adicionais.
presence.updated
Atualizacao de presenca de usuario ou presenca em chat.
Flag: presenceUpdated
Eventos internos: *events.ChatPresence, *events.Presence
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: PresenceUpdatedWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: presence.updatedBody
{
"data": {
"chatJid": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"media": "text",
"senderJid": "[email protected]",
"state": "composing"
},
"event": "presence.updated",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, opcional, não aceitanull. Tipo fixo presence no payload vindo de *events.Presence. Valores possíveis:presence.chatJid:string, opcional, não aceitanull. JID do chat no payload de ChatPresence.senderJid:string, opcional, não aceitanull. JID do remetente no payload de ChatPresence.state:string, opcional, não aceitanull. Estado de presenca no payload de ChatPresence.media:string, opcional, não aceitanull. Tipo de midia quando presenca esta relacionada a midia.jid:string, opcional, não aceitanull. JID no payload de Presence.unavailable:boolean, opcional, não aceitanull. Indica indisponibilidade no payload de Presence.lastSeen:string, opcional, não aceitanull. Ultimo visto quando informado.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 do processamento.
Valores possíveis
type:presence
Observações
- O formato varia entre ChatPresence e Presence; use os campos presentes no payload recebido.
profile.picture.update
Atualizacao de foto de perfil da propria instancia ou de outro JID.
Flag: profilePictureUpdated
Eventos internos: *events.Picture
Persistência: Quando o JID e a propria instancia, atualiza profilePicUrl da instancia antes da entrega. Para outros JIDs nao ha persistencia especifica.
Tipo de data: object
DTO/normalizador: ProfilePictureUpdatedWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: profile.picture.updateBody
{
"data": {
"author": "[email protected]",
"dateTime": "2026-07-04T18:00:00Z",
"isGroup": true,
"jid": "[email protected]",
"pictureId": "pic-123",
"remove": false
},
"event": "profile.picture.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
jid:string, obrigatório, não aceitanull. JID que teve a foto alterada.author:string, opcional, não aceitanull. JID do autor quando informado; omitido quando vazio.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.remove:boolean, obrigatório, não aceitanull. Indica remocao de foto.pictureId:string, opcional, não aceitanull. ID da foto quando informado; omitido quando vazio.isGroup:boolean, obrigatório, não aceitanull. Indica se o JID pertence a grupo.
Observações
- Sem observações adicionais.
qrcode.updated
Novo QR Code disponivel para pareamento da instancia.
Flag: qrcodeUpdated
Eventos internos: QR channel
Persistência: Atualiza o status da instancia para qr_code antes da entrega.
Tipo de data: object
DTO/normalizador: QRCodeUpdatedWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/webhook/manager.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: qrcode.updatedBody
{
"data": {
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA",
"code": "2@abc",
"count": 1,
"expiresAt": "2026-07-04T18:01:00Z",
"expiresInSeconds": 60
},
"event": "qrcode.updated",
"instance": {
"connectionStatus": "qr_code",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": null
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
count:number, obrigatório, não aceitanull. Quantidade de QRs emitidos nesta tentativa.code:string, obrigatório, não aceitanull. Codigo bruto do QR Code.base64:string, obrigatório, não aceitanull. Imagem do QR Code em data URL base64.expiresInSeconds:number, obrigatório, não aceitanull. Tempo restante informado pelo canal de QR, em segundos.expiresAt:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC calculado para expiracao do QR Code.
Observações
- Evento emitido pelo fluxo de QR, nao diretamente por um struct de evento do whatsmeow.
send.message
Mensagem enviada pela API apos envio e persistencia bem-sucedidos.
Flag: sendMessage
Eventos internos: message service send result
Persistência: Persistida antes da entrega pelo fluxo de envio de mensagens da API.
Tipo de data: object
DTO/normalizador: MessageWebhookData
Campos dinâmicos: não
Implementado em: internal/message/service.go, internal/message/audio.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: send.messageBody
{
"data": {
"content": {
"text": "Mensagem enviada"
},
"device": "web",
"id": 2048,
"isGroup": false,
"keyFromMe": true,
"keyLid": null,
"keyParticipant": null,
"keyParticipantLid": null,
"keyRemoteJid": "[email protected]",
"messageTimestamp": 1783188000,
"messageType": "conversation",
"metadata": null,
"pushName": null
},
"event": "send.message",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
id:number, obrigatório, não aceitanull. ID interno da mensagem.keyRemoteJid:string | null, obrigatório, aceitanull. JID remoto da mensagem.keyLid:string | null, obrigatório, aceitanull. LID remoto da mensagem.keyFromMe:boolean, obrigatório, não aceitanull. Indica se a mensagem foi enviada pela propria instancia.keyParticipant:string | null, obrigatório, aceitanull. Participante em mensagens de grupo.keyParticipantLid:string | null, obrigatório, aceitanull. LID do participante em mensagens de grupo.pushName:string | null, obrigatório, aceitanull. Nome exibido do remetente quando conhecido.messageType:string, obrigatório, não aceitanull. Tipo normalizado da mensagem.content:object, obrigatório, não aceitanull. Conteudo normalizado da mensagem.messageTimestamp:number, obrigatório, não aceitanull. Timestamp Unix em segundos.device:string | null, obrigatório, aceitanull. Dispositivo/origem inferida da mensagem.isGroup:boolean, obrigatório, não aceitanull. Indica se a mensagem pertence a grupo.metadata:object | null, obrigatório, aceitanull. Metadados adicionais normalizados.
Observações
- Usa o mesmo DTO de messages.upsert, mas a origem e o envio pela propria API.
- Quando uma mensagem e aceita com options.mentionAll=true, o mesmo evento send.message tambem entrega o resultado definitivo do processamento assincrono. Nesse caso, data contem processId, status, mentionAll, externalAttributes e, em caso de sucesso, data.messageId, data.remoteJid, data.participantCount e data.timestamp. Em caso de falha, contem error.code e error.message.
settings.update
Atualizacao de configuracoes do usuario/instancia.
Flag: settingsUpdated
Eventos internos: *events.PushNameSetting, *events.UserStatusMute
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: SettingsUpdatedWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/whatsapp/webhook_events.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: settings.updateBody
{
"data": {
"dateTime": "2026-07-04T18:00:00Z",
"fromFullSync": false,
"name": "Minha instancia",
"type": "push.name"
},
"event": "settings.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, obrigatório, não aceitanull. Subtipo de configuracao. Valores possíveis:push.name,user.status.mute.jid:string, opcional, não aceitanull. JID afetado quando o subtipo informar.name:string, opcional, não aceitanull. Nome configurado no subtipo push.name.muted:boolean, opcional, não aceitanull. Estado de mute no subtipo user.status.mute.fromFullSync:boolean, obrigatório, não aceitanull. Indica se veio de sincronizacao completa.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 UTC do evento ou do processamento.
Valores possíveis
type:push.name,user.status.mute
Observações
- Sem observações adicionais.
status.instance
Eventos de estado operacional ou avisos da instancia.
Flag: statusInstance
Eventos internos: *events.ClientOutdated, *events.TemporaryBan, *events.OfflineSyncPreview, *events.OfflineSyncCompleted, *events.PrivacySettings, *events.AppState, *events.AppStateSyncComplete, *events.AppStateSyncError, *events.AccountReachoutTimelock
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: InstanceStatusWebhookData
Campos dinâmicos: sim
Implementado em: internal/whatsapp/service.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: status.instanceBody
{
"data": {
"data": {
"count": 185
},
"status": "completed",
"type": "offline.sync.completed"
},
"event": "status.instance",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
type:string, obrigatório, não aceitanull. Subtipo do status da instancia.status:string, opcional, não aceitanull. Status textual do subtipo; omitido quando vazio.message:string, opcional, não aceitanull. Mensagem tecnica ou humana; omitida quando vazia.data:object, opcional, não aceitanull. Dados adicionais do subtipo; omitido quando ausente.
Valores possíveis
type:client.outdated,temporary.ban,offline.sync.preview,offline.sync.completed,privacy.settings,app.state,app.state.sync.completed,app.state.sync.error,account.reachout.timelock
Observações
- Sem observações adicionais.
user.about.update
Atualizacao do recado/about de um usuario.
Flag: userAboutUpdated
Eventos internos: *events.UserAbout
Persistência: Nao persiste dados especificos antes da entrega do webhook.
Tipo de data: object
DTO/normalizador: UserAboutUpdatedWebhookData
Campos dinâmicos: não
Implementado em: internal/whatsapp/service.go, internal/webhook/payload.go
Requisição
POST /webhooks/codechat HTTP/1.1
Content-Type: application/json
x-webhook-event: user.about.updateBody
{
"data": {
"dateTime": "2026-07-04T18:00:00Z",
"jid": "[email protected]",
"status": "Disponivel"
},
"event": "user.about.update",
"instance": {
"connectionStatus": "online",
"externalAttributes": {},
"id": 1,
"name": "codechat",
"ownerJid": "[email protected]"
},
"timestamp": "2026-07-04T18:00:00Z"
}Campos de data
jid:string, obrigatório, não aceitanull. JID do usuario.status:string, opcional, não aceitanull. Texto do about quando informado.dateTime:string, obrigatório, não aceitanull. Timestamp RFC3339 do processamento.
Observações
- Sem observações adicionais.
Eventos não suportados ou ignorados
| Evento interno | Status | Motivo |
|---|---|---|
PairPasskeyConfirmation | intentionally_ignored | Evento interativo de pareamento com codigo; nao e contrato de webhook. |
PairPasskeyError | handled_without_webhook | Tratado como estado/log de pareamento; nao ha payload publico estavel. |
PairPasskeyRequest | intentionally_ignored | Contem desafio/chave publica de pareamento e nao e serializado para webhook. |
QRScannedWithoutMultidevice | handled_without_webhook | O canal de QR converte o caso em falha de pareamento; emissoes diretas futuras caem em log fallback. |
MediaRetryError | internal_only | Struct auxiliar de erro usada dentro do payload de media.retry. |
MexNotificationData | internal_only | Struct auxiliar para notificacoes MEX sem evento publico dedicado. |
NewsletterMessageMeta | internal_only | Struct auxiliar usada dentro de news.letter. |
