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
- Você cria uma rota
httpsno seu servidor para receber os eventos. Em geral, uma rota por integração. - Você cadastra essa URL no portal de webhooks do Spark e escolhe os eventos que quer receber.
- A cada evento, sua rota verifica a assinatura, responde
2xxrá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.Formato da requisição
Cada entrega é umPOST 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,chatIdeoccurredAt(ISO 8601).chat: resumo do chat (id,platform,kind,entrypointId,name,statuse 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_appesystem.business_appindica mensagem enviada pelo app WhatsApp Business num número em coexistência.
message.transcription venha preenchida. Se a transcrição falhar, o evento é entregue com message.transcription igual a null.
chats.created:
tenantId,chatId,occurredAteplatform(whatsapp,whatsapp_lite,instagram,telegramoulead_form).entrypointId, quando o chat pertence a um canal.acquisition, quando o lead veio do Meta Lead Ads:source(meta_lead_ads),commercialChannel,capturedAtemeta, 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,sessionIdeoccurredAt.- Em
connected:entrypoint, com o mesmo formato da consulta da sessão. - Em
connection_failed:status(failedouexpired) ereason.
entrypoints.whatsapp.history_synced:
tenantId,entrypointId,occurredAt,importedChatseimportedMessages.- As mensagens e os chats importados não geram
messages.received,messages.sentnemchats.created.
message_templates.*:
tenantId,occurredAtetemplate, no mesmo formato deGET /v1/message-templates/{id}.- Trate cada evento como um upsert pelo
template.id. Emdeleted, apague a cópia local. - Um status
DELETEDvindo da Meta chega comostatus_updatede 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 entre200 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, respostas5xx 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-timestampesvix-signaturee o segredo do endpoint (whsec_…) para a classeWebhookdo pacotesvixou para a biblioteca equivalente na sua linguagem.
Tipos para o seu código
A especificação OpenAPI traz os webhooks em:x-webhooks: uma entrada por evento (messages.receivede os demais), com o corpo e exemplos.components.schemas: os tipos de cada corpo, comoSparkWebhookBodyMessagesReceivedeMessagesReceivedWebhookPayload.
- Usar os tipos do SDK
sparkcrm, comoSparkWebhookBody. Veja TypeScript: webhooks e tipos. - Gerar tipos com Orval, openapi-typescript ou outra ferramenta a partir da especificação.
- Ver os exemplos de cada evento no catálogo do portal de webhooks.
Leitura adicional
- Introdução ao recebimento de webhooks, do Svix.
- Como verificar webhooks, do Svix.

