Docs / API

Los webhooks te permiten recibir eventos en tiempo real en un endpoint HTTPS controlado por vos. Cada evento se envía como un POST JSON firmado con HMAC.

Eventos disponibles

EventoCuándo se dispara
DMARC_THRESHOLD_REACHEDCompliance cae debajo del umbral configurado
NEW_LOOKALIKE_DETECTEDSe detecta un lookalike nuevo
RBL_LISTEDUna IP tuya aparece en un RBL
PHISHING_REPORTEDUn empleado reporta un phishing
PHISHING_CLUSTEREDUn cluster de phishing supera N reportes
SSPM_HIGH_RISK_APP_ADDEDNueva app OAuth con scopes peligrosos
SSPM_NEW_INBOX_RULENueva inbox rule sospechosa
TAKEDOWN_RESOLVEDUn takedown pasa a resolved
AWARENESS_CAMPAIGN_COMPLETEDCampaña de simulación termina
AUDIT_LOG_ANOMALYAnomalía en el audit log (login desde geo raro, etc.)

Registrar un webhook

curl -X POST https://platform.emate.cloud/v1/webhooks \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your.endpoint/emate-hook",
    "events": ["PHISHING_REPORTED", "NEW_LOOKALIKE_DETECTED"],
    "secret": "generated-server-side-if-omitted"
  }'

Respuesta:

{
  "id": "wh_abc123",
  "url": "https://your.endpoint/emate-hook",
  "events": ["PHISHING_REPORTED", "NEW_LOOKALIKE_DETECTED"],
  "secret": "whsec_xyz789...",
  "created_at": "2026-07-08T10:00:00Z"
}

Guardá el secret — lo vas a necesitar para verificar la firma.

Formato del payload

{
  "id": "evt_abc123",
  "type": "PHISHING_REPORTED",
  "created_at": "2026-07-08T14:22:00Z",
  "tenant_id": "d3d3...",
  "data": {
    "phishing_id": "...",
    "from_domain": "phish.example",
    "from_address": "[email protected]",
    "subject": "...",
    "ai_classification": "credential_phishing",
    "cluster_key": "cluster-invoice-2026Q3",
    "iocs": {
      "domains": ["phish.example"],
      "ips": ["203.0.113.42"],
      "urls": ["https://phish.example/login"]
    }
  }
}

Verificar la firma

Cada request incluye headers:

  • X-eMate-Signature-Timestamp — Unix timestamp del envío.
  • X-eMate-Signature — hex de HMAC-SHA256(secret, "{timestamp}.{body}").

Ejemplo Python:

import hmac
import hashlib
import time

def verify(request_body: bytes, timestamp: str, signature: str, secret: str) -> bool:
    # Rechazar requests > 5 min viejas (protección contra replay).
    if abs(time.time() - int(timestamp)) > 300:
        return False
    signed = f"{timestamp}.{request_body.decode()}".encode()
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Ejemplo Node.js:

import crypto from 'crypto';

function verify(rawBody, timestamp, signature, secret) {
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const signed = `${timestamp}.${rawBody}`;
  const expected = crypto.createHmac('sha256', secret).update(signed).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

Retries

Si tu endpoint devuelve algo distinto de 2xx (o timeout > 10s), la plataforma reintenta con backoff exponencial:

  • Intento 1: inmediato.
  • Intento 2: +30s.
  • Intento 3: +2min.
  • Intento 4: +10min.
  • Intento 5: +1h.
  • Intento 6: +6h.
  • Intento 7: +24h.

Después del intento 7, la delivery queda como failed y podés redisparar manualmente desde /v1/webhooks/{id}/deliveries o desde la UI en Settings → Webhooks → Deliveries.

Best practices

  • Devuelve 200 rápido. Si necesitás procesar largo, aceptá el webhook, encolá el work y devolvé 200. Los timeouts frustran retries innecesariamente.
  • Idempotencia. La plataforma puede reintentar la misma delivery. Usá evt_id como key de idempotencia.
  • Ordenamiento. Los webhooks no garantizan orden. Si necesitás secuencia, ordená por created_at en tu lado.
  • Retention. Guardamos deliveries por 90 días. Después del período, no se puede redisparar.