Webhook per lead e appuntamenti: invia le richieste a Zapier, Make, n8n o al tuo CRM

Webhook per lead e appuntamenti

Un webhook invia subito ogni nuova richiesta a un indirizzo a tua scelta. Lead e appuntamenti arrivano direttamente in Zapier, Make, n8n o nel tuo CRM, ad esempio per aprire un ticket o mandare un'email al tuo team commerciale.

Il webhook è disponibile dal piano Standard, vedi la pagina dei prezzi.

Configurazione

  1. Apri Dashboard → il tuo assistente → Funzioni.
  2. Nell'elenco scegli Inoltrare automaticamente (gruppo Trovare clienti). Lì trovi la sezione Webhook.
  3. Inserisci l'indirizzo, ad esempio l'URL "Catch Hook" di Zapier, e fai clic su Salva.
  4. Copia la Chiave segreta. Viene mostrata solo questa volta. Se serve, Nuova chiave ne crea una nuova.
  5. Scegli cosa inoltrare: Nuove richieste di contatto, Nuovi appuntamenti o entrambi.
  6. Prova invia una richiesta di esempio al tuo indirizzo.

L'indirizzo deve iniziare con https://, essere raggiungibile pubblicamente e usare la porta 443 o 8443. Gli indirizzi della tua rete interna (ad esempio localhost o 192.168.…) vengono rifiutati.

Eventi

EventoQuando
lead.createdÈ stato salvato un lead, dalla chat, da una telefonata o da un modulo dell'Action Bar.
booking.createdÈ stato prenotato un appuntamento.

Esempio: nuovo lead

{
  "id": "7a05fd6b-3b54-4235-b76e-7695c4ab13a3",
  "event": "lead.created",
  "createdAt": "2026-10-23T15:11:28.895Z",
  "data": {
    "leadId": "51f7f1e3-3e2f-471b-ade6-90959a5d3724",
    "source": "chat",
    "name": "Giulia Esempio",
    "email": "giulia@example.com",
    "phone": "+39 02 1234 5678",
    "interest": "Preventivo per una pompa di calore",
    "language": "it",
    "fields": { "Azienda": "Esempio Srl" },
    "sessionId": "861f9c24-11ab-4352-b326-5670b0196fc0",
    "createdAt": "2026-10-23T15:11:28.742Z"
  }
}

source è chat, phone o form. I campi senza valore vengono omessi. fields contiene i tuoi dati aggiuntivi, con l'etichetta come chiave. Una richiesta di richiamata aggiunge callback con day e time, un modulo aggiunge formName.

Esempio: nuovo appuntamento

{
  "id": "0c8f2d0e-6f1a-4a43-9a0b-2f9a3c1d5e77",
  "event": "booking.created",
  "createdAt": "2026-10-23T15:20:04.112Z",
  "data": {
    "bookingId": "e3f82cb1-4f6a-4d6e-9c55-0d1a2b3c4d5e",
    "source": "card",
    "appointmentType": { "id": "consultation", "title": "Consulenza gratuita", "durationMinutes": 30 },
    "start": "2026-10-28T14:00",
    "end": "2026-10-28T14:30",
    "startUtc": "2026-10-28T13:00:00.000Z",
    "endUtc": "2026-10-28T13:30:00.000Z",
    "timezone": "Europe/Rome",
    "name": "Marco Esempio",
    "email": "marco@example.com",
    "fields": { "Azienda": "Esempio Srl" },
    "createdAt": "2026-10-23T15:20:04.050Z"
  }
}

start e end sono l'ora locale nel fuso timezone, startUtc e endUtc gli stessi momenti in UTC. source è card (prenotato tramite la scheda appuntamenti nella chat), chat o phone. I campi senza valore vengono omessi: name (se il nome non è stato chiesto o non è stato indicato), email, phone, note (il motivo), meetingLink (link alla videochiamata, solo con Google Calendar) e sessionId. fields contiene le risposte agli altri dati di Prenotare appuntamenti, con l'etichetta come chiave.

Intestazioni

IntestazioneContenuto
X-Webhook-IdID univoco dell'invio, uguale al campo id. Serve a riconoscere i duplicati.
X-Webhook-Eventlead.created o booking.created
X-Webhook-TimestampMomento dell'invio in secondi dal 1970
X-Webhook-Signaturesha256= più HMAC-SHA256 su timestamp.rawBody con la tua chiave segreta

Verificare la firma

Controlla la firma prima di usare i dati. Usa il corpo della richiesta originale, senza modifiche, non un JSON serializzato di nuovo.

Node.js:

import { createHmac, timingSafeEqual } from 'node:crypto'

export function isValidWebhook(rawBody, headers, secret) {
  const timestamp = headers['x-webhook-timestamp']
  const expected = 'sha256=' + createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')
  const received = String(headers['x-webhook-signature'] || '')
  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300
  return fresh && received.length === expected.length && timingSafeEqual(Buffer.from(received), Buffer.from(expected))
}

PHP:

$raw = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$received = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $raw, $secret);

if (!hash_equals($expected, $received) || abs(time() - (int) $timestamp) > 300) {
    http_response_code(401);
    exit;
}
$event = json_decode($raw, true);

In Zapier o Make puoi saltare la verifica della firma, purché l'indirizzo resti segreto.

Risposta e nuovi tentativi

  • Rispondi con uno stato 2xx quando hai accettato i dati. Non leggiamo il corpo della tua risposta.
  • Aspettiamo al massimo 5 secondi.
  • In caso di timeout, errori di rete, stato 429 o 5xx riproviamo dopo 1 e dopo 5 secondi, quindi al massimo tre volte in tutto.
  • Gli altri errori (ad esempio 404) non vengono ripetuti. I reindirizzamenti non vengono seguiti.
  • La dashboard mostra l'esito dell'ultimo invio in Ultimo invio.

Se il tuo sistema non risponde, nessun lead va perso: si trova sempre prima nella tua dashboard Lead.