SmartCQ
Piattaforma

Webhook

Inoltra gli eventi del tuo tenant verso un sistema esterno (CRM, gestionale, data warehouse) con firma HMAC e retry automatico.

I webhook ti permettono di ricevere notifiche in tempo reale quando succede qualcosa nel tuo tenant SmartCQ. Sono utili se hai un CRM o un gestionale già in uso e vuoi mantenerlo allineato con quello che SmartCQ osserva (un contatto si è disiscritto, una campagna è completata, ecc.).

Quando usarli

  • Hai un CRM esterno: vuoi che si aggiorni quando un contatto cambia stato email (bounce, unsubscribe, segnalazione spam).
  • Hai una dashboard custom o un data warehouse: vuoi che riceva gli eventi appena succedono, senza fare polling.
  • Vuoi un audit trail interno: registri ogni cambio rilevante in un sistema terzo.

Eventi disponibili

EventoQuando si generaPayload
contact.email_status_changedLo stato email di un contatto cambia (bounce, unsubscribe, segnalazione spam, riattivazione){ contactId, email, from, to, reason, webhookEventType? }
campaign.completedUna campagna ha finito il dispatch (tutti i send chiamati, qualunque esito){ campaignId, name, kind, completedAt, stats }

Notacontact.email_status_changed copre in modo unificato bounce, segnalazione spam e disiscrizione. Il consumer legge from e to per capire la transizione. Non ci sono eventi paralleli email.bounced, email.complained, email.unsubscribed.

Puoi sottoscriverti a un evento specifico, a tutti gli eventi di uno scope (contact.*, campaign.*) o a tutti gli eventi (*).

Configurare un webhook

  1. Vai su Impostazioni → Webhook dal tuo tenant.
  2. Clicca Aggiungi webhook.
  3. Scegli il tipo di evento, inserisci l'URL del tuo endpoint e un'etichetta opzionale.
  4. SmartCQ genera un secret HMAC unico per quel webhook. Copialo subito: dopo non sarà più mostrato.

L'URL deve essere pubblicamente raggiungibile e accettare richieste POST con body JSON.

Come arrivano gli eventi

SmartCQ invia una richiesta POST al tuo URL con questi header:

Content-Type: application/json
User-Agent: SmartCQ-Webhook/1
x-smartcq-signature: sha256=<hex>
x-smartcq-event-id: <uuid>
x-smartcq-event-type: <type>
x-smartcq-event-version: <number>
x-smartcq-delivery-id: <uuid>

Il body ha questa struttura:

{
  "id": "<event-uuid>",
  "type": "contact.email_status_changed",
  "version": 1,
  "tenantId": "<tenant-uuid>",
  "createdAt": "2026-05-10T08:00:00.000Z",
  "payload": {
    "contactId": "...",
    "email": "...",
    "from": "active",
    "to": "bounced",
    "reason": "webhook",
    "webhookEventType": "email.bounced"
  }
}

Verifica firma HMAC

L'header x-smartcq-signature è calcolato come sha256=<hex(HMAC-SHA256(body, secret))> sul body raw della richiesta.

Esempio Node.js:

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody: string, header: string, secret: string): boolean {
  const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(header);
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

Esempio Python (Flask):

import hmac, hashlib

def verify(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)

Rispondi con un 2xx entro 8 secondi: se vai oltre o rispondi con errore, SmartCQ riprova.

Idempotency

Ogni delivery ha un x-smartcq-delivery-id univoco. Se il tuo endpoint è retry-safe, puoi ignorarlo. Altrimenti, salva l'id ricevuto e scarta i duplicati che hanno lo stesso x-smartcq-event-id (uguale per tutti i tentativi sullo stesso evento).

Retry esponenziale

Se la consegna fallisce (errore di rete o risposta non-2xx), SmartCQ riprova con backoff esponenziale:

TentativoDelay
1° retrydopo 1 minuto
2° retrydopo 5 minuti
3° retrydopo 30 minuti
4° retrydopo 2 ore
5° retrydopo 12 ore

Dopo 5 fallimenti consecutivi l'evento entra in stato parked e non viene più riprovato. Lo trovi nella sezione "Ultime consegne" della pagina webhook con badge rosso.

Nota — Il dispatcher di SmartCQ gira una volta al giorno sul piano attuale. La latenza tipica è quindi ~24h, accettabile per scenari di sincronizzazione asincrona (CRM esterno, data warehouse). Per scenari real-time c'è una roadmap su upgrade a frequenza oraria.

Disabilitare e cancellare

  • Disabilita un webhook: gli eventi successivi non vengono più inoltrati a quell'URL. Il webhook resta in lista, riattivabile in qualsiasi momento.
  • Elimina: rimuove definitivamente la subscription. Gli eventi storici restano visibili (audit-style) ma non saranno mai consegnati ad altri URL.

Buone pratiche

  • Mantieni l'endpoint snello: rispondi 2xx velocemente, accoda l'elaborazione vera in background.
  • Logga x-smartcq-event-id per tracciare lato tuo cosa hai ricevuto.
  • Non fidarti dell'ordine: gli eventi possono arrivare fuori ordine se uno è andato in retry. Riconcilia leggendo il timestamp createdAt.
  • Versiona il consumer: l'header x-smartcq-event-version ti dice lo schema del payload. SmartCQ bumpа la versione ai cambi breaking.

On this page