Skip to main content

Visão Geral

Webhooks permitem que seu sistema receba notificações em tempo real quando eventos ocorrem no Kinbox. Use webhooks para integrar o Kinbox com outros sistemas, automatizar processos e criar fluxos de trabalho personalizados.

Como Funcionam

Quando um evento ocorre no Kinbox (como uma nova mensagem ou atualização de conversa), o sistema envia uma requisição HTTP POST para a URL que você configurou, contendo dados sobre o evento.

Eventos Disponíveis

Nova Mensagem

Quando uma mensagem é recebida de um cliente

Conversa Criada

Quando uma nova conversa é iniciada

Conversa Atualizada

Quando uma conversa muda de status

Conversa Atribuída

Quando uma conversa é atribuída a um operador

Conversa Finalizada

Quando uma conversa é encerrada

Tag Aplicada

Quando uma tag é adicionada ou removida

Negócio Atualizado

Quando um negócio do CRM é modificado

Avaliação Recebida

Quando cliente avalia o atendimento

Configuração

1

Prepare seu endpoint

Crie um endpoint em seu sistema que receberá as requisições POST:
// Exemplo em Node.js/Express
app.post('/kinbox-webhook', (req, res) => {
  const event = req.body;
  
  // Processe o evento
  console.log('Evento recebido:', event.type);
  
  // Retorne 200 OK
  res.status(200).send('OK');
});
2

Configure no Kinbox

  1. Vá em Configurações > Integrações > Webhooks
  2. Clique em Adicionar Webhook
  3. Insira a URL do seu endpoint
  4. Selecione os eventos que deseja receber
3

Configure autenticação (opcional)

Adicione um secret token para validar que requisições vêm do Kinbox:
  • O Kinbox enviará o token no header X-Kinbox-Signature
  • Compare com o token configurado para validar origem
4

Teste o webhook

Use o botão “Testar Webhook” no Kinbox para enviar um evento de teste.
5

Ative o webhook

Após confirmar que funciona, ative o webhook para começar a receber eventos reais.

Estrutura dos Eventos

Todos os eventos seguem uma estrutura padrão:
{
  "eventId": "evt_1234567890",
  "eventType": "message.received",
  "timestamp": "2024-03-06T15:30:00Z",
  "workspaceId": "ws_abcdef123456",
  "data": {
    // Dados específicos do evento
  }
}

Campos Comuns

  • eventId: ID único do evento
  • eventType: Tipo do evento (veja lista abaixo)
  • timestamp: Data e hora do evento (ISO 8601)
  • workspaceId: ID do workspace onde o evento ocorreu
  • data: Objeto com dados específicos do evento

Tipos de Eventos

message.received

Disparado quando uma nova mensagem é recebida de um cliente.
{
  "eventType": "message.received",
  "data": {
    "messageId": "msg_123456",
    "conversationId": "conv_789012",
    "contactId": "contact_345678",
    "channelId": "channel_901234",
    "channelType": "whatsapp",
    "from": "5511999999999",
    "content": {
      "type": "text",
      "text": "Olá, preciso de ajuda"
    },
    "timestamp": "2024-03-06T15:30:00Z",
    "contact": {
      "id": "contact_345678",
      "name": "João Silva",
      "phone": "5511999999999",
      "email": "[email protected]"
    }
  }
}

conversation.created

Disparado quando uma nova conversa é iniciada.
{
  "eventType": "conversation.created",
  "data": {
    "conversationId": "conv_789012",
    "contactId": "contact_345678",
    "channelId": "channel_901234",
    "channelType": "whatsapp",
    "status": "open",
    "createdAt": "2024-03-06T15:30:00Z",
    "contact": {
      "id": "contact_345678",
      "name": "João Silva",
      "phone": "5511999999999",
      "email": "[email protected]"
    },
    "source": {
      "type": "google_ads",
      "campaign": "Campanha Verão 2024",
      "gclid": "abc123xyz789"
    }
  }
}

conversation.updated

Disparado quando uma conversa é atualizada (status, tags, etc).
{
  "eventType": "conversation.updated",
  "data": {
    "conversationId": "conv_789012",
    "changes": {
      "status": {
        "from": "open",
        "to": "closed"
      },
      "tags": {
        "added": ["resolvido", "satisfeito"],
        "removed": ["pendente"]
      }
    },
    "updatedAt": "2024-03-06T16:00:00Z",
    "updatedBy": {
      "type": "user",
      "userId": "user_123456",
      "name": "Maria Operadora"
    }
  }
}

conversation.assigned

Disparado quando uma conversa é atribuída a um operador.
{
  "eventType": "conversation.assigned",
  "data": {
    "conversationId": "conv_789012",
    "contactId": "contact_345678",
    "assignedTo": {
      "userId": "user_123456",
      "name": "Maria Operadora",
      "email": "[email protected]"
    },
    "assignedBy": {
      "type": "automation",
      "automationId": "auto_456789",
      "automationName": "Atribuição por Grupo"
    },
    "assignedAt": "2024-03-06T15:35:00Z"
  }
}

conversation.closed

Disparado quando uma conversa é finalizada.
{
  "eventType": "conversation.closed",
  "data": {
    "conversationId": "conv_789012",
    "contactId": "contact_345678",
    "closedAt": "2024-03-06T16:00:00Z",
    "closedBy": {
      "type": "user",
      "userId": "user_123456",
      "name": "Maria Operadora"
    },
    "duration": 1800,
    "messageCount": 15,
    "rating": {
      "score": 5,
      "comment": "Ótimo atendimento!"
    }
  }
}

tag.applied

Disparado quando tags são adicionadas ou removidas de uma conversa.
{
  "eventType": "tag.applied",
  "data": {
    "conversationId": "conv_789012",
    "action": "added",
    "tags": [
      {
        "id": "tag_123",
        "name": "urgente",
        "color": "#ff0000"
      }
    ],
    "appliedBy": {
      "type": "user",
      "userId": "user_123456",
      "name": "Maria Operadora"
    },
    "appliedAt": "2024-03-06T15:40:00Z"
  }
}

deal.updated

Disparado quando um negócio do CRM é atualizado.
{
  "eventType": "deal.updated",
  "data": {
    "dealId": "deal_789012",
    "conversationId": "conv_789012",
    "contactId": "contact_345678",
    "changes": {
      "stage": {
        "from": "Negociação",
        "to": "Fechado Ganho"
      },
      "value": {
        "from": 1000.00,
        "to": 1200.00
      }
    },
    "pipeline": {
      "id": "pipeline_123",
      "name": "Vendas"
    },
    "updatedAt": "2024-03-06T16:30:00Z",
    "updatedBy": {
      "type": "user",
      "userId": "user_123456",
      "name": "João Vendedor"
    }
  }
}

rating.received

Disparado quando um cliente avalia o atendimento.
{
  "eventType": "rating.received",
  "data": {
    "ratingId": "rating_123456",
    "conversationId": "conv_789012",
    "contactId": "contact_345678",
    "operatorId": "user_123456",
    "score": 5,
    "maxScore": 5,
    "comment": "Atendimento excelente, muito atencioso!",
    "ratedAt": "2024-03-06T16:05:00Z"
  }
}

Segurança

Validação de Assinatura

O Kinbox envia um header X-Kinbox-Signature com cada requisição. Use-o para validar que a requisição realmente vem do Kinbox:
const crypto = require('crypto');

function validateWebhook(req, secret) {
  const signature = req.headers['x-kinbox-signature'];
  const body = JSON.stringify(req.body);
  
  const hash = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  
  return signature === hash;
}

// Uso
app.post('/kinbox-webhook', (req, res) => {
  if (!validateWebhook(req, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Processe o evento
  // ...
  
  res.status(200).send('OK');
});

Whitelisting de IPs

Configure seu firewall para aceitar apenas requisições dos IPs do Kinbox:
52.67.123.45
52.67.123.46
52.67.123.47
Consulte a lista atualizada de IPs no painel do Kinbox.

HTTPS Obrigatório

Por segurança, o Kinbox apenas envia webhooks para URLs HTTPS.
Endpoints HTTP não são suportados. Certifique-se de usar HTTPS com certificado válido.

Retry e Confiabilidade

Política de Retry

Se seu endpoint não responder com sucesso (código 2xx), o Kinbox tentará reenviar:
  • 1ª tentativa: Imediata
  • 2ª tentativa: Após 1 minuto
  • 3ª tentativa: Após 5 minutos
  • 4ª tentativa: Após 30 minutos
  • 5ª tentativa: Após 2 horas
Após 5 tentativas falhas, o webhook é marcado como com falha.

Idempotência

Seu endpoint deve ser idempotente, ou seja, processar o mesmo evento múltiplas vezes deve ter o mesmo resultado que processar uma vez. Use o eventId para rastrear eventos já processados:
const processedEvents = new Set();

app.post('/kinbox-webhook', (req, res) => {
  const { eventId } = req.body;
  
  // Verifica se já processou este evento
  if (processedEvents.has(eventId)) {
    return res.status(200).send('Already processed');
  }
  
  // Processa o evento
  processEvent(req.body);
  
  // Marca como processado
  processedEvents.add(eventId);
  
  res.status(200).send('OK');
});

Timeout

Seu endpoint deve responder em até 30 segundos. Requisições que demoram mais são consideradas timeout.
Para processamentos demorados, responda imediatamente e processe assincronamente.

Webhooks Inbound

Além de enviar webhooks, o Kinbox pode receber webhooks de sistemas externos:

RD Station Marketing

Receba leads do RD Station automaticamente: URL do Webhook:
https://api4.kinbox.com.br/v3/webhooks/inbound/rdstation/create-contact
Configuração:
  1. Acesse o RD Station
  2. Vá em Integrações > Webhooks
  3. Configure a URL acima
  4. Selecione eventos de conversão
Leads recebidos do RD Station criam contatos automaticamente no Kinbox.

GreatPages

Receba leads de landing pages: URL do Webhook:
https://api4.kinbox.com.br/v3/webhooks/inbound/greatpages/create-contact
Configuração:
  1. Acesse GreatPages
  2. Edite sua landing page
  3. Configure webhook na seção de integrações
  4. Insira a URL acima

Monitoramento

Logs de Webhook

O Kinbox mantém logs de todas as entregas de webhook:
  1. Acesse Configurações > Integrações > Webhooks
  2. Clique no webhook desejado
  3. Veja a aba Logs
Informações disponíveis:
  • Data e hora da tentativa
  • Status HTTP retornado
  • Tempo de resposta
  • Payload enviado
  • Resposta recebida

Alertas

Configure alertas para ser notificado quando:
  • Webhook falha consecutivamente
  • Taxa de erro ultrapassa limite
  • Endpoint está lento

Duplicação de Webhooks

O Kinbox possui recurso para evitar webhooks duplicados, especialmente para canais oficiais do WhatsApp:
Webhooks duplicados são automaticamente filtrados
Use eventId único para garantir processamento único

Casos de Uso

Sincronizar com CRM Externo

Quando uma conversa é criada, crie/atualize contato no seu CRM:
app.post('/kinbox-webhook', async (req, res) => {
  const { eventType, data } = req.body;
  
  if (eventType === 'conversation.created') {
    const { contact } = data;
    
    // Sincroniza com CRM
    await crm.upsertContact({
      name: contact.name,
      phone: contact.phone,
      email: contact.email,
      source: 'kinbox'
    });
  }
  
  res.status(200).send('OK');
});

Notificar Equipe no Slack

Envie notificação no Slack quando nova mensagem urgente chega:
app.post('/kinbox-webhook', async (req, res) => {
  const { eventType, data } = req.body;
  
  if (eventType === 'message.received') {
    const { content, contact, conversationId } = data;
    
    // Se mensagem contém "urgente"
    if (content.text.toLowerCase().includes('urgente')) {
      await slack.sendMessage({
        channel: '#atendimento',
        text: `🚨 Mensagem urgente de ${contact.name}: ${content.text}`,
        link: `https://app.kinbox.com.br/conversations/${conversationId}`
      });
    }
  }
  
  res.status(200).send('OK');
});

Análise de Sentimento

Analise sentimento de mensagens e marque conversas:
app.post('/kinbox-webhook', async (req, res) => {
  const { eventType, data } = req.body;
  
  if (eventType === 'message.received') {
    const { content, conversationId } = data;
    
    // Analisa sentimento com IA
    const sentiment = await ai.analyzeSentiment(content.text);
    
    // Se negativo, adiciona tag
    if (sentiment === 'negative') {
      await kinbox.addTag(conversationId, 'cliente-insatisfeito');
    }
  }
  
  res.status(200).send('OK');
});

Automação de Respostas

Responda automaticamente baseado em regras:
app.post('/kinbox-webhook', async (req, res) => {
  const { eventType, data } = req.body;
  
  if (eventType === 'message.received') {
    const { content, conversationId } = data;
    const text = content.text.toLowerCase();
    
    // Horário de funcionamento
    if (text.includes('horário')) {
      await kinbox.sendMessage(conversationId, {
        text: 'Nosso horário de atendimento é de segunda a sexta, das 8h às 18h.'
      });
    }
    
    // Status de pedido
    if (text.includes('pedido')) {
      const orderId = extractOrderId(text);
      const status = await getOrderStatus(orderId);
      
      await kinbox.sendMessage(conversationId, {
        text: `Seu pedido ${orderId} está: ${status}`
      });
    }
  }
  
  res.status(200).send('OK');
});

Testando Webhooks

Localmente

Use ferramentas como ngrok para testar localmente:
# Inicie ngrok
ngrok http 3000

# Use a URL fornecida no Kinbox
https://abc123.ngrok.io/kinbox-webhook

Ferramentas de Teste

Algumas ferramentas úteis:

Evento de Teste

O Kinbox permite enviar evento de teste:
  1. Acesse Configurações > Webhooks
  2. Selecione o webhook
  3. Clique em Enviar Teste
  4. Escolha tipo de evento
  5. Verifique se seu endpoint recebeu

Limites

  • Máximo de webhooks: 10 por workspace
  • Timeout: 30 segundos
  • Tentativas: 5 retries com backoff exponencial
  • Payload máximo: 1MB

Troubleshooting

Verifique:
  1. URL está correta e acessível publicamente
  2. Endpoint usa HTTPS com certificado válido
  3. Firewall não está bloqueando IPs do Kinbox
  4. Webhook está ativo no painel
  5. Evento está selecionado nas configurações
Teste: Use “Enviar Teste” no painel para verificar conectividade.
Causas:
  • Seu endpoint está demorando para responder
  • Não está retornando código 2xx
  • Sistema está processando o mesmo eventId múltiplas vezes
Solução:
  1. Implemente verificação de eventId duplicado
  2. Responda rapidamente (< 30s)
  3. Retorne 200 OK após receber
Consulte logs:
  1. Acesse logs do webhook no painel
  2. Verifique erro específico
  3. Teste endpoint manualmente com curl
Erros comuns:
  • Timeout (endpoint muito lento)
  • SSL error (certificado inválido)
  • 401/403 (autenticação falhando)
  • 500 (erro no seu servidor)
Verifique:
  1. Secret token está correto
  2. Está usando algoritmo HMAC-SHA256
  3. Body está sendo hasheado como string JSON
  4. Comparação é case-sensitive
Debug:
console.log('Signature recebida:', req.headers['x-kinbox-signature']);
console.log('Signature calculada:', calculatedHash);
console.log('Body:', JSON.stringify(req.body));

Melhores Práticas

Valide assinatura de cada requisição
Implemente idempotência com eventId
Responda rapidamente e processe assincronamente
Configure monitoramento e alertas
Mantenha logs para debug
Trate erros graciosamente
Use queue para processar eventos em segundo plano
Teste diferentes cenários de falha

Recursos Adicionais

API Reference

Documentação completa da API

Cenários

Use Cenários para automações visuais

Exemplos no GitHub

Código de exemplo em várias linguagens

Suporte

Entre em contato para ajuda

Build docs developers (and LLMs) love