O que são webhooks?
Webhooks permitem que a SocialSell envie notificações automáticas para o seu sistema quando eventos ocorrem — como um novo contato criado, um negócio ganho ou uma mensagem recebida. Em vez de fazer polling constante na API, você recebe os dados imediatamente.
Eventos disponíveis
| Evento | Descrição |
|---|
contact.created | Um novo contato foi criado |
contact.updated | Um contato foi atualizado |
deal.created | Um novo negócio foi criado |
deal.stage.changed | Um negócio mudou de etapa no funil de venda |
deal.won | Um negócio foi marcado como ganho |
deal.lost | Um negócio foi marcado como perdido |
message.received | Uma nova mensagem foi recebida de um contato |
Criando uma assinatura
Requer o escopo write:webhooks e plano Growth ou superior.
curl -X POST https://api.socialsell.ai/v1/webhooks \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Notificações ERP",
"url": "https://meusistema.com/webhook/socialsell",
"events": ["contact.created", "deal.won", "deal.stage.changed"]
}'
A resposta inclui o campo secret — armazene-o com segurança para validar as entregas:
{
"data": {
"id": "664f1a2b3c4d5e6f78901234",
"name": "Notificações ERP",
"url": "https://meusistema.com/webhook/socialsell",
"events": ["contact.created", "deal.won", "deal.stage.changed"],
"status": "active",
"secret": "whsec_a1b2c3d4e5f6...",
"created_at": "2026-06-10T15:00:00.000Z"
}
}
O campo secret é retornado apenas na criação. Não é possível recuperá-lo depois. Armazene-o como variável de ambiente.
Cada evento entregue tem o seguinte formato:
{
"id": "evt_01jx8kz3m4n5p6q7r8s9t0u1v",
"event": "deal.won",
"organization_id": "664a1b2c3d4e5f6789012345",
"created_at": "2026-06-10T15:30:00.000Z",
"data": {
"id": "664f1a2b3c4d5e6f78901234",
"title": "Proposta Empresa XYZ",
"value": 5000,
"status": "won",
"pipeline": { "id": "...", "name": "Funil Principal" },
"stage": { "name": "Fechamento" },
"assigned_to": { "id": "...", "name": "João Silva" }
}
}
Validando a assinatura
Cada requisição inclui o header X-SocialSell-Signature com um HMAC-SHA256 do corpo usando seu secret:
X-SocialSell-Signature: sha256=a1b2c3d4e5f6...
Sempre valide a assinatura antes de processar o payload:
const crypto = require('crypto');
function validateWebhookSignature(body, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(typeof body === 'string' ? body : JSON.stringify(body))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// No seu handler Express:
app.post('/webhook/socialsell', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-socialsell-signature'];
const secret = process.env.SOCIALSELL_WEBHOOK_SECRET;
if (!validateWebhookSignature(req.body, signature, secret)) {
return res.status(401).send('Assinatura inválida');
}
const event = JSON.parse(req.body);
switch (event.event) {
case 'deal.won':
// processar negócio ganho
break;
case 'contact.created':
// processar novo contato
break;
}
res.status(200).send('OK');
});
Política de retentativas
A SocialSell tenta entregar cada evento com as seguintes regras:
- Timeout: 10 segundos para o endpoint responder
- Sucesso: resposta HTTP
2xx
- Falha: qualquer outro status ou timeout
- Retentativas: após falha, tenta novamente com backoff exponencial
- Desativação automática: após múltiplas falhas consecutivas, a assinatura é pausada automaticamente (campo
consecutive_failures)
Responda com 200 OK o mais rápido possível e processe o evento de forma assíncrona (ex: em uma fila). Isso evita timeouts causados por processamento lento.
Gerenciamento de assinaturas
Idempotência
Eventos podem ser entregues mais de uma vez em casos de falha. Use o campo id do evento para garantir idempotência no processamento:
// Armazene IDs já processados para evitar duplicatas
const processedEvents = new Set();
function handleWebhook(event) {
if (processedEvents.has(event.id)) return; // já processado
processedEvents.add(event.id);
// processar...
}