Skip to main content
Webhooks são o jeito recomendado de acompanhar a conversa em tempo real: em vez de consultar GET /v1/whatsapp/messages/{id} repetidamente, a Superlead envia um POST para a sua URL a cada transição de status, a cada mensagem recebida de um lead, a cada mensagem que a sua equipe envia pelo app do WhatsApp, a cada mudança de status de um template (aprovação, recusa, pausa) e a cada lead criado, alterado ou excluído. É assim que se resolve o caso clássico do WhatsApp: a Meta aceita um envio fora da janela de 24 horas (201 accepted) e o falha segundos depois, de forma assíncrona — a falha chega no seu webhook, com o motivo.

Configuração

1

Cadastre seu endpoint

No painel da Superlead, em Integrações → Webhooks, adicione a URL HTTPS que vai receber os eventos.
2

Guarde o signing secret

Na criação, você recebe um signing secret (whsec_...) — ele é exibido nesse momento; guarde em local seguro. É com ele que você verifica a autenticidade de cada entrega.
3

Responda 2xx rápido

Ao receber um evento, responda 2xx imediatamente e processe de forma assíncrona. Entregas sem 2xx são reenviadas automaticamente com backoff.

Evento whatsapp.message.updated

Disparado a cada transição de status de uma mensagem enviada: sent, delivered, read ou failed — um evento por transição.
  • Correlação: o wamid é o mesmo retornado por POST /v1/whatsapp/messages — use-o para casar o evento com o envio no seu sistema.
  • error: presente apenas quando status é failed. O code é o código numérico da Meta — o mesmo que aparece como upstream_code em GET /v1/whatsapp/messages/{id}. Para os significados, veja o catálogo de erros.
  • Para status de sucesso (sent, delivered, read), error vem null.

Evento whatsapp.message.received

Disparado quando um lead envia mensagem para o seu número. Exemplo com texto:
Conforme o type, o corpo traz o bloco correspondente no lugar de text: image/video/document (com link, mimeType, caption), audio (com voice), location, contacts ou interactive (resposta de botão/lista). Mensagens vindas de anúncios click-to-WhatsApp incluem também o bloco referral com os dados da campanha (sourceId, headline, ctwaClid, ad, campaign).
Receber whatsapp.message.received também é o sinal de que a janela de 24 horas reabriu para aquele lead — a partir dali, mensagens de texto livre voltam a ser aceitas.

Evento whatsapp.message.sent

Disparado quando alguém da sua equipe envia mensagem a um lead pelo app WhatsApp Business ou pelo WhatsApp Web/desktop (número em modo coexistência). É o sinal de que um humano está na conversa. Envios feitos pela sua própria integração via POST /v1/whatsapp/messages não geram este evento — você já sabe o que enviou, e o acompanhamento de entrega chega pelo whatsapp.message.updated.
  • Direção: from é o seu número conectado à Superlead e to é o telefone do lead — o espelho exato do whatsapp.message.received.
  • Correlação: use message.to para casar o evento com o lead no seu sistema (por exemplo, GET /v1/leads?phone=...).
  • Corpo por tipo: mesmos blocos do received — text, image, video, audio, document, sticker, location e contacts. Para video e document, o campo link vem omitido (o arquivo ainda não foi processado pela Superlead).

O objeto sender

Identifica quem enviou a mensagem:
Caso de uso: pausar seu bot quando um humano assume. Ao receber whatsapp.message.sent com sender.type === "human", pause as respostas automáticas para aquele message.to por um período (30 minutos, por exemplo) — um atendente entrou na conversa.

Evento whatsapp.template.updated

Disparado a cada mudança de status avisada pela Meta sobre um template da sua conta: aprovação, recusa, pausa, exclusão. É o jeito de saber que um template criado ou editado foi aprovado, sem consultar a API. Mudanças na nota de qualidade (quality score) e na categoria do template não são enviadas como este evento.
  • Correlação: templateUpdated.id é o mesmo tpl_... das rotas /v1/whatsapp/templates/{id}.
  • category: a categoria atual na Meta — pode ser diferente da que você pediu na criação. Pode ser null quando a Meta não informa.
  • rejectedReason e rejectionInfo: presentes na recusa; null nos demais eventos. Mesmo num evento REJECTED, rejectionInfo pode vir null quando a Meta não envia a explicação. O texto de rejectionInfo vem da Meta e costuma estar em inglês.
event não é o status do template. Alguns valores (FLAGGED, REINSTATED, LOCKED) são avisos, não status. Para decidir se um template pode ser enviado, trate APPROVED, REINSTATED e FLAGGED como “pode” (em FLAGGED a qualidade caiu e o template pode ser pausado) ou consulte GET /v1/whatsapp/templates/{id}. Valores novos podem surgir — ignore os que não conhecer.
Endpoints cadastrados antes deste evento não o recebem automaticamente: edite o endpoint em Integrações → Webhooks e marque Template Atualizado.

Eventos de lead

Os eventos lead.created, lead.updated e lead.deleted mantêm um sistema externo (CRM, dashboard, planilha) em dia com os seus leads sem consultar a API em laço.
  • lead é o mesmo recurso de GET /v1/leads/{id}, com as chaves em camelCase (entry_point vira entryPoint) e mais updatedAt. Em lead.created o formato é o mesmo.
  • Estado atual: o evento traz o lead como ele está no momento do envio, não só o que mudou. Grave pelo lead.id; se dois eventos chegarem fora de ordem, fique com o de maior updatedAt.
  • channel do envelope é null: eventos de lead não pertencem a um canal. O canal de origem do lead está em lead.channel.
  • lead.deleted traz só o id:
Os eventos de lead são opcionais: em Integrações → Webhooks, marque a categoria Leads no endpoint. Endpoints que já existiam não passam a recebê-los sozinhos.
Webhook é de melhor esforço. Para não perder nada, combine com a sincronização incremental: os eventos deixam o seu sistema em dia na hora, e uma passada periódica de GET /v1/leads?updated_since= (por exemplo, uma vez por dia) cobre qualquer evento que não tenha chegado.

Verificando a assinatura

Cada entrega vem assinada nos headers svix-id, svix-timestamp e svix-signature (infraestrutura Svix — mesmo padrão usado por Clerk, Resend e outros). Verifique com a biblioteca da sua linguagem e o signing secret do endpoint:
Rejeite entregas com assinatura inválida. Sem a verificação, qualquer um que descubra sua URL pode forjar eventos.

Boas práticas

  • Idempotência: reentregas acontecem (é a garantia de “pelo menos uma vez”). Use o id do evento (evt_...) como chave de deduplicação no seu lado.
  • Ordem não garantida: um delivered pode chegar depois de um read. Use o timestamp do evento, não a ordem de chegada. O evento de template não tem timestamp: use o createTime (hora da emissão do evento). Nos eventos de lead, use lead.updatedAt.
  • Webhook + polling: para fluxos críticos, combine os dois — webhook como caminho principal e GET /v1/whatsapp/messages/{id} como reconciliação periódica.