Zoosial
docs
InicioWebhooks de salida
Volver al sitio Volver al Dashboard
Zoosial
Buscar en docs...
⌘K
APIs

Webhooks de salida

Tus endpoints reciben eventos firmados cuando pasa algo en tus cuentas conectadas. Reintentos con backoff si tu endpoint falla.

Gestión

POST
/hooks
{ url(https), events[], secret? } → devuelve secret una sola vez (para verificar la firma).
GET
/hooks · /hooks/:id
Lista o detalle.
PATCHDELETE
/hooks/:id
Edita url/events/active, o borra.
POST
/hooks/:id/test
Encola una entrega de prueba (webhook.test).
GET
/hooks/:id/deliveries
Historial de entregas (éxito/fallo, reintentos) de un webhook.

Verificar la firma

Cada entrega lleva X-SocialGate-Signature: sha256=<hmac> (HMAC del body crudo, tal cual llega, con tu secret), más X-SocialGate-Event y X-SocialGate-Delivery. No re-serialices el JSON antes de comparar: el orden de las claves cambia y la firma deja de coincidir.

Alcance por perfil

Un webhook creado con una API key acotada a ciertos perfiles (scope: 'profiles') solo recibe los eventos de esos perfiles. Creado con una key sin restricción, recibe los de todo el owner.

Esto importa si eres una agencia o un integrador: si le das a alguien una key limitada al perfil de su cliente, el webhook que registre no verá los leads ni los mensajes del resto de tus perfiles. Esa key tampoco puede listar, editar ni consultar el historial de entregas de webhooks que cubran perfiles fuera de su alcance — responden 403.

Límites: 20 webhooks por cuenta y un ping de prueba cada 30 segundos por webhook.

Forma del payload

Todos los eventos comparten el mismo sobre y llevan lo específico anidado en data — no en la raíz.

JSON
{
  "event": "message.received",
  "ownerId": "…",
  "profileId": "prof_123",
  "data": { "accountId": "acc_456", "from": "34600000000", "text": "hola", "msgId": "…", "platform": "whatsapp" }
}

Eventos disponibles

post.scheduled
post.published
post.partial
post.failed
post.platform.failed
account.connected
account.needs_reconnection
account.disconnected
lead.received
message.received
automation.triggered
webhook.test
account.disconnected lo dispara DELETE /accounts/:id y DELETE /adaccounts/:id — es decir, cuando la desconexión la inicia alguien desde Zoosial. Si el usuario revoca el permiso desde Facebook, eso llega como account.needs_reconnection, no como disconnected.

Para probar tu receptor sin esperar a que pase nada real: POST /hooks/:id/test encola un webhook.test, y el simulador de leads emite un lead.received con datos realistas.

JavaScript
const crypto = require("crypto");

app.post("/hooks/sc", express.raw({ type: "application/json" }), (req, res) => {
  const expected = "sha256=" + crypto.createHmac("sha256", WEBHOOK_SECRET).update(req.body).digest("hex");
  if (req.headers["x-socialgate-signature"] !== expected) return res.sendStatus(401);
  // req.headers["x-socialgate-event"] === "message.received", etc.
  res.json({ ok: true });
});
En esta página
Gestión Verificar la firma Alcance por perfil Forma del payload Eventos disponibles
¿Tienes dudas?
Nuestro equipo responde en menos de 2h
Contactar soporte