Skip to main content
Os webhooks avisam o seu sistema quando algo acontece na organização, como uma mensagem nova ou um chat criado. A cada evento, o Spark faz um POST em JSON para as URLs https que você cadastrou. A entrega, as retentativas e a assinatura ficam a cargo do Svix. Para chaves e autenticação da API, veja a Introdução à API.

Como funciona

  1. Você cria uma rota https no seu servidor para receber os eventos. Em geral, uma rota por integração.
  2. Você cadastra essa URL no portal de webhooks do Spark e escolhe os eventos que quer receber.
  3. A cada evento, sua rota verifica a assinatura, responde 2xx rápido e processa o evento em fila, se precisar de mais tempo.

Cadastrar uma URL

1

Abra a aba Webhooks

Com uma conta de administrador, abra Configurações → Desenvolvedores. Habilite o ambiente de desenvolvedores, se ainda não estiver ativo, e abra a aba Webhooks.
2

Crie o endpoint

No portal de webhooks, adicione a URL e escolha os eventos. O portal mostra o catálogo de eventos com exemplos.
3

Copie o segredo

Copie o segredo do endpoint (whsec_…). Você vai usá-lo para verificar a assinatura.
No mesmo portal você envia eventos de teste, vê cada tentativa de entrega e reenvia eventos. O portal é do Svix; a documentação dele explica como adicionar endpoints.

Formato da requisição

Cada entrega é um POST com Content-Type: application/json e este corpo: A requisição traz os cabeçalhos svix-id, svix-timestamp e svix-signature, usados na verificação de assinatura.
tenantId é o ID da organização no Spark.

Eventos disponíveis

Campos por evento

messages.received e messages.sent:
  • tenantId, chatId e occurredAt (ISO 8601).
  • chat: resumo do chat (id, platform, kind, entrypointId, name, status e outros).
  • message: a mensagem completa (texto, tipo, status, mídia, localização, remetente, dados de modelo e outros).
  • Só em messages.received: entrypointId, o canal que recebeu a mensagem.
  • Só em messages.sent: source, a origem do envio. Valores: public_api, user, automation, campaign, addon, integration, business_hours, business_app e system. business_app indica mensagem enviada pelo app WhatsApp Business num número em coexistência.
Em mensagens de áudio, o Spark espera a transcrição antes de entregar o evento, para que message.transcription venha preenchida. Se a transcrição falhar, o evento é entregue com message.transcription igual a null. chats.created:
  • tenantId, chatId, occurredAt e platform (whatsapp, whatsapp_lite, instagram, telegram ou lead_form).
  • entrypointId, quando o chat pertence a um canal.
  • acquisition, quando o lead veio do Meta Lead Ads: source (meta_lead_ads), commercialChannel, capturedAt e meta, com os IDs de página, formulário, campanha, conjunto de anúncios e anúncio.
entrypoints.whatsapp.connected e entrypoints.whatsapp.connection_failed:
  • tenantId, sessionId e occurredAt.
  • Em connected: entrypoint, com o mesmo formato da consulta da sessão.
  • Em connection_failed: status (failed ou expired) e reason.
entrypoints.whatsapp.history_synced:
  • tenantId, entrypointId, occurredAt, importedChats e importedMessages.
  • As mensagens e os chats importados não geram messages.received, messages.sent nem chats.created.
message_templates.*:
  • tenantId, occurredAt e template, no mesmo formato de GET /v1/message-templates/{id}.
  • Trate cada evento como um upsert pelo template.id. Em deleted, apague a cópia local.
  • Um status DELETED vindo da Meta chega como status_updated e não remove o modelo do Spark.
  • Alterações feitas pela própria API também geram eventos, para que outros sistemas da organização fiquem sincronizados.

Responder à entrega

O Svix considera a entrega bem-sucedida quando sua rota responde com status entre 200 e 299 dentro do prazo descrito na documentação do Svix. Se o processamento for demorado, salve o corpo ou coloque-o numa fila e responda 2xx logo em seguida. Se o seu framework aplica proteção CSRF a todas as rotas POST, desative essa proteção na rota que recebe os webhooks. Ela não usa cookie de sessão.

Retentativas e eventos repetidos

Timeouts, respostas 5xx e qualquer status fora de 2xx geram novas tentativas, com intervalos crescentes. O mesmo evento pode chegar mais de uma vez. Use o cabeçalho svix-id para identificar entregas repetidas e processar cada evento uma única vez.

Verificação de assinatura

A assinatura prova que a requisição saiu do Spark e que o corpo não foi alterado no caminho. Verifique todas as entregas em produção.
  • Use o corpo bruto da requisição, exatamente como chegou. Ler o JSON e serializar de novo invalida a assinatura.
  • Passe os cabeçalhos svix-id, svix-timestamp e svix-signature e o segredo do endpoint (whsec_…) para a classe Webhook do pacote svix ou para a biblioteca equivalente na sua linguagem.
O Svix tem exemplos para Next.js, Express, NestJS, FastAPI e outros frameworks em como verificar webhooks.

Tipos para o seu código

A especificação OpenAPI traz os webhooks em:
  • x-webhooks: uma entrada por evento (messages.received e os demais), com o corpo e exemplos.
  • components.schemas: os tipos de cada corpo, como SparkWebhookBodyMessagesReceived e MessagesReceivedWebhookPayload.
Você pode:

Leitura adicional