ThunderPhone 2.0 ya está disponible.Empieza por tu cuenta desde 2¢/min.Lee el anuncio

Webhooks

Catálogo de eventos

Todos los tipos de eventos de webhook que emite ThunderPhone.

Cada cuerpo de webhook tiene un campo type cuyo valor es uno de los tipos de eventos de esta página. Cuando te suscribes a un endpoint, el arreglo events debe contener los tipos de eventos que quieres (o estar vacío para suscribirte a todo, excepto los eventos por turno telephony.turn / web.turn, que se entregan solo a endpoints que los indican explícitamente).

Dos estilos de entrega incluyen estos eventos:

  • Las entregas a endpoints siempre son notificaciones no bloqueantes con reintentos: responde con cualquier código 2xx; el sobre incluye un event_id para deduplicar.
  • Los intercambios bloqueantes se ejecutan solo en el webhook heredado de URL única: la solicitud de configuración telephony.incoming / web.incoming (números en modo webhook: 13 s, incluido un reintento; claves de widget en modo webhook: 10 s) y el despacho de herramientas en modo webhook. Tu respuesta da forma a la llamada en curso.

Las cargas de ejemplo a continuación muestran el sobre de endpoint en su orden de transmisión (claves ordenadas alfabéticamente: data, event_id, type); las entregas heredadas incluyen los mismos data sin event_id.

Eventos de llamadas

telephony.incoming

Se envía cuando una llamada entrante llega a uno de tus números de teléfono. Las entregas al endpoint son notificaciones sin confirmación enviadas para todas las llamadas entrantes, tanto si el número está configurado para un agente como para un webhook. Los números sin un agente asignado también reciben la solicitud de configuración bloqueante en el webhook heredado; consulta telephony.incoming / web.incoming para ver el esquema completo de solicitud / respuesta.

{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}
CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado

telephony.complete

Se envía cuando termina una llamada telefónica entrante o saliente. No bloqueante. Incluye la transcripción, la URL de la grabación cuando está disponible y el resumen de facturación. Consulta telephony.complete / web.complete para ver el esquema de la carga útil.

CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado

telephony.tool

Se envía después de que una llamada telefónica invoque una herramienta de función. Notificación de auditoría no bloqueante: la herramienta ya se ejecutó cuando se entrega este evento; cubre tus propias herramientas de función y la herramienta integrada send_sms (no otras herramientas integradas, de base de conocimientos, de conexión de aplicaciones ni MCP). Para send_sms, tanto arguments.to como arguments.body son [REDACTED]. Las transcripciones de finalización también los ocultan; obtén el contenido y el destinatario desde el recurso SMS con ámbito de organización mediante el message_id de la respuesta.

{
  "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 es el resultado ejecutado: {"status": <http status>, "response": <your endpoint's JSON>} si tiene éxito, o {"status": <status>, "error": "<message>"} si falla.

CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado

telephony.turn

Se envía mientras una llamada telefónica está en curso, una vez por cada intervención con voz a medida que sucede: las respuestas habladas del agente y las intervenciones transcritas de quien llama. Te permite seguir la conversación en vivo mediante webhooks simples en lugar de consultar repetidamente GET /v1/calls/{call_id}/transcript. No bloqueante.

{
  "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"
}
CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado
positionintegerÍndice de la intervención en el historial de la llamada; una identidad estable para ordenar
rolestringassistant (voz del agente) o user (voz de quien llama)
textstringTexto de la transcripción de la intervención tal como se conoce al momento de la emisión
entry_typestringTipo de entrada subyacente del historial: completion (agente), o user_turn / span (quien llama)
start_ms, end_msintegerDesplazamientos de audio en ms desde el inicio de la llamada; presentes solo cuando el tiempo de reproducción ya se conocía al momento de la emisión

web.incoming

El equivalente de telephony.incoming para el canal web se envía cuando inicia una sesión de widget web o una llamada de prueba de micrófono del creador. Las entregas al endpoint son sin confirmación para cada sesión web. Las claves publicables en mode="webhook" también reciben la solicitud de configuración bloqueante en el webhook heredado; esa solicitud bloqueante tiene una estructura diferente (origin_domain, publishable_key_prefix; sin números de teléfono). 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 siempre es el literal "web". Para las sesiones del widget en modo webhook, to_number está vacío (el número del agente de la sesión se asigna después de la configuración); para las llamadas de prueba de micrófono del creador, origin_domain y publishable_key_prefix están vacíos.

CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado

web.complete

El equivalente de telephony.complete para el canal web cubre las llamadas del widget web (direction: "web") y las llamadas de prueba de micrófono del creador (direction: "test"). No bloqueante. Tiene la misma estructura de carga útil que telephony.complete, además de origin_domain, con from_number establecido en "web".

CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado

web.tool

El equivalente de telephony.tool para el canal web. data contiene origin_domain en lugar de from_number / to_number.

CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado

web.turn

El equivalente de telephony.turn para el canal web, que cubre las llamadas del widget web y las llamadas de prueba de micrófono del creador. Tiene la misma estructura de carga útil, con origin_domain en lugar de from_number / to_number. Al igual que telephony.turn, requiere una suscripción explícita: nunca se entrega mediante un arreglo events vacío.

CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando había uno asignado
agent_namestring | nullAgente que atendió la llamada, cuando había uno asignado

call.transfer_completed

Se envía una vez por llamada con el resultado final de una transferencia de llamada: una transferencia en frío o el puente entre personas que deja una transferencia asistida después de que el agente se retira. No bloquea y se entrega solo a endpoints (nunca al webhook heredado de una sola URL). Llega después de telephony.complete de la llamada: una vez que el operador se hace cargo de la llamada o la transferencia falla, o, cuando ThunderPhone establece un puente para la llamada, una vez que el puente termina.

{
  "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"
}
CampoTipoDescripción
call_idintegerLa llamada que se transfirió
agent_idinteger | nullAgente que gestionó la llamada, cuando se asignó uno
agent_namestring | nullAgente que gestionó la llamada, cuando se asignó uno
transfer_outcomestringrefer_accepted: el operador se hizo cargo de la llamada. bridged: ThunderPhone mantuvo conectados por sí mismo a quien llama y al destino, ya sea porque el operador rechazó una transferencia en frío o porque el agente de una transferencia asistida se retiró. bridge_unanswered: el operador rechazó una transferencia en frío y el destino no respondió la propia llamada de ThunderPhone. failed: la transferencia no se completó y la llamada terminó
destinationstring | nullEl número al que se transfirió la llamada
sip_statusinteger | nullEl estado SIP del operador cuando rechazó la transferencia en frío: 403 (por ejemplo, una troncal de Twilio sin transferencia de llamadas), 405 o 501. null cuando el operador no la rechazó
bridge_kindstring | nullSolo bridged: cold_fallback (una transferencia en frío rechazada que ThunderPhone conectó) o warm (las dos personas de una transferencia asistida después de que el agente se retiró)
bridge_secondsinteger | nullSolo bridged: el tiempo del puente que ThunderPhone facturó, en segundos
bridge_total_centsinteger | nullSolo bridged: el costo del puente en centavos de USD después de aplicar cualquier crédito de llamadas gratis, facturado por separado de billing_total_cents de la llamada

Los mismos valores están en el objeto de llamada como transfer_outcome, transfer_destination, transfer_sip_status, transfer_bridge_kind, transfer_bridge_seconds y transfer_bridge_total_cents. event_id es el mismo en cada entrega de una llamada, por lo que un informe repetido nunca genera un segundo evento.


Eventos de SMS

Los eventos de SMS describen los mensajes enviados a través de la cuenta de Twilio o Telnyx conectada de la organización. El cuerpo del mensaje se omite y to se redacciona. Recupera el mensaje con alcance de organización desde GET /v1/sms/{message_id} cuando se necesite su contenido o destinatario.

sms.sent

Se envía cuando el operador del cliente acepta una solicitud de SMS saliente. No es un comprobante de entrega 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

Se envía después de un rechazo permanente del operador, cuando se agotan los reintentos transitorios o cuando el resultado es terminalmente desconocido. error_code es un código estable de ThunderPhone y error_message indica la acción del cliente cuando está disponible. status: "unknown" significa que el operador pudo haber aceptado el SMS; concílialo en el registro del operador, ya que ThunderPhone no lo reenviará automáticamente.

sms.received

Reservado para la compatibilidad con SMS entrantes. No se emiten eventos sms.received en la versión actual. La configuración de webhooks entrantes del operador y la verificación de firmas se lanzarán por separado.


Eventos de voz

La creación de voces personalizadas es asíncrona. Estos eventos no bloqueantes te permiten reaccionar a un resultado final en lugar de consultar periódicamente el endpoint de detalles del clon.

voice.ready y voice.failed se entregan únicamente a un endpoint de toda la organización con events: []. No pueden seleccionarse como filtros de eventos explícitos.

voice.ready

Se envía cuando una voz personalizada termina de procesarse y puede asignarse 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

Se envía cuando el procesamiento de una voz personalizada alcanza un fallo 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"
}
CampoTipoDescripción
voice.idcadenaID público de la voz personalizada
voice.namecadenaValor de voz del agente con el formato custom:<public_id>
voice.display_namecadenaNombre de la voz visible para la organización
voice.languagecadenaCódigo de idioma único del clon
voice.gendercadenamale, female o una cadena vacía
voice.statuscadenaready para voice.ready; failed para voice.failed
voice.failure_reasoncadenaVacío en caso de éxito; detalle del fallo de procesamiento en caso de error
voice.created_at, voice.updated_atmarca de tiempoMarcas de tiempo ISO 8601
reasoncadenaDetalle del fallo; presente solo en voice.failed

Eventos de calidad

call.graded

Se envía cada vez que se completa una ejecución de calificación con IA para una llamada. No bloqueante.

{
  "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"
}
CampoTipoDescripción
agent_identero | nuloAgente que gestionó la llamada, cuando se asignó uno
agent_namecadena | nuloAgente que gestionó la llamada, cuando se asignó uno
grade.identeroID de la calificación
grade.scoreentero | nulo0–100
grade.call_outcomecadenasuccess, failure, unknown o no_conversation
grade.summarycadenaResumen de un párrafo
grade.detected_issuesarregloCadenas de problemas detectados por el evaluador
grade.statuscadenaSiempre completed — solo las ejecuciones finalizadas emiten eventos
grade.grader_modelcadenaQué evaluador produjo el resultado (p. ej., heuristic-v1)
grade.graded_at, grade.created_atmarca de tiempo
reportobjeto | nuloEl informe de llamada orientado al cliente: etiqueta de resultado, indicador y motivo de atención necesaria, quien llama, resumen de una línea, experiencia de quien llama. En una calificación heurística inicial, es null o un informe pending cuyos campos son marcadores de posición; el evento de la calificación completa contiene el informe finalizado

call.data_extracted

Se envía cada vez que una extracción de datos estructurados se completa correctamente, incluido un reintento tardío después de telephony.complete / web.complete o una nueva ejecución manual mediante POST /v1/calls/{call_id}/extract. No bloqueante.

En un modo de extracción bloqueante, el evento de finalización normalmente espera no más que el presupuesto de extracción de 75 segundos. Si se pierde el proceso de trabajo de extracción, el drenaje de finalización de producción (cada cinco minutos) libera una finalización cuyo blocking_deadline_at haya vencido antes de iniciar otro intento de extracción. Un éxito posterior se entrega por separado mediante este 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"
}
CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando se asignó uno
agent_namestring | nullAgente que atendió la llamada, cuando se asignó uno
summarystring | nullEl resumen de llamada completado cuando el agente tiene activada la opción Generar un resumen de llamada, por lo que un evento de extracción tardío también entrega un resumen que no alcanzó la ventana de finalización; de lo contrario, null. Los agentes con un resumen pero sin campos de extracción nunca emiten este evento: obtén un resumen tardío con GET /v1/calls/{call_id}
extracted_data.statusstringSiempre completed para este evento
extracted_data.fieldsobjectValores indexados por las claves de campo de extracción configuradas; los valores no disponibles son null
extracted_data.evidenceobjectEvidencia indexada por campo de extracción. Un valor distinto de null contiene la cita exacta validada estructuralmente (como máximo 1,000 caracteres), speaker_role (caller o agent) y turn_index; las citas más largas devueltas por el modelo se rechazan en lugar de truncarse, y la evidencia es null siempre que su campo sea null
extracted_data.verificationstringverified solo cuando la pasada de evidencia independiente devolvió exactamente un veredicto válido para cada campo candidato. unavailable significa que la pasada falló, agotó el tiempo, no tuvo presupuesto suficiente o devolvió resultados malformados o parciales. Una pasada completamente no disponible conserva los valores fundamentados estructuralmente para la revisión del cliente. Para resultados parciales, se aplican los veredictos válidos y cada candidato sin exactamente un veredicto válido se establece en null
extracted_data.field_reasonsobjectMotivos indexados por los campos que se establecieron en null mediante fundamentación estructural o el verificador independiente
extracted_data.schema_versionstringHash del esquema de campos exacto usado para esta extracción
extracted_attimestampHora de finalización en ISO 8601
modelstringModelo usado para la extracción

campaign.completed

Se envía una vez cuando una campaña pasa de running a completed, ya sea porque su programación terminó o porque todos los contactos alcanzaron estados terminales. Los reintentos del ejecutor no emiten otro evento. Este evento de ciclo de vida a nivel de organización se entrega solo a endpoints con alcance de organización, no a endpoints con alcance de agente. No bloqueante.

{
  "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"
}

Los cuatro conteos de resultados son mutuamente excluyentes y suman contacts_total: completed contiene contactos exitosos; no_answer contiene contactos fallidos o agotados en estado terminal cuyo resultado final fue sin respuesta; failed contiene todos los demás contactos fallidos o agotados en estado terminal; y remaining contiene contactos pendientes, programados o a los que se está llamando actualmente. Un contacto que espera un reintento es remaining, incluso si su intento más reciente no recibió respuesta. Las llamadas en curso se concilian antes de la instantánea única de finalización. started_at es el inicio configurado de la campaña o la hora de creación de la campaña cuando no se configuró ningún inicio.

issue.reported

Se envía cuando se crea un reporte de problema: ya sea presentado por un usuario desde el dashboard (source: "user") o automáticamente mediante la calificación de llamadas (source: "system"). No bloqueante.

{
  "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"
}
CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando se asignó uno
agent_namestring | nullAgente que atendió la llamada, cuando se asignó uno
issue_report.severitystringcritical, warning o info
issue_report.statusstringopen o resolved
issue_report.sourcestringuser (presentado desde el dashboard) o system (creado mediante calificación)

issue.escalated

Se envía cuando se envía un patrón de problemas a ThunderPhone para revisión del personal: después de Reportar a ThunderPhone, o cuando Corregir con IA no puede confirmar una solución del lado del cliente y enruta el problema automáticamente. Solo los endpoints de toda la organización reciben este 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"
}
CampoTipoDescripción
automaticbooleantrue para una escalación automática; false para una escalación manual
cluster_idUUIDPatrón de problemas escalado
escalation_idUUIDRegistro de escalación
statusstringopen cuando se emite el evento

Esta es una notificación, no el paquete de evidencia. Usa cluster_id para correlacionarla con el patrón de problemas. Consulta Reportar a ThunderPhone.


Eventos de llamadas de prueba

test-call.completed

Se envía cuando una ejecución de llamada de prueba alcanza un estado terminal: completed o failed, incluidas las ejecuciones que fallaron al iniciarse y nunca generaron una llamada. No bloqueante. Útil para integrar ejecuciones de CI por lotes con tus sistemas de chat/notificaciones.

{
  "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"
}
CampoTipoDescripción
agent_idinteger | nullAgente que atendió la llamada, cuando se asignó uno
agent_namestring | nullAgente que atendió la llamada, cuando se asignó uno
test_call_run.target_typestringagent o phone_number
test_call_run.target_idintegerEl ID del agente o del número de teléfono al que se dirigió la ejecución, según target_type
test_call_run.statusstringcompleted o failed
test_call_run.call_idinteger | nullnull cuando la ejecución falló antes de realizar una llamada
test_call_run.error_messagestringVacío si se realiza correctamente

Eventos de alertas

alert.triggered

Se envía cuando una regla de alerta con el canal Enviar a webhooks de desarrollador activado supera su umbral. No bloqueante. Una regla se activa una vez y luego respeta su período de espera, por lo que una infracción sostenida genera un evento por cada ventana de período de espera.

{
  "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"
}
CampoTipoDescripción
event_id (en data)UUIDEl ID de activación de la alerta, distinto del event_id de entrega del sobre
rule_id, rule_nameUUID, stringLa regla que se activó
metricstringsuccess_rate, failure_rate, avg_score, call_volume o suite_regression
comparatorstringlt, lte, gt o gte
metric_valuenumberEl valor de la métrica durante la ventana cuando se activó la regla
thresholdnumberEl umbral configurado
window_hoursintegerVentana de evaluación retrospectiva
fired_attimestamp

Consulta la guía de alertas para crear reglas, métricas, períodos de espera y los canales de correo electrónico / Slack.


Eventos de migración

migration.call.complete

Se envía cuando finaliza una llamada realizada mediante POST /v1/migrations/{id}/calls, sin importar qué plataforma la atendió. No bloquea. Llega hasta unos 5 minutos después de que termina la llamada. data incluye todos los campos de telephony.complete más un bloque migration. Una llamada realizada por ThunderPhone también envía telephony.complete como de costumbre, con el mismo call_id. Una llamada en la otra plataforma que no haya terminado después de 2 horas, o cuya migración haya finalizado o perdido su clave primero, se envía con status: "unknown" y sin transcripción.

{
  "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"
}
CampoTipoDescripción
migration.idUUIDLa migración
migration.routing_idUUIDLa llamada enrutada, tal como se devolvió cuando la realizaste
migration.armstringours (ThunderPhone la realizó) o vendor (la otra plataforma la realizó)
migration.vendorstringretell, vapi, elevenlabs o bland
migration.vendor_call_idstring | nullEl ID de llamada de la otra plataforma; null para ours
migration.metadataobjectLos metadata que enviaste al realizar la llamada
migration.vendor_cost_usdstring | nullEl costo de la llamada que informó la otra plataforma, cuando lo informó
call_idinteger | nullEl ID de llamada de ThunderPhone; null para vendor
statusstringPara vendor: completed cuando la persona llamada habló, failed cuando no lo hizo, unknown como se indicó anteriormente. Para ours: como en telephony.complete

Para una llamada vendor, ThunderPhone no tiene datos de facturación ni de extracción: billable_minutes, billing_total_cents y extracted_data son null, product y voice están vacíos, recording_mode es vendor y recording_url es el enlace de la otra plataforma, cuando proporcionó uno.

migration.rollback

Se envía cuando el cambio gradual de una migración devuelve automáticamente todas las llamadas a la otra plataforma: 3 llamadas no lograron conectarse a ThunderPhone en un plazo de 15 minutos, 2 llamadas enviadas a ThunderPhone terminaron antes de que el agente respondiera o la tasa de resultados de tareas de ThunderPhone cayó más que la diferencia configurada por debajo de la de la otra plataforma. No bloqueante, una vez por reversión. Después de esto, la proporción de ThunderPhone es del 0 % y la migración queda pausada hasta que alguien la reanude en la pestaña Migración del agente. La carga útil no incluye números de teléfono, transcripciones ni ID de llamadas.

{
  "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"
}
CampoTipoDescripción
migration_idUUIDLa migración
vendorcadenaretell, vapi, elevenlabs o bland
reasoncadenaours_failed_burst (3 conexiones fallidas en 15 minutos), dropped_calls (2 llamadas terminaron antes de que el agente respondiera, en un plazo de 30 minutos) o rate_gap (diferencia en la tasa de resultados de tareas en al menos rollback_min_calls llamadas evaluadas por cada lado)
previous_percententeroProporción de llamadas de ThunderPhone antes de la reversión
ours_percententeroSiempre 0
stepentero | nuloEl paso de programación en el que estaba (basado en 0)
ours / theirsobjeto | nuloLlamadas evaluadas en el paso actual y su tasa de éxito; theirs puede corresponder a los últimos 30 días cuando el paso tiene muy pocas llamadas. null cuando no hubo ninguna
ours_failedenteroConexiones fallidas contabilizadas en los últimos 15 minutos
droppedenteroLlamadas contabilizadas como abandonadas en los últimos 30 minutos
rolled_back_atmarca de tiempo

Recursos relacionados