Webhook in entrata
Instradamento dinamico dell'agente — Finn chiama il tuo server quando arriva una chiamata in entrata.
Webhook in entrata
Quando arriva una chiamata in entrata, Finn può chiedere in tempo reale al tuo server con quale agente rispondere, quali variabili inserire e quale knowledge base caricare. Questo permette di instradare le chiamate in modo dinamico: per numero del chiamante, livello dell'account, fascia oraria, coorte A/B o qualsiasi logica gestita dal tuo backend.
Se ti basta un agente fisso, salta questa pagina. Se invece vuoi un instradamento dinamico per singola chiamata, questa è la pagina giusta.
Come funziona
caller dials → Finn answers ring → Finn POSTs to your URL → your server returns agent + vars → Finn streams the voice agent
L'handshake aggiunge circa 100–200 ms di latenza. Il tuo endpoint deve rispondere in meno di 500 ms, altrimenti Finn ricade sull'agente predefinito.
Configurazione
1. Imposta l'URL del webhook in entrata
Dashboard → Impostazioni → Numeri di telefono → [numero] → URL webhook in entrata.
Incolla il tuo endpoint HTTPS e salva. Finn lo contatta una volta con un body {"ping": true} per verificarne la raggiungibilità.
Tramite API
curl https://api.hirefinn.ai/v1/phone-numbers/ph_1234 \
-X PATCH \
-H "Authorization: Bearer $FINN_API_KEY" \
-d '{ "inbound_webhook_url": "https://your-app.com/finn/inbound" }'
2. Imposta un agente di fallback
Configura un Finn predefinito per quel numero: viene usato se il webhook va in timeout, restituisce un errore o una risposta non valida.
Payload della richiesta
Finn invia una POST al tuo URL con:
{
"session_id": "ws_2H4abc",
"request_type": "inbound",
"phone_number_id": "ph_1234",
"channel": "pstn",
"from": {
"phone": "+919876543210",
"country": "IN",
"carrier": "Airtel"
},
"to": {
"phone": "+918765432100",
"country": "IN"
},
"received_at": "2026-05-22T14:30:00Z",
"metadata": {}
}
Per le chiamate WhatsApp, il blocco from usa campi specifici di WhatsApp:
"from": {
"wa_id": "919876543210",
"display_name": "Priya M",
"profile_pic_url": "https://..."
},
"channel": "whatsapp"
Risposta
Restituisci entro 500 ms un body JSON che descrive come instradare la chiamata:
{
"finn_id": "fn_def456",
"language": "hi-IN",
"variables": {
"customer_name": "Priya M",
"account_tier": "premium",
"last_order_id": "ord_99831",
"preferred_agent": "Aria"
},
"knowledge_base_ids": ["kb_general", "kb_premium_perks"],
"metadata": {
"campaign_tag": "premium-support-q2",
"ab_cohort": "B"
},
"recording_enabled": true,
"max_call_duration_seconds": 600
}
Riferimento dei campi
| Campo | Obbligatorio? | Note |
|---|---|---|
finn_id | Sì | Quale agente risponde. Deve appartenere alla tua organizzazione. |
language | No | Sovrascrive la lingua predefinita dell'agente. en-US, hi-IN, es-ES, ecc. |
variables | No | Insieme libero di coppie chiave/valore. Disponibile nel prompt come {variable_name}. |
knowledge_base_ids | No | Sovrascrive quali knowledge base vengono caricate per questa chiamata. |
metadata | No | Allegato al record della chiamata e al webhook post-chiamata. Usalo per il tagging delle tue analisi. |
recording_enabled | No | Sovrascrive il valore predefinito dell'agente. |
max_call_duration_seconds | No | Limite massimo. Il valore predefinito è 1800 (30 min). |
Rifiuta la chiamata
{ "action": "reject", "reason": "blocked_caller" }
Finn chiude la chiamata con un messaggio in uscita configurato ("Questo numero non è più attivo"). Da usare per l'applicazione delle liste DNC, gli account bloccati o le chiusure fuori orario.
Trasferisci subito
{ "action": "transfer", "to": "+918888888888", "reason": "vip_route" }
Salta del tutto l'agente AI: instrada direttamente a un operatore. Utile per i livelli VIP / di escalation.
Esempio di implementazione (Node)
import express from "express";
const app = express();
app.use(express.json());
app.post("/finn/inbound", async (req, res) => {
const { from, to, channel } = req.body;
// 1. Look up caller in CRM (must be fast — DB index by phone)
const phone = from.phone ?? `+${from.wa_id}`;
const customer = await crm.findByPhone(phone);
// 2. Block known DNC
if (customer?.dnc) {
return res.json({ action: "reject", reason: "dnc" });
}
// 3. VIP → straight to human
if (customer?.tier === "vip") {
return res.json({
action: "transfer",
to: process.env.VIP_DESK_NUMBER!,
reason: "vip_route",
});
}
// 4. Localized agent based on caller country
const language = from.country === "IN" ? "hi-IN" : "en-US";
// 5. Pick agent + load context
return res.json({
finn_id: customer?.tier === "premium"
? "fn_premium_aria"
: "fn_standard_aria",
language,
variables: {
customer_name: customer?.name ?? "there",
account_tier: customer?.tier ?? "standard",
last_order_id: customer?.last_order_id ?? "",
},
knowledge_base_ids:
customer?.tier === "premium" ? ["kb_general", "kb_premium"] : ["kb_general"],
metadata: { ab_cohort: customer?.ab_cohort ?? "A" },
});
});
app.listen(3000);
Verifica della firma
Stesso schema dei webhook post-chiamata: HMAC-SHA256 sul corpo raw, header X-Finn-Signature.
const sig = req.headers["x-finn-signature"] as string;
const ok = verifyFinnSignature(rawBody, sig, process.env.FINN_INBOUND_SECRET!);
if (!ok) return res.status(401).send("bad signature");
Vedi Webhook post-chiamata per l'implementazione completa della verifica.
Requisiti di prestazione
Questo passaggio è sul percorso critico: il chiamante sente il segnale di libero mentre attende la tua risposta.
| Metrica | Obiettivo |
|---|---|
| Tempo di risposta | < 500 ms (p99) |
| Timeout | 1000 ms |
| Fallback in caso di timeout | Agente predefinito configurato sul numero di telefono |
| Fallback in caso di 5xx | Agente predefinito |
| Fallback in caso di JSON non valido | Agente predefinito + errore registrato |
Consigli per restare sotto i 500 ms
- Metti in cache le ricerche CRM per numero di telefono per 5 minuti
- Usa un database colocato: webhook da us-east e DB in us-west significa 80 ms per tratta
- Pre-calcola le decisioni di instradamento: salva la risposta sulla scheda del cliente, non deciderla al volo
- Salta l'arricchimento non essenziale nel passaggio inbound: sposta quel lavoro sul webhook post-chiamata
Pre-screening del chiamante
La maggior parte delle applicazioni usa il webhook inbound per uno di questi schemi:
| Schema | Caso d'uso |
|---|---|
| Ricerca + personalizzazione | Recupera il record cliente, passa nome e livello come variabili |
| Applicazione DNC | Rifiuta le chiamate da numeri bloccati |
| Instradamento VIP | Salta l'agente, trasferisci direttamente a un operatore |
| Rilevamento della lingua | Scegli hi-IN per l'India, en-US per i chiamanti dagli Stati Uniti |
| Test A/B | Instrada il 50% delle chiamate a una nuova versione dell'agente |
| Instradamento fuori orario | Agente diverso (o segreteria) fuori dall'orario lavorativo |
| Monitoraggio delle campagne | Etichetta le chiamate da specifici numeri di tracciamento con un ID campagna |
| SaaS multi-tenant | Instrada al tenant il cui numero è stato composto |
Test
Usa la CLI di Finn per simulare chiamate in entrata senza uno squillo PSTN reale:
finn inbound simulate \
--phone-number-id ph_1234 \
--from +919876543210 \
--webhook-url https://your-app.com/finn/inbound
L'output mostra la risposta dell'endpoint, la latenza e l'agente e le variabili risolte. Compatibile con CI.
Problemi comuni
| Sintomo | Soluzione |
|---|---|
| Le chiamate ricadono sempre sull'agente predefinito | L'endpoint supera i 500 ms. Controlla i tempi nel log dei webhook di Finn. |
| Il chiamante sente 2-3 s di silenzio prima che l'agente parli | L'endpoint è lento ma entro il timeout. Ottimizzalo a meno di 200 ms. |
| Le variabili non compaiono nel parlato dell'agente | Discrepanza tra il segnaposto del prompt {customer_name} e la chiave del webhook customerName. Usa snake_case su entrambi i lati. |
| Ha risposto l'agente sbagliato | L'endpoint ha restituito un finn_id che appartiene a un'altra organizzazione. Verifica la proprietà. |
action: reject non rispettato | Verifica che reason sia una stringa e che il JSON di risposta sia valido. Risposte non valide → fallback. |
Correlati
Was this page helpful?
Still stuck or have feedback?
Email [email protected] or use the chat bubble in the bottom-right corner — it's a Finn that knows the Academy cold.