AllyOneCRM / Webhooks
Webhooks
Receba eventos do CRM na URL do seu sistema, assinados com HMAC-SHA256 — sem polling.
Cadastrar
POST/v1/webhooks
{
"name": "ERP — produção",
"url": "https://erp.suaempresa.com/webhooks/allyone",
"events": ["contact.created", "deal.won", "form.submitted"]
}
Exige a permissão integrations:manage (owner e admin, por padrão). A URL precisa ser pública: endereços internos, de loopback e de metadados de nuvem são recusados. A resposta 201 traz o secret usado na assinatura — guarde-o no seu cofre de segredos.
Eventos
| Evento | Quando dispara | data |
|---|---|---|
contact.created | Contato criado pela API ou pelo painel. | id, email, first_name, tags |
form.submitted | Formulário do CRM enviado. | form_id, form_name, contact_id, data |
deal.stage_changed | Negócio mudou de etapa. | deal_id, title, stage_id |
deal.won | Negócio marcado como ganho. | deal_id, title, value |
deal.lost | Negócio marcado como perdido. | deal_id, title |
contact.updated | Contato alterado pela API ou pelo painel. | id, fields (campos alterados) |
deal.created | Negócio criado. | deal_id, title, value, stage_id, contact_id |
survey.responded | Pesquisa (NPS/CSAT) respondida. | survey_id, contact_id, score |
campaign.completed | Campanha concluída (fim do envio, limite atingido, audiência vazia ou conclusão manual). | campaign_id, name, sent, failed, reason |
journey.enrolled | Contato inscrito numa jornada. | journey_id, contact_id, enrollment_id |
journey.completed | Contato chegou ao fim da jornada. | journey_id, contact_id, enrollment_id |
contact.unsubscribed | Descadastro pelo link (por canal), "SAIR" no WhatsApp ou eliminação a pedido do titular (LGPD). | contact_id, channel, reason |
score.rule_fired | Regra de pontuação aplicada a um contato. | regra e contato |
Payload
{
"id": "5b0d2c8e-7f1a-4c3e-9a51-2e6c0b7d4f10",
"event": "deal.won",
"timestamp": "2026-10-01T14:03:11.204Z",
"tenant_id": "4f1c...",
"data": { "deal_id": "9a2e...", "title": "Plano anual — ACME", "value": 18000 }
}
O tipo do evento está no campo event do corpo. Cada entrega tem um id próprio (também no cabeçalho X-AllyOne-Delivery), igual em todas as tentativas — use-o para descartar repetições.
Validar a assinatura
Content-Type: application/json
X-AllyOne-Signature: sha256=<hex>
X-AllyOne-Event: deal.won
X-AllyOne-Delivery: 5b0d2c8e-7f1a-4c3e-9a51-2e6c0b7d4f10
User-Agent: AllyOne-CRM-Webhook/1.0
X-AllyOne-Signature é o HMAC-SHA256 do corpo bruto com o secret do webhook. Calcule sobre os bytes recebidos, antes de fazer parse do JSON, e compare em tempo constante:
import crypto from 'node:crypto'
// rawBody: o corpo EXATO recebido (Buffer/string), antes de qualquer JSON.parse
function isValid(rawBody, header, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex')
const a = Buffer.from(expected), b = Buffer.from(header ?? '')
return a.length === b.length && crypto.timingSafeEqual(a, b)
}
import hmac, hashlib
def is_valid(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header or "")
Entrega e falhas
- Sucesso é qualquer resposta
2xxem até 10 segundos. Redirecionamentos não são seguidos. - Em falha, o CRM tenta de novo na hora: até 3 tentativas no total, com 1 s e 2 s de intervalo. Depois disso não há nova tentativa.
- Cada entrega fica registrada em
GET /v1/webhooks/:id/deliveries(as 50 mais recentes, com status HTTP, número de tentativas e sucesso) — use para conciliar o que falhou. - Responda
2xxrápido e processe numa fila do seu lado: um endpoint lento consome as 3 tentativas em segundos.
Gerenciar
| Rota | O que faz |
|---|---|
GET /v1/webhooks | Lista os webhooks do tenant. |
GET /v1/webhooks/events | Eventos aceitos na assinatura. |
PATCH /v1/webhooks/:id | Altera name, url, events ou active. |
POST /v1/webhooks/:id/rotate-secret | Gera um secret novo (o antigo deixa de valer na hora). |
GET /v1/webhooks/:id/deliveries | Histórico de entregas. |
DELETE /v1/webhooks/:id | Remove. |
