---
title: "Catalogo degli eventi"
description: "Tutti i tipi di eventi webhook emessi da ThunderPhone."
---

Ogni corpo webhook ha un campo `type` il cui valore è uno dei tipi di evento
in questa pagina. Quando ti iscrivi a un
[endpoint](/it/webhooks/endpoints), l'array `events` deve contenere i
tipi di evento desiderati (oppure essere vuoto per iscriverti a tutti —
tranne gli eventi per turno [`telephony.turn`](#telephony-turn) /
[`web.turn`](#web-turn), che vengono inviati solo agli endpoint che
li nominano esplicitamente).

Due stili di consegna trasportano questi eventi:

* Le **consegne agli endpoint** sono sempre notifiche **non bloccanti**
  con [tentativi](/it/webhooks/overview): rispondi con
  un qualsiasi 2xx; l'involucro include un `event_id` per la deduplicazione.
* Gli scambi **bloccanti** avvengono solo sul
  [webhook legacy a URL singolo](/it/webhooks/overview): la richiesta di
  configurazione [`telephony.incoming` / `web.incoming`](/it/webhooks/call-incoming)
  (numeri in modalità webhook: 13 s incluso un tentativo;
  chiavi widget in modalità webhook: 10 s) e l'[invio degli strumenti](/it/tools/overview)
  in modalità webhook. La tua risposta determina la chiamata in tempo reale.

Gli esempi di payload seguenti mostrano l'involucro dell'endpoint nel relativo ordine
wire (chiavi ordinate alfabeticamente: `data`, `event_id`, `type`); le consegne legacy
contengono gli stessi `data` senza `event_id`.

## Eventi delle chiamate

### `telephony.incoming`

Inviato quando una chiamata in entrata raggiunge uno dei tuoi
[numeri di telefono](/api-reference/phone-numbers). Le consegne all'endpoint sono
notifiche fire-and-forget inviate per **ogni** chiamata in entrata, indipendentemente dal fatto
che il numero sia configurato per un agente o per un webhook. I numeri senza
un agente assegnato ricevono inoltre la richiesta di configurazione
**bloccante** sul webhook legacy — consulta
[`telephony.incoming` / `web.incoming`](/it/webhooks/call-incoming) per
lo schema completo di richiesta / risposta.

```json
{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |

### `telephony.complete`

Inviato quando termina una chiamata telefonica in entrata o in uscita. Non bloccante.
Include la trascrizione, l'URL della registrazione quando disponibile e il riepilogo della fatturazione. Consulta
[`telephony.complete` / `web.complete`](/it/webhooks/call-complete) per
lo schema del payload.

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |

### `telephony.tool`

Inviato dopo che una chiamata telefonica invoca uno
[strumento funzione](/it/tools/overview). Notifica di audit non bloccante —
lo strumento è già stato eseguito quando viene consegnato questo evento; copre
i tuoi strumenti funzione e lo strumento integrato `send_sms` (non altri strumenti integrati,
della knowledge base, di connessione ad app o MCP). Per `send_sms`,
sia `arguments.to` sia `arguments.body` sono `[REDACTED]`. Anche le
trascrizioni di completamento li oscurano; recupera il contenuto e il destinatario dalla
risorsa SMS con ambito organizzazione usando il `message_id` della risposta.

```json
{
  "data": {
    "arguments": { "date": "2026-04-21" },
    "call_id": 987654321,
    "from_number": "+14155550199",
    "response": {
      "response": { "available_slots": ["9:00 AM", "2:00 PM"] },
      "status": 200
    },
    "to_number": "+15551234567",
    "tool_name": "search_appointments"
  },
  "event_id": "1f0a7c3e-52d4-4a0e-8f4b-b1a6a1c0d9e2",
  "type": "telephony.tool"
}
```

`response` è il risultato eseguito: `{"status": <http status>,
"response": <your endpoint's JSON>}` in caso di successo oppure
`{"status": <status>, "error": "<message>"}` in caso di errore.

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |

### `telephony.turn`

Inviato durante una chiamata telefonica **in corso**, una volta per ogni
turno contenente parlato man mano che avviene — i completamenti vocali dell'agente e
i turni trascritti del chiamante. Ti consente di seguire la conversazione in diretta
tramite semplici webhook anziché effettuare il polling di
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).
Non bloccante.

<Note>
  **Sottoscrizione esplicita richiesta.** A differenza di ogni altro tipo di evento,
  gli eventi di turno non vengono mai consegnati tramite un array `events`
  vuoto (sottoscrizione a tutti). Un endpoint li riceve solo quando il relativo elenco `events`
  contiene esplicitamente `telephony.turn` / `web.turn`.
</Note>

```json
{
  "data": {
    "call_id": 987654321,
    "entry_type": "completion",
    "from_number": "+14155550199",
    "position": 7,
    "role": "assistant",
    "start_ms": 15200,
    "text": "How many employees does your company have?",
    "to_number": "+15551234567"
  },
  "event_id": "8d3f5a2c-7b1e-4c9a-b6d0-2e4f6a8c0d1e",
  "type": "telephony.turn"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |
| `position` | integer | Indice del turno nella cronologia della chiamata — un'identità stabile per l'ordinamento |
| `role` | string | `assistant` (parlato dell'agente) o `user` (parlato del chiamante) |
| `text` | string | Testo della trascrizione del turno noto al momento dell'emissione |
| `entry_type` | string | Tipo di voce della cronologia sottostante: `completion` (agente) oppure `user_turn` / `span` (chiamante) |
| `start_ms`, `end_ms` | integer | Offset audio in ms dall'inizio della chiamata; presenti solo quando la temporizzazione della riproduzione era già nota al momento dell'emissione |

<Note>
  La consegna avviene almeno una volta e i turni possono arrivare **fuori ordine**:
  esegui la deduplicazione sull'`event_id` dell'envelope e ordina in base a `position`. Le
  trascrizioni del chiamante possono ancora essere perfezionate dopo l'emissione; la trascrizione
  [`telephony.complete`](/it/webhooks/call-complete) post-chiamata è
  autorevole. Vengono emessi solo i turni parlati — chiamate di strumenti, sussurri e
  altre voci interne non appaiono mai in questo flusso.
</Note>

### `web.incoming`

L'equivalente del canale web di `telephony.incoming`, inviato quando inizia una
sessione di [widget web](/it/widget/overview) o una chiamata di test del microfono del builder.
Le consegne all'endpoint sono fire-and-forget per ogni sessione web.
Le chiavi pubblicabili in `mode="webhook"` ricevono inoltre la richiesta di configurazione
**bloccante** sul webhook legacy — tale richiesta bloccante ha una struttura diversa (`origin_domain`,
`publishable_key_prefix`; nessun numero di telefono). Consulta
[`telephony.incoming` / `web.incoming`](/it/webhooks/call-incoming).

```json
{
  "data": {
    "call_id": 987654322,
    "from_number": "web",
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2",
    "to_number": "+15551234567"
  },
  "event_id": "9a2b4c6d-8e0f-4a1b-9c2d-3e4f5a6b7c8d",
  "type": "web.incoming"
}
```

`from_number` è sempre il valore letterale `"web"`. Per le sessioni del widget
in modalità webhook, `to_number` è vuoto (il numero dell'agente della sessione viene assegnato
dopo la configurazione); per le chiamate di test del microfono del builder, `origin_domain` e
`publishable_key_prefix` sono vuoti.

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |

### `web.complete`

L'equivalente del canale web di `telephony.complete`, che copre le chiamate del
widget web (`direction: "web"`) e le chiamate di test del microfono del builder
(`direction: "test"`). Non bloccante. Stessa struttura del payload di
[`telephony.complete`](/it/webhooks/call-complete), oltre a `origin_domain`,
con `from_number` impostato su `"web"`.

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |

<Note>
  Sul webhook legacy con URL singolo, le chiamate di test del microfono del builder
  storicamente vengono riportate come `telephony.complete` — solo le chiamate con `direction:
  "web"` usano qui il tipo `web.complete`. Il sistema degli endpoint
  mappa sia le chiamate web sia quelle di test su `web.*`. I payload storici possono
  contenere i valori legacy di `direction` `widget` o `mic`.
</Note>

### `web.tool`

L'equivalente del canale web di `telephony.tool`. Il campo `data` contiene
`origin_domain` anziché `from_number` / `to_number`.

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |

### `web.turn`

L'equivalente del canale web di [`telephony.turn`](#telephony-turn),
che copre le chiamate del widget web e le chiamate di test del microfono del builder. Stessa struttura
del payload, con `origin_domain` anziché `from_number` / `to_number`.
Come `telephony.turn`, richiede una **sottoscrizione esplicita** —
non viene mai consegnato tramite un array `events` vuoto.

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |

### `call.transfer_completed`

Inviato una volta per chiamata con l'esito finale di un
[trasferimento di chiamata](/it/guides/call-transfers): un trasferimento a freddo oppure il
ponte tra persone che un trasferimento a caldo lascia attivo dopo l'uscita dell'agente.
Non bloccante e recapitato solo agli endpoint (mai al webhook legacy
con URL singolo). Arriva dopo `telephony.complete` della chiamata:
quando l'operatore prende in carico la chiamata o il trasferimento non riesce oppure, quando
ThunderPhone ha creato un ponte per la chiamata, alla fine del ponte.

```json
{
  "data": {
    "agent_id": 12,
    "agent_name": "Front desk",
    "bridge_kind": "cold_fallback",
    "bridge_seconds": 255,
    "bridge_total_cents": 5,
    "call_id": 987654321,
    "destination": "+15555550102",
    "sip_status": 403,
    "transfer_outcome": "bridged"
  },
  "event_id": "5b0f6c1e-9d2a-5e7b-8c4d-1a2b3c4d5e6f",
  "type": "call.transfer_completed"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `call_id` | integer | La chiamata che è stata trasferita |
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |
| `transfer_outcome` | string | `refer_accepted`: l'operatore ha preso in carico la chiamata. `bridged`: ThunderPhone ha mantenuto connessi il chiamante e la destinazione, perché l'operatore ha rifiutato un trasferimento a freddo oppure perché l'agente di un trasferimento a caldo è uscito. `bridge_unanswered`: l'operatore ha rifiutato un trasferimento a freddo e la destinazione non ha risposto alla chiamata effettuata da ThunderPhone. `failed`: il trasferimento non è andato a buon fine e la chiamata è terminata |
| `destination` | string \| null | Il numero a cui è stata trasferita la chiamata |
| `sip_status` | integer \| null | Lo stato SIP dell'operatore quando ha rifiutato il trasferimento a freddo: `403` (ad esempio un trunk Twilio senza trasferimento di chiamata), `405` o `501`. `null` quando l'operatore non lo ha rifiutato |
| `bridge_kind` | string \| null | Solo `bridged`: `cold_fallback` (un trasferimento a freddo rifiutato che ThunderPhone ha connesso) oppure `warm` (le due persone di un trasferimento a caldo dopo l'uscita dell'agente) |
| `bridge_seconds` | integer \| null | Solo `bridged`: il tempo collegato fatturato da ThunderPhone, in secondi |
| `bridge_total_cents` | integer \| null | Solo `bridged`: il costo del ponte in centesimi USD dopo eventuali crediti gratuiti per chiamate, fatturato separatamente da `billing_total_cents` della chiamata |

Gli stessi valori sono presenti nell'[oggetto chiamata](/api-reference/calls#call-object)
come `transfer_outcome`, `transfer_destination`, `transfer_sip_status`,
`transfer_bridge_kind`, `transfer_bridge_seconds` e
`transfer_bridge_total_cents`. `event_id` è lo stesso in ogni consegna
per una chiamata, quindi una segnalazione ripetuta non genera mai un secondo evento.

---

## Eventi SMS

Gli eventi SMS descrivono i messaggi inviati tramite l'account Twilio o Telnyx
connesso dell'organizzazione. Il corpo del messaggio viene omesso e `to` viene oscurato.
Recupera il messaggio con ambito organizzazione da
[`GET /v1/sms/{message_id}`](/api-reference/sms#retrieve-a-message) quando ne
servono il contenuto o il destinatario.

### `sms.sent`

Inviato quando l'operatore del cliente accetta una richiesta SMS in uscita. Non è
una ricevuta di consegna al dispositivo.

```json
{
  "data": {
    "accepted_at": "2026-09-19T15:42:10.113Z",
    "agent_id": 12,
    "call_id": 987654321,
    "created_at": "2026-09-19T15:42:09.901Z",
    "direction": "outbound",
    "error_code": null,
    "error_message": null,
    "from_number": "+15551234567",
    "id": "313a3117-827b-46e9-a01a-ac1493838724",
    "provider": "twilio",
    "provider_id": "SM0123456789abcdef0123456789abcdef",
    "segment_count": 1,
    "source": "agent_tool",
    "status": "accepted",
    "to": "[REDACTED]"
  },
  "event_id": "0ae347b4-1716-45bb-9a0e-b52373586e37",
  "type": "sms.sent"
}
```

### `sms.failed`

Inviato dopo un rifiuto permanente da parte dell'operatore, dopo l'esaurimento
dei tentativi per errori transitori o quando l'esito è definitivamente sconosciuto.
`error_code` è un codice ThunderPhone stabile e `error_message` indica l'azione
che il cliente deve intraprendere, quando disponibile. `status: "unknown"` indica
che l'operatore potrebbe aver accettato l'SMS; verificalo nel registro dell'operatore
perché ThunderPhone non lo reinvierà automaticamente.

### `sms.received`

Riservato al supporto per SMS in entrata. Nella versione corrente non vengono
emessi eventi `sms.received`. La configurazione dei webhook dell'operatore per gli
SMS in entrata e la verifica della firma verranno rilasciate separatamente.

---

## Eventi vocali

La creazione di voci personalizzate è asincrona. Questi eventi non bloccanti ti
consentono di reagire a un risultato finale anziché eseguire il polling
dell'[endpoint dei dettagli del clone](/api-reference/custom-voices#list-and-retrieve-clones).

`voice.ready` e `voice.failed` vengono recapitati solo a un endpoint a livello di
organizzazione con `events: []`. Non possono essere selezionati come filtri evento espliciti.

### `voice.ready`

Inviato quando una voce personalizzata completa l'elaborazione e può essere
assegnata a un agente.

```json
{
  "data": {
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "ready",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "2d5f0a61-e9b5-4a3c-b684-29d7d9e4b214",
  "type": "voice.ready"
}
```

### `voice.failed`

Inviato quando l'elaborazione della voce personalizzata raggiunge un errore permanente.

```json
{
  "data": {
    "reason": "audio sample could not be processed",
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "audio sample could not be processed",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "failed",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "3493e985-1a75-4f77-a10a-e74af440cd31",
  "type": "voice.failed"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `voice.id` | string | ID pubblico della voce personalizzata |
| `voice.name` | string | Valore della voce dell'agente nel formato `custom:<public_id>` |
| `voice.display_name` | string | Nome della voce visibile all'organizzazione |
| `voice.language` | string | Codice della singola lingua del clone |
| `voice.gender` | string | `male`, `female` o una stringa vuota |
| `voice.status` | string | `ready` per `voice.ready`; `failed` per `voice.failed` |
| `voice.failure_reason` | string | Vuoto in caso di successo; dettaglio dell'errore di elaborazione in caso di errore |
| `voice.created_at`, `voice.updated_at` | timestamp | Timestamp ISO 8601 |
| `reason` | string | Dettaglio dell'errore; presente solo in `voice.failed` |

---

## Eventi di qualità

### `call.graded`

Inviato ogni volta che una [valutazione IA](/api-reference/calls#ai-call-grading)
viene completata per una chiamata. Non bloccante.

```json
{
  "data": {
    "call_id": 987654321,
    "grade": {
      "call_outcome": "success",
      "created_at": "2026-04-20T18:25:11.002Z",
      "detected_issues": [],
      "graded_at": "2026-04-20T18:25:11.002Z",
      "grader_model": "heuristic-v1",
      "id": 5512,
      "score": 92,
      "status": "completed",
      "summary": "Caller asked about their policy and got a full answer…"
    },
    "report": null
  },
  "event_id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "type": "call.graded"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |
| `grade.id` | integer | ID della valutazione |
| `grade.score` | integer \| null | 0–100 |
| `grade.call_outcome` | string | `success`, `failure`, `unknown` o `no_conversation` |
| `grade.summary` | string | Riepilogo di un paragrafo |
| `grade.detected_issues` | array | Stringhe dei problemi rilevati dal valutatore |
| `grade.status` | string | Sempre `completed` — vengono emesse solo esecuzioni completate |
| `grade.grader_model` | string | Valutatore che ha prodotto il risultato (ad es. `heuristic-v1`) |
| `grade.graded_at`, `grade.created_at` | timestamp | |
| `report` | object \| null | [Report della chiamata](/api-reference/calls#call-report) rivolto al cliente: etichetta dell'esito, indicatore e motivo di attenzione necessaria, chiamante, riepilogo di una riga, esperienza del chiamante. In una valutazione euristica iniziale è `null` o un report `pending` i cui campi sono segnaposto; l'evento della valutazione completa include quello completato |

<Note>
  Una chiamata può essere valutata più di una volta — spesso una valutazione
  euristica rapida è seguita da una valutazione completa del modello quando la
  registrazione è disponibile e sono possibili rivalutazioni manuali. Ogni
  esecuzione completata emette il proprio evento `call.graded`; considera
  autorevole il valore `graded_at` più recente.
</Note>

### `call.data_extracted`

Inviato ogni volta che l'estrazione di dati strutturati viene completata con
successo, incluso un nuovo tentativo tardivo dopo `telephony.complete` /
`web.complete` o una nuova esecuzione manuale tramite
[`POST /v1/calls/{call_id}/extract`](/api-reference/calls#run-data-extraction).
Non bloccante.

In una modalità di estrazione bloccante, l'evento di completamento normalmente
non attende oltre il budget di estrazione di 75 secondi. Se il processo worker
di estrazione viene perso, lo svuotamento di finalizzazione in produzione
(ogni cinque minuti) rilascia un completamento il cui `blocking_deadline_at` è
scaduto prima di avviare un altro tentativo di estrazione. Un successo
successivo viene inviato separatamente come questo evento.

<Warning>
  I valori estratti sono l'interpretazione della conversazione da parte di un
  modello. Ogni valore non null include la citazione, il ruolo del parlante e
  l'indice del turno su cui si basa, oltre a un flag di verifica a livello di
  esecuzione. Verifica il risultato prima di prendere decisioni che riguardano
  denaro, identità o accesso.
</Warning>

```json
{
  "data": {
    "call_id": 987654321,
    "agent_id": 12,
    "agent_name": "Acme intake",
    "extracted_data": {
      "status": "completed",
      "fields": {
        "customer_name": "Alex Morgan",
        "appointment_date": "2026-04-23"
      },
      "evidence": {
        "customer_name": {
          "quote": "My name is Alex Morgan",
          "speaker_role": "caller",
          "turn_index": 4
        },
        "appointment_date": {
          "quote": "April 23 works for me",
          "speaker_role": "caller",
          "turn_index": 7
        }
      },
      "verification": "verified",
      "field_reasons": {},
      "schema_version": "92850758e231a3c95a..."
    },
    "extracted_at": "2026-04-20T18:25:11.002Z",
    "model": "<model id>",
    "summary": "Alex Morgan called to book a follow-up visit and confirmed Thursday, April 23."
  },
  "event_id": "4d79ef1d-c2b1-4ed6-85b8-8326bd2895ef",
  "type": "call.data_extracted"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |
| `summary` | string \| null | Il [riepilogo della chiamata](/it/webhooks/call-complete) completato quando l'agente ha attivato **Genera un riepilogo della chiamata**, quindi un evento di estrazione tardivo fornisce anche un riepilogo che non ha rispettato la finestra di completamento; altrimenti `null`. Gli agenti con un riepilogo ma senza campi di estrazione non emettono mai questo evento: leggi un riepilogo tardivo da `GET /v1/calls/{call_id}` |
| `extracted_data.status` | string | Sempre `completed` per questo evento |
| `extracted_data.fields` | object | Valori indicizzati dalle chiavi dei campi di estrazione configurati; i valori non disponibili sono `null` |
| `extracted_data.evidence` | object | Evidenze indicizzate per campo di estrazione. Un valore non null contiene la citazione esatta controllata strutturalmente, al massimo 1.000 caratteri, `speaker_role` (`caller` o `agent`) e `turn_index`; le citazioni più lunghe restituite dal modello vengono rifiutate anziché troncate e l'evidenza è `null` ogni volta che il relativo campo è `null` |
| `extracted_data.verification` | string | `verified` solo quando il passaggio indipendente sulle evidenze ha restituito esattamente un verdetto valido per ogni campo candidato. `unavailable` indica che il passaggio non è riuscito, è scaduto, non aveva budget sufficiente oppure ha restituito output non valido o parziale. Un passaggio interamente non disponibile mantiene i valori basati strutturalmente per la revisione del cliente. Per l'output parziale, vengono applicati i verdetti validi e ogni candidato senza esattamente un verdetto valido viene impostato a null |
| `extracted_data.field_reasons` | object | Motivi indicizzati dai campi impostati a null dal fondamento strutturale o dal verificatore indipendente |
| `extracted_data.schema_version` | string | Hash dello schema esatto dei campi usato per questa estrazione |
| `extracted_at` | timestamp | Ora di completamento ISO 8601 |
| `model` | string | Modello usato per l'estrazione |

### `campaign.completed`

Inviato una volta quando una campagna passa da `running` a `completed`, sia che
la sua pianificazione sia terminata sia che tutti i contatti abbiano raggiunto
stati terminali. I nuovi tentativi del runner non emettono un altro evento.
Questo evento del ciclo di vita a livello di organizzazione viene inviato solo
agli endpoint con ambito organizzazione, non agli endpoint con ambito agente.
Non bloccante.

```json
{
  "data": {
    "campaign_id": "3f6b2c9e-2a0d-4c63-b6d6-a708dc98f403",
    "name": "May win-back",
    "agent_id": 12,
    "status": "completed",
    "started_at": "2026-04-20T17:00:00Z",
    "completed_at": "2026-04-20T18:25:11Z",
    "counts": {
      "contacts_total": 150,
      "completed": 121,
      "failed": 11,
      "no_answer": 18,
      "remaining": 0
    }
  },
  "event_id": "8d8f52ce-6b46-423f-9dde-cea0b91ec135",
  "type": "campaign.completed"
}
```

I quattro conteggi degli esiti sono disgiunti e la loro somma è
`contacts_total`: `completed` contiene i contatti riusciti; `no_answer`
contiene i contatti terminali non riusciti/esauriti il cui esito finale è stata
nessuna risposta; `failed` contiene tutti gli altri contatti terminali non
riusciti/esauriti; e `remaining` contiene i contatti in attesa, pianificati o
attualmente in chiamata. Un contatto in attesa di un nuovo tentativo è
`remaining`, anche quando il suo tentativo più recente non ha ricevuto
risposta. Le chiamate in corso vengono riconciliate prima dello snapshot di
completamento emesso una sola volta. `started_at` corrisponde all'avvio della
campagna configurato oppure all'ora di creazione della campagna quando non è
stato configurato alcun avvio.

### `issue.reported`

Inviato quando viene creato un [rapporto su un problema](/api-reference/issue-reports) —
inviato da un utente dalla dashboard (`source: "user"`) oppure creato
automaticamente dalla valutazione della chiamata (`source: "system"`). Non
bloccante.

```json
{
  "data": {
    "call_id": 987654321,
    "issue_report": {
      "created_at": "2026-04-20T18:25:11.002Z",
      "description": "Five-second silence before responding to the main question.",
      "id": 4321,
      "severity": "warning",
      "source": "system",
      "status": "open",
      "title": "Agent paused too long"
    }
  },
  "event_id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
  "type": "issue.reported"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |
| `issue_report.severity` | string | `critical`, `warning` o `info` |
| `issue_report.status` | string | `open` o `resolved` |
| `issue_report.source` | string | `user` (inviato dalla dashboard) o `system` (creato dalla valutazione) |

<Note>
  Rivalutare una chiamata ricrea i rapporti sui problemi generati dal sistema,
  emettendo nuovamente `issue.reported` per i rapporti ricreati. Esegui la
  deduplicazione su `call_id` + `title` se desideri una sola notifica per
  ciascun problema sottostante.
</Note>

### `issue.escalated`

Inviato quando un modello di problema viene inviato a ThunderPhone per la
revisione del personale: dopo **Segnala a ThunderPhone**, oppure quando
Correggi con l'IA non può confermare una correzione lato cliente e instrada
automaticamente il problema. Solo gli endpoint a livello di organizzazione
ricevono questo evento.

```json
{
  "data": {
    "automatic": false,
    "cluster_id": "7ac2844c-2df0-4fa8-a560-7378da649e19",
    "escalation_id": "ec99f52b-c8c0-41dd-a4f2-dd8a07b10894",
    "status": "open"
  },
  "event_id": "d8f8f420-7a42-45ba-bcf1-b747f9bbecda",
  "type": "issue.escalated"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `automatic` | boolean | `true` per un'escalation automatica; `false` per un'escalation manuale |
| `cluster_id` | UUID | Modello di problema escalato |
| `escalation_id` | UUID | Record di escalation |
| `status` | string | `open` quando l'evento viene emesso |

Questa è una notifica, non il pacchetto di evidenze. Usa `cluster_id` per
correlarla al modello di problema. Consulta [Segnala a ThunderPhone](/it/guides/issues).

---

## Eventi delle chiamate di test

### `test-call.completed`

Inviato quando una
[esecuzione di chiamata di test](/api-reference/test-calls#test-call-run-object)
raggiunge uno stato terminale — `completed` o `failed`, incluse le esecuzioni
che non sono riuscite all'avvio e non hanno mai prodotto una chiamata. Non bloccante. Utile
per integrare esecuzioni CI batch nei sistemi di chat/notifiche.

```json
{
  "data": {
    "test_call_run": {
      "call_id": 987654321,
      "completed_at": "2026-04-20T18:25:04.822Z",
      "error_message": "",
      "id": 7110,
      "status": "completed",
      "target_id": 12,
      "target_type": "agent"
    }
  },
  "event_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
  "type": "test-call.completed"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente che ha gestito la chiamata, quando assegnato |
| `agent_name` | string \| null | Agente che ha gestito la chiamata, quando assegnato |
| `test_call_run.target_type` | string | `agent` o `phone_number` |
| `test_call_run.target_id` | integer | ID dell'agente o del numero di telefono a cui era destinata l'esecuzione, corrispondente a `target_type` |
| `test_call_run.status` | string | `completed` o `failed` |
| `test_call_run.call_id` | integer \| null | `null` quando l'esecuzione non è riuscita prima dell'avvio di una chiamata |
| `test_call_run.error_message` | string | Vuoto in caso di esito positivo |

---

## Eventi di avviso

### `alert.triggered`

Inviato quando una [regola di avviso](/it/guides/alerts) con il canale **Invia a
webhook per sviluppatori** abilitato supera la propria soglia.
Non bloccante. Una regola si attiva una volta e poi rispetta il proprio periodo di attesa, quindi una
violazione persistente produce un evento per ogni finestra di attesa.

```json
{
  "data": {
    "comparator": "lt",
    "event_id": "b8e6a1d4-2c3f-4a5b-9c8d-7e6f5a4b3c2d",
    "fired_at": "2026-04-20T18:00:00+00:00",
    "metric": "success_rate",
    "metric_value": 71.4,
    "rule_id": "d2c3b4a5-6f7e-4d8c-9b0a-1c2d3e4f5a6b",
    "rule_name": "Success rate below 80%",
    "threshold": 80.0,
    "window_hours": 24
  },
  "event_id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f7a",
  "type": "alert.triggered"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `event_id` (in `data`) | UUID | ID di **attivazione** dell'avviso — distinto dall'`event_id` di consegna dell'envelope |
| `rule_id`, `rule_name` | UUID, string | La regola che si è attivata |
| `metric` | string | `success_rate`, `failure_rate`, `avg_score`, `call_volume` o `suite_regression` |
| `comparator` | string | `lt`, `lte`, `gt` o `gte` |
| `metric_value` | number | Il valore della metrica nella finestra in cui la regola si è attivata |
| `threshold` | number | La soglia configurata |
| `window_hours` | integer | Finestra di valutazione precedente |
| `fired_at` | timestamp | |

Consulta la [guida agli avvisi](/it/guides/alerts) per creare regole, metriche,
periodi di attesa e canali email / Slack.

---

## Eventi di migrazione

### `migration.call.complete`

Inviato quando termina una chiamata effettuata tramite
[`POST /v1/migrations/{id}/calls`](/api-reference/migration-calls),
indipendentemente dalla piattaforma che l'ha effettuata. Non bloccante. Arriva fino a circa 5 minuti
dopo la fine della chiamata. `data` contiene tutti i campi di
[`telephony.complete`](/it/webhooks/call-complete) più un blocco `migration`. Una
chiamata effettuata da ThunderPhone invia anche `telephony.complete` come di consueto, con lo
stesso `call_id`. Una chiamata sull'altra piattaforma che non è terminata dopo 2
ore, oppure la cui migrazione è terminata o ha perso prima la propria chiave, viene inviata con
`status: "unknown"` e senza trascrizione.

```json
{
  "data": {
    "agent_id": 42,
    "agent_name": "Front desk",
    "billable_minutes": null,
    "billing_total_cents": null,
    "call_id": null,
    "direction": "outbound",
    "duration_seconds": 94,
    "end_reason": "user_hangup",
    "end_time": "2026-10-06T17:01:34+00:00",
    "extracted_data": null,
    "from_number": "+15551234567",
    "migration": {
      "arm": "vendor",
      "id": "5f0c2a9e-7b1d-4c3e-8a6f-2d9e1b4c7a30",
      "metadata": {
        "lead_id": "8812"
      },
      "routing_id": "9b2f8c1e-4d3a-4f6b-8e2d-1a7c5b9e0f34",
      "vendor": "retell",
      "vendor_call_id": "call_6a1f0e",
      "vendor_cost_usd": "0.1240"
    },
    "product": "",
    "recording_mode": "vendor",
    "recording_url": "https://…",
    "start_time": "2026-10-06T17:00:00+00:00",
    "status": "completed",
    "summary": "The callee booked a table for two on Thursday.",
    "thunderphone_retained_call_content": true,
    "to_number": "+14155552671",
    "transcripts": [
      {
        "content": "Hi Ada, this is Rosa's calling about your booking.",
        "role": "agent"
      },
      {
        "content": "Yes, Thursday works.",
        "role": "user"
      }
    ],
    "transfer_number": null,
    "unresolved_variables": [],
    "variables": {
      "first_name": "Ada"
    },
    "voice": ""
  },
  "event_id": "7c1e2f3a-4b5c-4d6e-8f7a-9b0c1d2e3f4a",
  "type": "migration.call.complete"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `migration.id` | UUID | La migrazione |
| `migration.routing_id` | UUID | La chiamata instradata, come restituita quando l'hai effettuata |
| `migration.arm` | string | `ours` (l'ha effettuata ThunderPhone) oppure `vendor` (l'ha effettuata l'altra piattaforma) |
| `migration.vendor` | string | `retell`, `vapi`, `elevenlabs` o `bland` |
| `migration.vendor_call_id` | string \| null | L'id della chiamata dell'altra piattaforma; `null` per `ours` |
| `migration.metadata` | object | I `metadata` inviati durante l'effettuazione della chiamata |
| `migration.vendor_cost_usd` | string \| null | Il costo della chiamata riportato dall'altra piattaforma, se comunicato |
| `call_id` | integer \| null | L'id della chiamata ThunderPhone; `null` per `vendor` |
| `status` | string | Per `vendor`: `completed` quando il destinatario ha parlato, `failed` quando non ha parlato, `unknown` come sopra. Per `ours`: come in `telephony.complete` |

Per una chiamata `vendor`, ThunderPhone non dispone di dati di fatturazione o estrazione:
`billable_minutes`, `billing_total_cents` e `extracted_data` sono `null`,
`product` e `voice` sono vuoti, `recording_mode` è `vendor` e
`recording_url` è il link dell'altra piattaforma, se ne ha fornito uno.

### `migration.rollback`

Inviato quando il passaggio graduale di una migrazione riporta automaticamente tutte le chiamate all'altra piattaforma: 3 chiamate non sono riuscite a connettersi a ThunderPhone entro 15 minuti, 2 chiamate inviate a ThunderPhone sono terminate prima che l'agente rispondesse oppure il tasso di esito delle attività di ThunderPhone è sceso oltre il divario configurato rispetto a quello dell'altra piattaforma. Non bloccante, una volta per ogni rollback. Dopo questo evento, la quota di ThunderPhone è 0% e la migrazione è in pausa finché qualcuno non la riprende nella scheda Migrazione dell'agente. Il payload non contiene numeri di telefono, trascrizioni né ID chiamata.

```json
{
  "data": {
    "agent_id": 42,
    "agent_name": "Front desk",
    "dropped": 0,
    "migration_id": "5f0c2a9e-7b1d-4c3e-8a6f-2d9e1b4c7a30",
    "ours": {
      "graded": 20,
      "success_rate": 0.8
    },
    "ours_failed": 3,
    "ours_percent": 0,
    "previous_percent": 25,
    "reason": "ours_failed_burst",
    "rolled_back_at": "2026-10-10T12:05:00+00:00",
    "step": 1,
    "theirs": {
      "graded": 20,
      "success_rate": 0.8
    },
    "vendor": "retell"
  },
  "event_id": "3d1f6b2a-8c4e-5a7b-9d0e-2f1a3b4c5d6e",
  "type": "migration.rollback"
}
```

| Campo | Tipo | Descrizione |
|-------|------|-------------|
| `migration_id` | UUID | La migrazione |
| `vendor` | string | `retell`, `vapi`, `elevenlabs` o `bland` |
| `reason` | string | `ours_failed_burst` (3 connessioni non riuscite in 15 minuti), `dropped_calls` (2 chiamate terminate prima che l'agente rispondesse, entro 30 minuti) o `rate_gap` (divario nel tasso di esito delle attività su almeno `rollback_min_calls` chiamate valutate per lato) |
| `previous_percent` | integer | La quota di chiamate di ThunderPhone prima del rollback |
| `ours_percent` | integer | Sempre `0` |
| `step` | integer \| null | Il passaggio della pianificazione in cui si trovava (a partire da 0) |
| `ours` / `theirs` | object \| null | Le chiamate valutate nel passaggio corrente e il relativo tasso di successo; `theirs` può riferirsi agli ultimi 30 giorni quando il passaggio ha troppe poche chiamate. `null` se non ce n'erano |
| `ours_failed` | integer | Connessioni non riuscite conteggiate negli ultimi 15 minuti |
| `dropped` | integer | Chiamate conteggiate come interrotte negli ultimi 30 minuti |
| `rolled_back_at` | timestamp | |

---

## Correlati

<CardGroup cols={2}>
  <Card title="telephony.incoming / web.incoming" icon="phone" href="/it/webhooks/call-incoming">
    Il payload bloccante delle chiamate in entrata a cui devi rispondere.
  </Card>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/it/webhooks/call-complete">
    Trascrizione e metriche post-chiamata.
  </Card>
  <Card title="Endpoint webhook" icon="bolt" href="/it/webhooks/endpoints">
    Iscrivi un URL a un sottoinsieme di questi eventi.
  </Card>
  <Card title="Strumenti funzione" icon="screwdriver-wrench" href="/it/tools/overview">
    Come vengono generati gli eventi `telephony.tool` / `web.tool`.
  </Card>
</CardGroup>
