Open in
Catalogo degli eventi
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, l'array events deve contenere i
tipi di evento desiderati (oppure essere vuoto per iscriverti a tutti —
tranne gli eventi per turno telephony.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: rispondi con
un qualsiasi 2xx; l'involucro include un
event_idper la deduplicazione. - Gli scambi bloccanti avvengono solo sul
webhook legacy a URL singolo: la richiesta di
configurazione
telephony.incoming/web.incoming(numeri in modalità webhook: 13 s incluso un tentativo; chiavi widget in modalità webhook: 10 s) e l'invio degli strumenti 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. 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 per
lo schema completo di richiesta / risposta.
{
"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 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. 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.
{
"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.
Non bloccante.
{
"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 |
web.incoming
L'equivalente del canale web di telephony.incoming, inviato quando inizia una
sessione di widget web 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.
{
"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, 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 |
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,
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: 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.
{
"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
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} 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.
{
"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.
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.
{
"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.
{
"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 viene completata per una chiamata. Non bloccante.
{
"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 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 |
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.
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.
{
"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 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.
{
"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 —
inviato da un utente dalla dashboard (source: "user") oppure creato
automaticamente dalla valutazione della chiamata (source: "system"). Non
bloccante.
{
"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) |
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.
{
"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.
Eventi delle chiamate di test
test-call.completed
Inviato quando una
esecuzione di chiamata di test
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.
{
"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 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.
{
"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 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,
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 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.
{
"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.
{
"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
Il payload bloccante delle chiamate in entrata a cui devi rispondere.
Trascrizione e metriche post-chiamata.
Iscrivi un URL a un sottoinsieme di questi eventi.
Come vengono generati gli eventi telephony.tool / web.tool.