Open in
Endpoints de webhook
Gestiona varias URL de webhook con secretos por endpoint y filtros de eventos.
El sistema de webhooks basado en endpoints te permite registrar múltiples destinos por organización, cada uno con su propio secreto, su propio estado y su propia suscripción a un subconjunto de tipos de eventos. Este es el modelo recomendado para todas las integraciones nuevas.
Compáralo con el webhook heredado de URL única, que se mantiene por compatibilidad con versiones anteriores, pero solo admite una URL por organización.
Endpoints
| Método | Ruta | Rol obligatorio | Descripción |
|---|---|---|---|
GET | /v1/developer/webhook-endpoints | admin+ | Listar endpoints |
POST | /v1/developer/webhook-endpoints | admin+ | Crear un endpoint |
PATCH | /v1/developer/webhook-endpoints/{endpoint_id} | admin+ | Actualizar etiqueta / URL / eventos / estado |
DELETE | /v1/developer/webhook-endpoints/{endpoint_id} | admin+ | Eliminar un endpoint |
POST | /v1/developer/webhook-endpoints/{endpoint_id}/rotate-secret | admin+ | Reemplazar el secreto de firma |
POST | /v1/developer/webhook-endpoints/{endpoint_id}/test | admin+ | Enviar una entrega de prueba firmada |
GET | /v1/developer/webhook-deliveries | admin+ | Inspeccionar resultados recientes de entregas de endpoints y heredadas |
Objeto de endpoint
{
"id": "c4d5e6f7-...",
"label": "Production — Call events",
"url": "https://example.com/thunderphone/hook",
"events": ["telephony.incoming", "telephony.complete"],
"status": "active",
"agent_id": 42,
"agent_name": "Support Agent",
"secret_hint": "a1b2…9f0e",
"paused_at": null,
"pause_last_error": "",
"pause_undelivered_count": null,
"created_at": "2026-04-20T18:24:10.113Z",
"updated_at": "2026-04-20T18:24:10.113Z"
}| Campo | Tipo | Descripción |
|---|---|---|
id | UUID | ID del punto de conexión |
label | cadena | Nombre visible, de 1 a 120 caracteres |
url | cadena | URL HTTPS; se permite http://localhost para desarrollo |
events | matriz de cadenas | Tipos de eventos suscritos (consulta los valores válidos). Una matriz vacía se suscribe a todos los eventos, excepto a los eventos explícitos por turno (telephony.turn / web.turn) |
status | cadena | active, disabled (pausado manualmente) o failing (se establece automáticamente cuando una entrega agota su programación de reintentos de 24 h sin un solo 2xx) |
agent_id | entero | null | Agente al que se limita este punto de conexión; null significa para toda la organización |
agent_name | cadena | null | Nombre del agente limitado, o null para un punto de conexión de toda la organización |
secret_hint | cadena | Los primeros 4 y últimos 4 caracteres del secreto de firma con puntos suspensivos (a1b2…9f0e); es suficiente para comparar el secreto que guardaste localmente sin exponer el valor completo |
paused_at | marca de tiempo | null | Cuándo ThunderPhone estableció el punto de conexión en failing. null mientras está active o disabled |
pause_last_error | cadena | El último error de entrega cuando se pausó el punto de conexión, por ejemplo HTTP 503: Service Unavailable. Vacío salvo que esté en failing |
pause_undelivered_count | entero | null | Eventos no entregados desde la última entrega exitosa del punto de conexión, contados cuando se pausó |
created_at, updated_at | marca de tiempo |
Tipos de eventos válidos
events se valida con respecto a este conjunto exacto: los valores fuera de la lista
devuelven 400. Consulta el catálogo de eventos para ver la
estructura de la carga útil de cada tipo.
telephony.incoming,telephony.complete,telephony.tool,telephony.turnweb.incoming,web.complete,web.tool,web.turnsms.sent,sms.failedsms.received(reservado; aún no se emite)call.graded,call.data_extracted,call.transfer_completedcampaign.completedissue.reported,issue.escalatedtest-call.completedalert.triggered
issue.escalated no tiene contexto de agente y se entrega únicamente a
endpoints de toda la organización.
voice.ready y voice.failed no se pueden seleccionar explícitamente. Para recibirlos,
crea un endpoint de toda la organización con events: []. Una lista de eventos vacía
recibe todos los eventos compatibles excepto telephony.turn y web.turn,
que se deben seleccionar explícitamente.
Estados de los endpoints
active— las entregas fluyen normalmente.disabled— pausado manualmente mediantePATCH. No se envían solicitudes. Nunca cambiamos el estado de un endpointdisabled; volver a cambiarlo aactivesiempre depende de ti.failing— se establece automáticamente cuando una entrega al endpoint agota todo su programa de reintentos (8 intentos durante 24 horas) sin recibir nunca un 2xx. Un endpoint con errores no recibe más tráfico. Enviamos un correo electrónico a los propietarios y administradores de tu organización cuando esto sucede, y el panel muestra el endpoint pausado con un botón Reactivar. Una vez que el endpoint se corrija, cambia su estado mediantePATCHde nuevo aactive; las entregas cuyo programa de reintentos aún no haya terminado se reanudarán donde se quedaron.
Listar endpoints
curl https://api.thunderphone.com/v1/developer/webhook-endpoints \
-H "Authorization: Bearer sk_live_YOUR_API_KEY"Devuelve un arreglo de objetos de endpoint.
Pasa ?agent_id=42 para devolver solo los endpoints asociados a ese agente.
Endpoints asociados a un agente
Los endpoints de toda la organización reciben todos los eventos coincidentes. Un endpoint con
agent_id recibe solo los eventos coincidentes de las llamadas atendidas por ese agente;
los eventos sin contexto de agente, como alert.triggered, nunca llegan a él. También
puedes crear y administrar estos endpoints desde la sección
Webhooks del creador de agentes.
Crea un endpoint
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Production — Call events",
"url": "https://example.com/thunderphone/hook",
"events": ["telephony.incoming", "telephony.complete"]
}'result = requests.post(
"https://api.thunderphone.com/v1/developer/webhook-endpoints",
headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
json={
"label": "Production — Call events",
"url": "https://example.com/thunderphone/hook",
"events": ["telephony.incoming", "telephony.complete"],
},
).json()
secret = result["secret"]
endpoint_id = result["id"]Campos de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
label | cadena | sí | 1–120 caracteres |
url | cadena | sí | URL HTTPS (http permitido solo para localhost / 127.0.0.1) |
events | arreglo | no | Si está vacío o se omite, se suscribe a todos los eventos excepto telephony.turn / web.turn, que requieren una suscripción explícita. Debe usar los valores indicados en Tipos de eventos válidos; se eliminan los duplicados |
agent_id | entero | nulo | no | Limita la entrega a un agente de esta organización; omite o usa null para un endpoint de toda la organización |
Devuelve 201 Created con el objeto Endpoint más
un campo secret adicional de nivel superior que contiene la clave de firma sin procesar: una
cadena hexadecimal de 48 caracteres:
{
"id": "c4d5e6f7-…",
"label": "Production — Call events",
"url": "https://example.com/thunderphone/hook",
"events": ["telephony.incoming", "telephony.complete"],
"status": "active",
"secret_hint": "a1b2…9f0e",
"created_at": "2026-04-20T18:24:10.113Z",
"updated_at": "2026-04-20T18:24:10.113Z",
"secret": "a1b2c37e08d94f5b16a2c8d90e7f3a4b5c6d7e8f90a19f0e"
}Actualiza un endpoint
curl -X PATCH https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Production — Call + Grade events",
"events": ["telephony.incoming", "telephony.complete", "call.graded"]
}'| Campo | Tipo | Descripción |
|---|---|---|
label | cadena | |
url | cadena | |
events | arreglo | |
status | cadena | active o disabled. Establece active para volver a habilitar un endpoint que el servidor marcó como failing |
agent_id | entero | nulo | Establece un ID de agente para limitar el endpoint o null para que sea de toda la organización |
Devuelve 200 OK con el objeto Endpoint actualizado.
Rota el secreto de firma
Reemplaza el secreto de firma de un endpoint, por ejemplo, si se perdió o podría haberse filtrado. Para un endpoint con alcance de agente, también puedes usar el panel: abre la sección Webhooks del agente y selecciona Regenerar secreto en el endpoint. Los endpoints de toda la organización se rotan mediante la API.
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../rotate-secret \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
include_copies | booleano | no | El valor predeterminado es true. También proporciona el nuevo secreto a los demás endpoints de tu organización que tienen la misma URL y el mismo secreto actual, como las copias de este endpoint en otros agentes, para que un receptor siga verificando con un solo secreto |
Devuelve 200 OK:
{
"endpoint": { "id": "c4d5e6f7-...", "secret_hint": "7f3a…c21d", "...": "..." },
"secret": "7f3a90b2c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5c21d",
"rotated_endpoint_ids": ["c4d5e6f7-..."]
}| Campo | Tipo | Descripción |
|---|---|---|
endpoint | objeto | El objeto Endpoint con su nuevo secret_hint |
secret | cadena | El nuevo secreto de firma. Se devuelve solo en esta respuesta |
rotated_endpoint_ids | arreglo de UUID | Cada endpoint que ahora usa el nuevo secreto |
Enviar una entrega de prueba
Envía un evento sintético webhook.test a un endpoint mediante el flujo de
entrega normal, incluida la serialización canónica de JSON, ambos
encabezados de firma, el registro de entregas y el seguimiento de reintentos.
La prueba se dirige al endpoint seleccionado independientemente de su filtro events.
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
-H "Authorization: Bearer sk_live_YOUR_API_KEY"El endpoint recibe un sobre como este:
{
"data": {
"message": "ThunderPhone webhook test",
"sent_at": "2026-07-17T20:12:34.567890+00:00"
},
"event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
"type": "webhook.test"
}La API devuelve 200 OK después del primer intento, incluso si el destino
devuelve un error. Revisa success, status, response_code y error
para conocer el resultado de la entrega:
{
"success": true,
"event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
"event_type": "webhook.test",
"status": "delivered",
"response_code": 204,
"error": ""
}webhook.test es sintético y no se puede agregar a la suscripción de events
de un endpoint. Si el primer intento falla, ThunderPhone lo reintenta una vez aproximadamente
un minuto después y luego se detiene; la entrega muestra entonces status: "failed"
en Depurar entregas. Una entrega de prueba nunca marca
el endpoint como failing.
Para configurar un desencadenador con una estructura de evento real, pasa un
event_type opcional. La entrega sigue siendo sintética y contiene "sample": true;
las muestras relacionadas con llamadas usan call_id: 0 y agent_id: 0.
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"event_type":"call.graded"}'event_type acepta cualquier valor de Tipos de evento válidos.
Omitirlo conserva el comportamiento genérico de webhook.test.
Eliminar un endpoint
curl -X DELETE https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
-H "Authorization: Bearer sk_live_YOUR_API_KEY"Devuelve 204 No Content. La entrega a la URL se detiene de inmediato;
se abandonan los reintentos en curso.
Depurar entregas
Antes de concluir que no se envió un webhook, revisa
GET /v1/developer/webhook-deliveries.
Muestra intentos recientes de ambos sistemas de webhooks, incluido el id de llamada,
el origen de la URL, el estado HTTP, el número de intentos, la categoría de error permitida y la hora del próximo
reintento. Nunca devuelve la carga útil del evento, la transcripción, el texto de error almacenado,
el cuerpo de la respuesta ni la ruta de la URL.
También puedes ver el mismo historial reciente en Agentes → selecciona un agente → Webhooks → Entregas recientes. Las filas muestran la etiqueta del endpoint y el origen de la URL usado por el último intento. Este es un estado operativo, no un registro de auditoría inmutable: eliminar un endpoint también elimina sus filas de entrega.
Para un 404 de n8n, primero confirma que el flujo de trabajo esté activo, acepte POST y use
la URL de webhook de producción en lugar de la URL de prueba. Un 401 o 403 indica un problema de
autenticación o validación de firma; los tiempos de espera indican latencia
o disponibilidad del destino; los errores de TLS indican un problema con la cadena de certificados, el nombre de host o el vencimiento.