Los webhooks de AgendaPro permiten recibir notificaciones automaticas en tiempo real cuando ocurren cambios en reservas, clientes, pagos y fichas. En lugar de consultar periodicamente la API (polling), se configura una URL en tu sistema que recibira un POST con los datos del cambio cada vez que ocurra un evento relevante.
Configuracion
Los webhooks se configuran en AgendaPro desde Configuraciones > API Publica. Se debe proporcionar una URL que cumpla los siguientes requisitos:
Acepte requests POST: El servidor debe estar preparado para recibir solicitudes HTTP con metodo POST.
Acepte Content-Type: application/json: El cuerpo de la solicitud enviada por AgendaPro estara en formato JSON.
Responda con HTTP 200: Para confirmar la recepcion exitosa del webhook, el servidor debe responder con un codigo de estado 200.
Sea accesible publicamente: La URL debe ser alcanzable desde Internet. Se recomienda utilizar HTTPS para proteger los datos en transito.
Autenticacion de webhooks
AgendaPro envia los webhooks con HTTP Basic Auth en cada solicitud. Esto permite verificar que el webhook proviene legitimamente de AgendaPro y no de un tercero malicioso. Las credenciales son:
Credencial | Valor |
Username | Derivado del |
Password | La |
Para validar la autenticidad del webhook en tu servidor, se debe verificar que las credenciales del header Authorization coincidan con los valores esperados de tu empresa. Ejemplo de validacion en pseudocodigo:
# El header Authorization llega en formato Basic Auth # Authorization: Basic base64(username:password) # Decodificar y comparar con los valores esperados credentials = decode_base64(authorization_header) username, password = credentials.split(":") if username == expected_company_id AND password == expected_secret_key: # Webhook autentico, procesar else: # Rechazar con 401 UnauthorizedEstructura del payload
Todos los webhooks enviados por AgendaPro comparten la misma estructura base de JSON. El contenido del campo resource varia segun el tipo de recurso afectado.
{ "trigger": "create", "resource_type": "Booking", "created_at": "25/02/2026 14:30 UTC", "user": "usuario@empresa.com", "request_uuid": "abc123-def456-ghi789", "resource": { }, "changes": { }, "links": { } }Campos del payload
Campo | Tipo | Descripcion |
| string | Tipo de accion que disparo el webhook. Valores posibles: |
| string | Tipo de recurso afectado por la accion. Valores posibles: |
| string | Fecha y hora en que ocurrio el evento, en formato |
| string / null | Email del usuario que realizo la accion que disparo el webhook (ejemplo: |
| string | Identificador unico universal del request que genero el evento. Cada webhook tiene un UUID distinto. Util para implementar logica de idempotencia y evitar procesar el mismo evento dos veces en caso de reintentos o duplicados. |
| object | El recurso completo en su estado actual al momento del evento. Contiene el JSON del booking, client, payment o chart segun corresponda. Para un |
| object | Solo presente cuando |
| object | Solo presente para recursos de tipo |
Eventos disponibles
Reservas (Booking)
Evento | trigger | Descripcion |
Creacion |
| Se dispara cuando se crea una nueva reserva, ya sea desde la aplicacion web de AgendaPro, la aplicacion movil, el widget de reservas online, o la API publica. |
Actualizacion |
| Se dispara cuando se modifica una reserva existente. Solo se notifica si cambian campos monitoreados: |
Clientes (Client)
Evento | trigger | Descripcion |
Creacion |
| Se dispara cuando se registra un nuevo cliente en el sistema, ya sea desde el panel de administracion, el flujo de reserva, o la API publica. |
Actualizacion |
| Se dispara cuando se modifican los datos de un cliente. Solo se notifica si cambian campos monitoreados: |
Eliminacion |
| Se dispara cuando se elimina un cliente del sistema. |
Pagos (Payment)
Evento | trigger | Descripcion |
Creacion |
| Se dispara cuando se registra un nuevo pago, ya sea desde el punto de venta, al cerrar una atencion, o via la API publica. |
Actualizacion |
| Se dispara cuando se modifica un pago existente. Solo se notifica si cambian campos monitoreados: |
Eliminacion |
| Se dispara cuando se elimina un pago. |
Fichas (Chart)
Evento | trigger | Descripcion |
Creacion |
| Se dispara cuando se crea una nueva ficha clinica o de seguimiento para un cliente, ya sea desde el flujo de atencion o el panel de administracion. |
Actualizacion |
| Se dispara cuando se modifica una ficha. Solo se notifica si cambia el campo monitoreado: |
Eliminacion |
| Se dispara cuando se elimina una ficha. |
Ejemplo de payload: Creacion de reserva
{ "trigger": "create", "resource_type": "Booking", "created_at": "25/02/2026 14:30 UTC", "user": "sofia@misalon.com", "request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "resource": { "id": 174800001, "service_provider_id": 660296, "service_id": 562733, "location_id": 54724, "price": 30000.0, "status_id": 1, "notes": "", "company_comment": "", "service": "Corte cabello", "service_provider": "Ana Muñoz", "location": "Las Condes", "status": "Reservado", "start": "2026-03-05T09:00:00.000Z", "end": "2026-03-05T10:00:00.000Z", "client": { "id": 39743958, "first_name": "Pedro", "last_name": "Gómez", "email": "pedro@ejemplo.com", "phone": "", "identification": "12345678-9" } }, "changes": {}, "links": { "confirm": "https://agendapro.com/bookings/confirm/abc123", "cancel": "https://agendapro.com/bookings/cancel/abc123", "edit": "https://agendapro.com/bookings/edit/abc123" } }Ejemplo de payload: Actualizacion de reserva
{ "trigger": "update", "resource_type": "Booking", "created_at": "25/02/2026 15:45 UTC", "user": "sofia@misalon.com", "request_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "resource": { "id": 174800001, "service_provider_id": 660296, "service_id": 562733, "location_id": 54724, "price": 30000.0, "status_id": 1, "notes": "", "company_comment": "", "service": "Corte cabello", "service_provider": "Ana Muñoz", "location": "Las Condes", "status": "Reservado", "start": "2026-03-06T10:00:00.000Z", "end": "2026-03-06T11:00:00.000Z", "client": { "id": 39743958, "first_name": "Pedro", "last_name": "Gómez", "email": "pedro@ejemplo.com", "phone": "", "identification": "12345678-9" } }, "changes": { "start_time": ["2026-03-05T09:00:00.000Z", "2026-03-06T10:00:00.000Z"], "end_time": ["2026-03-05T10:00:00.000Z", "2026-03-06T11:00:00.000Z"] }, "links": { "confirm": "https://agendapro.com/bookings/confirm/abc123", "cancel": "https://agendapro.com/bookings/cancel/abc123", "edit": "https://agendapro.com/bookings/edit/abc123" } }Ejemplo de payload: Creacion de cliente
{ "trigger": "create", "resource_type": "Client", "created_at": "25/02/2026 16:00 UTC", "user": null, "request_uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012", "resource": { "id": 46765492, "first_name": "Laura", "last_name": "Díaz", "email": "laura@ejemplo.com", "identification_number": "", "phone": "+56922334455", "second_phone": "", "age": null, "birth_day": null, "birth_month": null, "birth_year": null, "record_number": "", "address": "", "district": "", "city": "", "gender": 0 }, "changes": {} }Reintentos y desactivacion
AgendaPro implementa un mecanismo de reintentos para garantizar la entrega de los webhooks:
Reintentos automaticos: Si la URL de webhook no responde, responde con un codigo de error (distinto de 200), o el servidor no es alcanzable, AgendaPro reintentara el envio automaticamente.
Desactivacion automatica: Si los reintentos se agotan sin obtener una respuesta exitosa, el webhook se desactiva automaticamente (
active=false). Esto evita que el sistema siga intentando enviar a una URL que no esta disponible.Reactivacion manual: Un webhook desactivado se puede reactivar manualmente desde Configuraciones > API Publica en el panel de administracion de AgendaPro.
Registro de intentos: Cada intento de envio se registra en un log que incluye el request enviado y el response recibido. Este log es util para depurar problemas de conectividad o errores en el procesamiento del webhook.
Idempotencia
Cada webhook incluye un campo request_uuid con un identificador unico universal. Este UUID permite implementar logica de idempotencia en el servidor receptor:
Deteccion de duplicados: Si por alguna razon (reintentos, problemas de red, etc.) se recibe el mismo evento dos veces, se puede usar el
request_uuidpara detectar que ya fue procesado y evitar procesarlo nuevamente.Implementacion recomendada: Almacenar los
request_uuidprocesados en una tabla o cache. Antes de procesar un webhook entrante, verificar si el UUID ya existe. Si ya fue procesado, responder con HTTP 200 sin ejecutar la logica de negocio.
Ejemplo de validacion en pseudocodigo:
webhook = parse_json(request.body) uuid = webhook["request_uuid"] if already_processed(uuid): respond(200) # Ya procesado, ignorar return process_webhook(webhook) mark_as_processed(uuid) respond(200)
Ejemplo de servidor receptor
A continuacion se muestra un ejemplo basico de un servidor que recibe webhooks de AgendaPro, valida la autenticacion y procesa los eventos:
# Probar la recepcion de un webhook con curl (simulacion) curl -X POST "https://tu-servidor.com/webhooks/agendapro" \ -u "company_id:secret_key" \ -H "Content-Type: application/json" \ -d '{ "trigger": "create", "resource_type": "Booking", "created_at": "25/02/2026 14:30 UTC", "user": "sofia@misalon.com", "request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "resource": { "id": 174800001, "service_provider_id": 660296, "service_id": 562733, "location_id": 54724, "price": 30000.0, "status_id": 1, "service": "Corte cabello", "service_provider": "Ana Muñoz", "location": "Las Condes", "status": "Reservado", "start": "2026-03-05T09:00:00.000Z", "end": "2026-03-05T10:00:00.000Z", "client": { "id": 39743958, "first_name": "Pedro", "last_name": "Gómez", "email": "pedro@ejemplo.com" } }, "changes": {}, "links": { "confirm": "https://agendapro.com/bookings/confirm/abc123", "cancel": "https://agendapro.com/bookings/cancel/abc123", "edit": "https://agendapro.com/bookings/edit/abc123" } }'Resumen de campos monitoreados por recurso
La siguiente tabla resume que campos disparan un webhook de tipo "update" para cada tipo de recurso:
Recurso | Campos monitoreados |
Booking |
|
Client |
|
Payment |
|
Chart |
|
Solo los cambios en estos campos disparan el webhook de actualizacion. Modificaciones en otros campos del recurso no generan notificaciones.
