Skip to main content

Webhook in entrata

Instradamento dinamico dell'agente — Finn chiama il tuo server quando arriva una chiamata in entrata.

6 min read

In entrata Webhooks

Quando arriva una chiamata in entrata, Finn può chiedere ** il tuo server** in tempo reale quale agente rispondere con, quali variabili iniettare, e quale base di conoscenza caricare. Questo ti permette di dirigere dinamicamente - con numero di chiamante, tier conto, tempo del giorno, coorte A / B, o qualsiasi logica il tuo backend si preoccupa.

Se basta un agente fisso, salta questo. Se vuoi un routing dinamico per chiamata**, questa è la pagina.


Come funziona

caller dials → Finn answers ring → Finn POSTs to your URL → your server returns agent + vars → Finn streams the voice agent

La stretta di mano aggiunge ~100–200m di latenza. Il tuo endpoint deve rispondere in under 500ms o Finn rientra nell'agente predefinito.


Configurazione

1. Impostare l'URL di webhook in entrata

Dashboard → Impostazioni → Numeri telefonici → [numero] → Inbound Webhook URL.

Incolla il tuo endpoint HTTPS. Salva. Finn lo scrive una volta con un corpo {"ping": true} per verificare la raggiungibilità.

Via 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. Impostare un agente fallback

Configurare un Finn predefinito per quel numero — usato se il vostro webhook volte fuori, errori, o restituisce una risposta non valida.


Richiesta pagamento

Finn POSTs 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 utilizza i campi specifici di WhatsApp:

"from": {
  "wa_id": "919876543210",
  "display_name": "Priya M",
  "profile_pic_url": "https://..."
},
"channel": "whatsapp"

Risposta

Restituisce un corpo JSON entro 500ms che descrive come indirizzare 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 del campo

| Campo | Richiesto? | Note | Traduzione: | finn_id | **Sì **** | Quale agente risponde. Deve appartenere al tuo org | language | No | Lingua di default dell'agente Override. en-US, hi-IN, es-ES, ecc. | | variables | No | Key/value bag free-form. Disponibile all'interno del prompt come {variable_name}. | | knowledge_base_ids | No | Override che le KB sono caricate per questa chiamata | metadata | No | Attached to the call record and post-call webhook. Utilizzare per il proprio tagging di analisi. # | recording_enabled | No | Override the agent default. | | max_call_duration_seconds | No | Hard cap. Predefinito è 1800 (30 min)

Rifiutare la chiamata

{ "action": "reject", "reason": "blocked_caller" }

Finn termina la chiamata con un messaggio in uscita configurato ("Questo numero non è più in servizio"). Utilizzare per l'applicazione DNC, i conti bloccati, o post-ore hangup.

Trasferisci immediatamente

{ "action": "transfer", "to": "+918888888888", "reason": "vip_route" }

Salta completamente l'agente dell'AI — rotta direttamente a un umano. Utile per vip/escalation tiers.


Esempio di attuazione (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 webhooks post-call — HMAC-SHA256 sopra il corpo grezzo, intestazione 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");

Vedere Post-call Webhooks per l'attuazione completa della verifica.


Requisiti di prestazione

Questo è sul sentiero hot — il chiamante è suono dell'anello uditivo mentre aspetta sulla vostra risposta.

| Metric | Target | Traduzione: | Tempo di risposta | ** < 500ms** (p99) | | Timeout | 1000ms | | Fallback on timeout | Agente predefinito configurato sul numero di telefono | | Fallback on 5xx | Agente predefinito | | Fallback on invalid JSON | Default agent + errore loggato |

Consigli per colpire < 500ms

  • Cache CRM lookups per numero di telefono per 5 minuti
  • ** Utilizzare un database colocated** — webhook da us-east, DB in us-west = 80ms ogni modo
  • Precompute routing Decision — memorizzare la risposta sul record del cliente, non decidere dal vivo
  • Arricchimento non essenziale sul tubo di ingresso — spingere quel lavoro al webhook post-call

Pre-screening del chiamante

La maggior parte delle applicazioni utilizza il webhook in entrata per uno di questi modelli:

| Pattern | Caso di utilizzo | Traduzione: | ** Lookup + personalize** | Pull customer record, pass name + tier come variabili | | ** ** **** | Rifiuti chiamate da numeri bloccati | | VIP routing | Skip agent, transfer dritto alla scrivania umana | | Rilevamento della lingua | Pick hi-IN per l'India, en-US per i chiamanti statunitensi | | A/B testing | Route 50% delle chiamate a una nuova versione agente | | ** After-hours routing** | Different agent (o voicemail) al di fuori delle ore di lavoro | Traduzione: Tag chiamate da numeri di tracciamento specifici con un ID campagna | | Multi-tenant SaaS | Percorso all'inquilino il cui numero è stato comporre |


Testing

Utilizzare il Finn CLI per simulare le chiamate in entrata senza un vero anello PSTN:

finn inbound simulate \
  --phone-number-id ph_1234 \
  --from +919876543210 \
  --webhook-url https://your-app.com/finn/inbound

L'output mostra la risposta endpoint, la latenza e l'agente + variabili risolte. Amichevole.


Acquisti comuni

| Sintomo | Fix | Traduzione: | Le chiamate cadono sempre all'agente predefinito | Il tuo endpoint è > 500ms. Controllare il registro webhook di Finn per i tempi. # | Caller ascolta 2-3s di silenzio prima che l'agente parli | Il tuo endpoint è lento ma in timeout. Ottimizzare a < 200ms | Variabili che non appaiono nel discorso dell'agente | Mismatch tra segnaposto rapido {customer_name} e webhook key customerName. Utilizzare serpent case entrambi i lati | Agente sbagliato ha risposto | Il tuo endpoint ha restituito un finn_id che appartiene ad un altro org. Verifica la proprietà. | | action: reject non onorato | Check reason è una stringa, risposta JSON è valida. 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.