#A cosa serve
Con il webhook di fine chiamata puoi:
- salvare ogni chiamata, con esito e riepilogo, nel tuo CRM o gestionale;
- aprire una pratica o un ticket con i dati che l'agente ha raccolto;
- passare la chiamata a Zapier o Make, e da lì a centinaia di app.
Prima di iniziare
- La funzione «Webhook di fine chiamata» del piano.
- Un indirizzo HTTPS raggiungibile da Internet che accetti richieste POST e risponda entro 10 secondi.
#Attivarlo
-
Apri il passo Post Chiamata
Nell'agente vocale vai in Profilo AgenteModifica ProfiloPost Chiamata: è il quarto passo della configurazione. Ci arrivi anche dal riepilogo del Profilo Agente, con il pulsante dell'area Azioni Post Chiamata, che si chiama Modifica, o Configura se l'area è ancora da impostare.
-
Accendi il webhook
Nel riquadro Webhook attiva Attiva il webhook e scrivi l'URL webhook, che deve iniziare con
https://. -
Scegli le opzioni
Invia solo per chiamate completate, acceso di serie, manda il webhook solo per le chiamate riuscite, spiegate più sotto. Includi URL della registrazione audio, acceso di serie, aggiunge il link dell'audio. Se la registrazione è spenta nel passo Generali, il link resta vuoto.
-
Salva e copia la chiave
Premi Salva modifiche: la chiave viene creata in quel momento. Nel riquadro Chiave Segreta Webhook (Secret HMAC) premi Mostra la chiave o Copia la chiave e mettila nella configurazione del tuo server.
Con Rigenera la chiave ne crei una nuova. La conferma avvisa che «Le firme fatte con la chiave attuale non saranno più valide: aggiorna il sistema che riceve il webhook.». Lettura e rigenerazione valgono subito, senza salvare.
#Quando parte
Il webhook parte dopo l'analisi di fine chiamata: esito, riepilogo, sentiment e variabili estratte sono già pronti nel JSON.
Una chiamata è riuscita quando qualcuno ha risposto e ha detto almeno una parola, oppure quando è stata trasferita a un collega. Una segreteria, o una risposta senza parole, non conta. È la stessa definizione di Chiamate: elenco e dettaglio, e nel JSON corrisponde a call.reached uguale a true.
- Con Invia solo per chiamate completate acceso, il webhook parte solo per le chiamate riuscite, comprese le trasferite: nonostante il nome, non conta lo stato «Completata».
- Con l'opzione spenta parte per ogni chiamata conclusa, anche mai risposta o finita in segreteria. In quei casi
call.reachedvalefalseecall.endReasondice perché la chiamata si è chiusa.
#Cosa riceve il tuo server
Una richiesta POST con il corpo in JSON e questi header:
| Header | Valore |
|---|---|
Content-Type | application/json |
X-Webhook-Signature | sha256= seguito dalla firma HMAC SHA-256 del corpo, in esadecimale. |
X-Webhook-Call-Id | L'identificativo della chiamata, lo stesso di call.id. |
JSON · esempio con dati di prova
{
"call": {
"customerNumber": "+390212345678",
"agentNumber": "+390612345678",
"direction": "inbound",
"startedAt": "19/10/2026 10:12",
"endedAt": "19/10/2026 10:15",
"duration": "3 min 5 s",
"reached": true,
"result": "appointment_booked",
"resultText": "Il cliente ha prenotato un tagliando.",
"sentiment": "positive",
"summary": "Mario Rossi chiede un tagliando. L'agente propone giovedì 22 ottobre alle 9:30 e il cliente accetta.",
"transcript": "AI: Buongiorno, Officina Rossi, come posso aiutarla?\n\nHUMAN: Vorrei prenotare un tagliando.",
"transferName": null,
"recordingUrl": "https://www.esempio.it/registrazione-di-esempio.mp3",
"appointment": {
"startsAt": "22/10/2026 09:30",
"calendarName": "Tagliando",
"startsAtIso": "2026-10-22T07:30:00.000Z",
"uid": "prenotazione-esempio-123"
},
"variables": { "nome_cliente": "Mario Rossi", "targa": "AB123CD" },
"id": "chiamata-esempio-001",
"conversationId": "conversazione-esempio-001",
"status": "ended",
"endReason": "agent_endcall",
"errorDetail": null,
"durationSec": 185,
"startedAtIso": "2026-10-19T08:12:04.000Z",
"endedAtIso": "2026-10-19T08:15:09.000Z"
},
"messages": [
{ "role": "assistant", "content": "Buongiorno, Officina Rossi, come posso aiutarla?" },
{ "role": "user", "content": "Vorrei prenotare un tagliando." }
],
"contact": {
"fullName": "Mario Rossi",
"email": "mario.rossi@esempio.it",
"phone": "+390212345678"
},
"event": "telephone.ended",
"variables": { "nome_cliente": "Mario Rossi", "targa": "AB123CD" }
}
eventTestoSempre
telephone.ended.callOggettoI dati della chiamata, con gli stessi nomi delle variabili
{{call.*}}: cosa contiene ogni campo è in Dati della chiamata. I campi leggibili sono nel fuso del workspace; quelli conIsosono date in UTC. I campi in codice hanno questi valori:direction:inboundooutbound;reached:truese la chiamata è riuscita, come spiegato in Quando parte, altrimentifalse;result:resolved,unresolved,abandoned,appointment_booked,transferred,no_interaction,no_answer,voicemailospam;sentiment:positive,neutralonegative;status:ended,failedotransferred;endReason, il motivo di chiusura:agent_endcall(chiusa dall'agente),user_hangup(riagganciata dal cliente),timeout(durata massima raggiunta),silence_timeout(silenzio prolungato),transfer(trasferita),voicemail(segreteria telefonica),no_answer(nessuna risposta),busy(occupato),rejected(rifiutata),invalid_number(numero non valido),blocked(bloccata dalla compagnia telefonica),sip_error(errore di linea) oerror(errore tecnico).
La durata si conta dalla risposta, senza lo squillo: per una chiamata mai risposta
durationSecvale 0 edurationè vuoto.messagesListaLa conversazione, messaggio per messaggio:
rolevaleassistantper l'agente euserper il cliente.contactOggetto o nullNome completo, email e telefono del contatto. È
nullquando alla chiamata non è legato un contatto, per esempio se chi chiama ha il numero nascosto.variablesOggettoLe variabili estratte dalla chiamata, con i nomi che hai scelto in Estrazione Dati e Variabili. Vuoto se l'estrazione è spenta. Lo stesso oggetto è anche in
call.variables.
Un dato che manca arriva null o vuoto: per esempio l'appuntamento, se non è stato preso, o il link dell'audio, se nessuno ha risposto o la registrazione non è ancora pronta.
#Verificare la firma
La firma ti dice che la richiesta arriva davvero da SupportFast e non è stata modificata. Calcola l'HMAC SHA-256 del corpo con la chiave segreta, sul testo così come lo ricevi e prima di trasformarlo in oggetto: anche uno spazio diverso cambia la firma. Scrivilo in esadecimale con davanti sha256= e confrontalo con l'header X-Webhook-Signature.
Node.js con Express
const crypto = require("crypto");
const express = require("express");
const app = express();
const SEGRETO = process.env.SUPPORTFAST_WEBHOOK_SECRET;
app.post("/webhook/fine-chiamata", express.raw({ type: "application/json" }), (req, res) => {
const ricevuta = req.get("X-Webhook-Signature") || "";
const attesa = "sha256=" + crypto.createHmac("sha256", SEGRETO).update(req.body).digest("hex");
const valida = ricevuta.length === attesa.length &&
crypto.timingSafeEqual(Buffer.from(ricevuta), Buffer.from(attesa));
if (!valida) return res.sendStatus(401);
res.sendStatus(200);
const dati = JSON.parse(req.body.toString("utf8"));
// salva dati.call, dati.contact e dati.variables nel tuo gestionale
});
app.listen(3000);
PHP
<?php
$segreto = getenv('SUPPORTFAST_WEBHOOK_SECRET');
$corpo = file_get_contents('php://input');
$ricevuta = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$attesa = 'sha256=' . hash_hmac('sha256', $corpo, $segreto);
if (!hash_equals($attesa, $ricevuta)) {
http_response_code(401);
exit;
}
http_response_code(200);
$dati = json_decode($corpo, true);
// salva $dati['call'], $dati['contact'] e $dati['variables'] nel tuo gestionale
#Se il tuo server non risponde
- Se la connessione non riesce, se passano i 10 secondi o se rispondi con un codice
5xx, riprova dopo 1, 3 e 10 secondi. In tutto, al massimo quattro invii. - Con un codice
4xxnon riprova. - Non segue i reindirizzamenti: un codice
3xxconta come errore e non si ritenta. - Non invia a indirizzi interni o privati, solo a server raggiungibili da Internet.
- Dopo l'ultimo tentativo l'invio si ferma. La chiamata resta comunque nella pagina Chiamate dell'agente.
Rispondi subito, lavora dopo. Rispondi 200 appena hai verificato la firma e fai dopo le operazioni lente. Per non salvare due volte la stessa chiamata dopo un nuovo tentativo, controlla X-Webhook-Call-Id.
#Come provarlo
-
Prepara chi riceve
Usa il tuo server o un indirizzo di prova che ti mostri le richieste in arrivo, come quelli di Zapier o Make. Mettilo in URL webhook e salva.
-
Fai una chiamata vera
Chiama l'agente dal tuo cellulare, parla qualche secondo e chiudi. Con Invia solo per chiamate completate acceso, una chiamata in cui non dici nulla non fa partire il webhook.
-
Controlla cosa è arrivato
Dopo l'analisi di fine chiamata arriva la richiesta. Verifica la firma e controlla i campi che ti servono.
#Con Zapier, Make o il tuo gestionale
In Zapier usa il trigger Catch Hook dell'app Webhooks by Zapier; in Make il modulo Custom webhook. Copia l'indirizzo che ti danno in URL webhook: dopo la prima chiamata i campi del JSON sono disponibili nei passi successivi. Questi strumenti non verificano la firma da soli: tieni riservato l'indirizzo.
Per il tuo gestionale chiedi al fornitore se ha un indirizzo adatto, o fallo preparare a uno sviluppatore con l'esempio qui sopra.
#In alternativa: un'automazione sugli eventi di telefonia
Se ti servono solo alcuni dati, o vuoi mandarli in più posti, usa un'automazione con un evento della categoria Telefonia, come Chiamata terminata. Con il nodo API chiami il tuo server con i campi che scegli; con gli altri nodi mandi un'email o un WhatsApp.
| Webhook di fine chiamata | Automazione | |
|---|---|---|
| Dove si imposta | Nel passo Post Chiamata dell'agente vocale, riquadro Webhook | Nelle automazioni del workspace |
| Dati inviati | Sempre tutti, nello stesso JSON | Quelli che scegli tu |
| Quando parte | A fine chiamata, anche per le trasferite | All'evento scelto: Chiamata terminata non parte per le trasferite |
| Sicurezza | Firma HMAC con la chiave | Gli header che imposti nel nodo API |
| Consumi | Nessuna esecuzione | Ogni partenza conta nelle esecuzioni del mese |
| Piano | «Webhook di fine chiamata» | Le automazioni e, per il nodo API, «API e webhook» |
Vedi Eventi di partenza (trigger) e Chiamare un'API esterna.
#Domande frequenti
La firma non corrisponde mai.
Controlla di usare la chiave attuale e che la firma sia in esadecimale minuscolo, con davanti sha256=. Il calcolo è spiegato in Verificare la firma.
Posso mandare i dati a più indirizzi?
Il webhook ha un solo indirizzo per agente. Per più destinazioni passa da Zapier o Make, oppure usa un'automazione.