Endpoints de webhook
Gestiona varias URL de webhook con secretos y filtros de eventos por endpoint.
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 requerido | 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}/test | admin+ | Enviar una entrega de prueba firmada |
Objeto endpoint
{
"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"
}| Campo | Tipo | Descripción |
|---|---|---|
id | UUID | ID del endpoint |
label | string | Nombre visible, de 1 a 120 caracteres |
url | string | URL HTTPS; se permite http://localhost para desarrollo |
events | array de string | Tipos de eventos suscritos (consulta los valores válidos). Un arreglo vacío se suscribe a todos los eventos, excepto los eventos explícitos por turno (telephony.turn / web.turn) |
status | string | 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) |
secret_hint | string | Los primeros 4 y últimos 4 caracteres del secreto de firma con puntos suspensivos (a1b2…9f0e), suficientes para comparar el secreto que guardaste localmente sin exponer el valor completo |
created_at, updated_at | timestamp |
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 conocer la
estructura de carga útil de cada tipo.
telephony.incoming,telephony.complete,telephony.tool,telephony.turnweb.incoming,web.complete,web.tool,web.turncall.gradedissue.reportedtest-call.completedalert.triggered
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; devolverlo aactivesiempre depende de ti.failing— se establece automáticamente cuando una entrega al endpoint agota toda su programación de reintentos (8 intentos durante 24 horas) sin obtener nunca un 2xx. Un endpoint con errores no recibe más tráfico. Una vez que el endpoint esté corregido, aplicaPATCHpara cambiar su estado aactive; las entregas cuya programación de reintentos aún no haya terminado se reanudan donde 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 endpoint.
Crear 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 | Vacío u omitido se suscribe a todos los eventos excepto telephony.turn / web.turn, que requieren una suscripción explícita. Debe usar los valores enumerados en Tipos de eventos válidos; se eliminan los duplicados |
Devuelve 201 Created con el objeto Endpoint, además
de un campo adicional secret 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"
}Actualizar 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 |
Devuelve 200 OK con el objeto Endpoint actualizado.
Enviar una entrega de prueba
Envía un evento sintético webhook.test a un endpoint mediante el flujo normal
de entrega, incluida la serialización JSON canónica,
X-ThunderPhone-Signature, el registro de entregas y la gestión 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 events
de un endpoint. Si el primer intento falla, la entrega sigue el mismo
calendario de reintentos que las entregas de eventos normales.
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.