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
- Apri Dashboard → il tuo assistente → Funzioni.
- Nell'elenco scegli Inoltrare automaticamente (gruppo Trovare clienti). Lì trovi la sezione Webhook.
- Inserisci l'indirizzo, ad esempio l'URL "Catch Hook" di Zapier, e fai clic su Salva.
- Copia la Chiave segreta. Viene mostrata solo questa volta. Se serve, Nuova chiave ne crea una nuova.
- Scegli cosa inoltrare: Nuove richieste di contatto, Nuovi appuntamenti o entrambi.
- 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
| Evento | Quando |
|---|---|
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
| Intestazione | Contenuto |
|---|---|
X-Webhook-Id | ID univoco dell'invio, uguale al campo id. Serve a riconoscere i duplicati. |
X-Webhook-Event | lead.created o booking.created |
X-Webhook-Timestamp | Momento dell'invio in secondi dal 1970 |
X-Webhook-Signature | sha256= 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.
