Webhooks
Receba eventos em tempo real — nova conversa, lead capturado, handoff solicitado — com verificação HMAC.
Webhooks enviam eventos do Simple Agent para o seu servidor em tempo real. Use para sincronizar leads com seu CRM, disparar automações ou registrar conversas no seu sistema.
Configurar um webhook
- Dashboard → Configurações → Webhooks → Adicionar endpoint
- Insira a URL do seu servidor
- Selecione os eventos que deseja receber
- Salve — o Simple Agent envia um evento de verificação imediatamente
Eventos disponíveis
| Evento | Quando ocorre |
|---|---|
conversation.created |
Primeira mensagem do usuário |
conversation.ended |
Conversa encerrada (timeout ou usuário fechou) |
message.received |
Cada mensagem do usuário |
message.sent |
Cada resposta do agent |
lead.captured |
Email do usuário coletado via Action |
handoff.requested |
Usuário solicitou atendimento humano |
source.indexed |
Fonte de treinamento indexada com sucesso |
source.failed |
Falha na indexação de fonte |
Formato do payload
{
"event": "lead.captured",
"id": "evt_01hwxyz...",
"created_at": "2026-05-14T10:30:00Z",
"agent_id": "ag_xxx",
"data": {
"lead": {
"email": "usuario@exemplo.com",
"name": "João Silva",
"phone": "+5511999999999"
},
"conversation_id": "conv_xxx",
"source_channel": "widget",
"session_locale": "pt-BR"
}
}
Verificação HMAC
O Simple Agent assina cada request com HMAC-SHA256 usando o Webhook Secret gerado no dashboard. Você deve verificar a assinatura para rejeitar requests não autorizados.
O header enviado:
X-Simple Agent-Signature: sha256=a4b7c3d2e1f0...
X-Simple Agent-Timestamp: 1715686800
Verificar em Node.js
import crypto from "crypto";
function verifyWebhook(
payload: string, // body como string bruta (não parsed)
signature: string, // header X-Simple Agent-Signature
timestamp: string, // header X-Simple Agent-Timestamp
secret: string // seu Webhook Secret
): boolean {
// Rejeitar requests com mais de 5 minutos
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) return false;
const signedPayload = `${timestamp}.${payload}`;
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(signedPayload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
// Em Express:
app.post("/webhook/simple-agent", express.raw({ type: "application/json" }), (req, res) => {
const isValid = verifyWebhook(
req.body.toString(),
req.headers["x-simpleagent-signature"] as string,
req.headers["x-simpleagent-timestamp"] as string,
process.env.SIMPLE AGENT_WEBHOOK_SECRET!
);
if (!isValid) return res.status(401).json({ error: "Invalid signature" });
const event = JSON.parse(req.body.toString());
// processar evento...
res.status(200).json({ received: true });
});
Verificar em Python
import hmac
import hashlib
import time
def verify_webhook(payload: bytes, signature: str, timestamp: str, secret: str) -> bool:
# Rejeitar requests antigos (>5 min)
if abs(time.time() - int(timestamp)) > 300:
return False
signed_payload = f"{timestamp}.{payload.decode()}"
expected = "sha256=" + hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Resposta esperada
Seu endpoint deve retornar HTTP 200 em até 10 segundos. Se não retornar 2xx, o Simple Agent considera falha e faz retry.
Política de retry:
| Tentativa | Delay |
|---|---|
| 1ª retry | 1 minuto |
| 2ª retry | 5 minutos |
| 3ª retry | 30 minutos |
| 4ª retry | 2 horas |
| 5ª retry | 8 horas |
Após 5 tentativas sem sucesso, o evento é descartado e aparece como failed no log de webhooks.
Log de deliveries
No dashboard → Configurações → Webhooks → Ver deliveries, você vê:
- Status de cada entrega (sucesso / falha)
- Payload enviado
- Resposta do seu servidor
- Botão Re-enviar para falhas
Reenviar manualmente via API
POST /v1/webhooks/{webhook_id}/deliveries/{delivery_id}/retry
curl -X POST https://simple-agent.me/api/v1/webhooks/wh_xxx/deliveries/del_xxx/retry \
-H "Authorization: Bearer af_live_xxx"
Dicas de segurança
- Nunca confie apenas no IP — sempre valide a assinatura HMAC
- Use
timingSafeEqualpara comparar assinaturas — evita timing attacks - Verifique o timestamp — rejeite eventos com mais de 5 minutos para prevenir replay attacks
- Salve o
event.id— ignore eventos com ID já processado (idempotência)