Wise Health Scheduling API

Versión 2.14.0

API REST para gestión de turnos médicos, diseñada para integración con canales conversacionales como WhatsApp. Más de 60 endpoints para manejar pacientes, turnos, disponibilidad, lista de espera, webhooks y catálogo médico.

Autenticación JWT

La API utiliza autenticación en dos pasos:

  1. Obtener un JWT token enviando tu API Key al endpoint POST /api/authenticate con el header X-API-Key: nxk_.... El token es válido por 3600 segundos (1 hora).
  2. Usar el token en todas las demás llamadas con el header Authorization: Bearer <token>.

Las API Keys directas ya no se aceptan en endpoints (excepto /api/authenticate).

Ciclo de vida de un turno

Los turnos pasan por los estados: hold → booked → confirmed → completed / cancelled / no_show / rescheduled.

  • hold: Reserva temporaria. Expira automáticamente según holdTimeoutMinutes.
  • booked: Turno agendado, pendiente de confirmación.
  • confirmed: Turno confirmado por el paciente o la clínica.
  • completed: Turno completado (requiere que el horario ya haya pasado).
  • cancelled: Turno cancelado respetando las políticas de cancelación.
  • no_show: El paciente no se presentó (requiere que el horario ya haya pasado).
  • rescheduled: El turno original fue reagendado; se crea uno nuevo vinculado por rescheduledFromId.

Webhooks

El sistema emite notificaciones firmadas con HMAC-SHA256 para los siguientes eventos:

  • appointment.created, appointment.confirmed, appointment.cancelled, appointment.rescheduled
  • appointment.completed, appointment.no_show, appointment.hold_expired, appointment.hold_released, appointment.reminder_due
  • patient.pin_generated, patient.pin_regenerated
  • waitlist.notified, waitlist.auto_assigned, waitlist.advance_offered, waitlist.priority_changed

Configurar webhookUrl y webhookSecret (mínimo 16 caracteres) vía PATCH /api/settings.

Convenciones

  • Todos los timestamps se envían y reciben en UTC ISO 8601 (ej: 2026-01-28T13:00:00Z).
  • Los endpoints de disponibilidad incluyen campos adicionales en timezone local de la clínica (date, startTime, endTime).
  • Usar slotId de GET /api/availability para booking evita errores de timezone y race conditions.
  • Los endpoints de escritura aceptan parámetros tanto en el cuerpo JSON como por query string.
  • Paginación consistente: { data, total, limit, offset } en listas.

Estado del sistema

MétodoRutaDescripción
GET /api/health Verifica el estado del servidor, versión y zona horaria. Público, sin autenticación.

Autenticación

MétodoRutaDescripción
POST /api/authenticate Genera un JWT válido por 1 hora a partir de una API Key (header X-API-Key). Este token se usa en todos los demás endpoints.

Configuración de la clínica

MétodoRutaDescripción
GET /api/settings Devuelve la configuración de la clínica: holdTimeoutMinutes, reminderHoursBefore, webhookEnabled, políticas de cancelación, etc.
PATCH /api/settings Actualiza la configuración de la clínica. Acepta holdTimeoutMinutes, reminderHoursBefore, webhookUrl, webhookSecret, webhookEnabled, cancellationPolicyHours, maxCancellationsPerMonth.

Disponibilidad

MétodoRutaDescripción
GET /api/availability Busca slots disponibles para un rango de fechas. Acepta filtros por practitionerId, locationId, specialtyId, serviceId. Devuelve slotId, fecha, hora local y UTC.

Turnos

MétodoRutaDescripción
GET /api/appointments Lista de turnos del tenant con paginación, filtros por status, practitionerId, locationId, specialtyId, dateFrom, dateTo.
POST /api/appointments Crea un turno (hold o booked) usando slotId o date/startTime/endTime. Soporta idempotency key.
GET /api/appointments/upcoming Lista de turnos próximos confirmados para envío de recordatorios, con cursor de paginación.
POST /api/appointments/recurring Crea una serie de turnos recurrentes con frecuencia semanal o quincenal (2–52 turnos).
GET /api/appointments/:id Detalle de un turno por su UUID.
POST /api/appointments/:id/confirm Confirma un turno en estado hold o booked. Dispara webhook appointment.confirmed.
POST /api/appointments/:id/cancel Cancela un turno respetando las políticas de cancelación del tenant. Dispara webhook appointment.cancelled.
POST /api/appointments/:id/reschedule Reagenda un turno: marca el original como rescheduled y crea uno nuevo vinculado por rescheduledFromId. Dispara webhook appointment.rescheduled.
POST /api/appointments/:id/complete Marca un turno como completado (solo si el horario ya pasó). Dispara webhook appointment.completed.
POST /api/appointments/:id/no-show Registra ausencia del paciente (solo si el horario ya pasó). Dispara webhook appointment.no_show.
POST /api/appointments/:id/release Libera manualmente un hold, devolviéndolo a disponible. Dispara webhook appointment.hold_released.

Pacientes

MétodoRutaDescripción
GET /api/patients Lista de pacientes con paginación y filtros por nombre, teléfono, cobertura, etiquetas, especialidad y actividad de turnos.
POST /api/patients Crea un nuevo paciente. Acepta nombre, teléfono, email, notas, cobertura e identificador (DNI, CUIT, etc.).
GET /api/patients/phone/:phone Busca un paciente por número de teléfono.
GET /api/patients/phone/:phone/appointments Historial de turnos del paciente encontrado por teléfono.
GET /api/patients/lookup Busca un paciente por valor de identificador (DNI, CUIT, CURP, etc.).
GET /api/patients/:id Detalle de un paciente por UUID.
PATCH /api/patients/:id Actualiza datos del paciente: nombre, teléfono, email, notas, coverageId.
GET /api/patients/:id/profile Perfil completo del paciente con historial de turnos paginado, enriquecido con profesional, sede, servicio y especialidad.
GET /api/patients/:id/specialists Resumen de profesionales que atendieron al paciente, con conteo de visitas y última fecha.
POST /api/patients/:id/identifiers Agrega un identificador (DNI, CUIT, etc.) al paciente.
DELETE /api/patients/:id/identifiers/:identifierId Elimina un identificador del paciente.
POST /api/patients/:id/generate-pin Genera un PIN de 4 dígitos para el paciente y despacha webhook patient.pin_generated.
POST /api/patients/:id/regenerate-pin Regenera el PIN existente del paciente. Dispara webhook patient.pin_regenerated.
POST /api/patients/verify-pin Verifica el PIN de un paciente. Protección anti-brute-force: bloqueo de 30 min tras 5 intentos fallidos.
POST /api/patients/identify Identifica un paciente por teléfono o documento. Indica si tiene PIN configurado.

Etiquetas de pacientes

MétodoRutaDescripción
GET /api/patient-tags Lista todas las etiquetas del tenant.
POST /api/patient-tags Crea una nueva etiqueta de paciente.
DELETE /api/patient-tags/:id Elimina una etiqueta del tenant.
POST /api/patients/:id/tags Asigna una etiqueta a un paciente.
DELETE /api/patients/:id/tags/:tagId Quita una etiqueta de un paciente.

Lista de espera

MétodoRutaDescripción
GET /api/waitlist Lista las entradas de la lista de espera. Filtros: specialtyId, practitionerId, status.
POST /api/waitlist Agrega un paciente a la lista de espera para una especialidad. Previene duplicados.
DELETE /api/waitlist/:id Elimina una entrada de la lista de espera (hard delete, responde 204).
POST /api/waitlist/:id/notify Notifica al paciente en lista de espera. Cambia estado a notified. Dispara webhook waitlist.notified.
PATCH /api/waitlist/:id/priority Actualiza la prioridad (1–5) de una entrada. Dispara webhook waitlist.priority_changed.

Action Tokens (WhatsApp)

MétodoRutaDescripción
POST /api/action-tokens Crea un token de un solo uso para acciones desde WhatsApp (confirm, cancel, reschedule). El token se muestra solo una vez.
POST /api/actions/:token Ejecuta la acción asociada al token (confirm / cancel / reschedule). Uso único garantizado. Aplica políticas de cancelación del tenant.

Webhooks y logs

MétodoRutaDescripción
GET /api/webhook-logs Lista el historial de envíos de webhooks con estado (sent, failed, pending) y paginación.
POST /api/webhook-logs/:id/retry Reencola un webhook fallido para reintento inmediato.

Logs de API

MétodoRutaDescripción
GET /api/api-logs Historial de llamadas JWT a la API. Filtros por método, path, status, apiKeyId y rango de fechas. Retención de 30 días.

Catálogo: Sedes

MétodoRutaDescripción
GET /api/locations Lista las sedes de la clínica.
POST /api/locations Crea una nueva sede.
PATCH /api/locations/:id Actualiza una sede.
DELETE /api/locations/:id Elimina una sede.

Catálogo: Especialidades

MétodoRutaDescripción
GET /api/specialties Lista las especialidades médicas de la clínica.
POST /api/specialties Crea una nueva especialidad.
PATCH /api/specialties/:id Actualiza una especialidad.
DELETE /api/specialties/:id Elimina una especialidad.

Catálogo: Profesionales

MétodoRutaDescripción
GET /api/practitioners Lista los profesionales de la clínica. Filtros: search, specialtyId, locationId.
POST /api/practitioners Crea un nuevo profesional.
PATCH /api/practitioners/:id Actualiza un profesional.
DELETE /api/practitioners/:id Desactiva un profesional (soft delete; preserva historial de turnos).
GET /api/practitioners/:id/specialties Lista las especialidades del profesional.
POST /api/practitioners/:id/specialties Asigna una especialidad al profesional.
DELETE /api/practitioners/:id/specialties/:specialtyId Quita una especialidad del profesional.
GET /api/practitioners/:id/locations Lista las sedes donde atiende el profesional (derivado de sus horarios).

Catálogo: Servicios

MétodoRutaDescripción
GET /api/services Lista los servicios médicos ofrecidos.
POST /api/services Crea un nuevo servicio.
PATCH /api/services/:id Actualiza un servicio.
DELETE /api/services/:id Elimina un servicio.
GET /api/services/:id/coverages Lista las coberturas y precios asociados a un servicio (pricing matrix).
POST /api/services/:id/coverages Agrega una cobertura al pricing matrix del servicio.
PATCH /api/services/:id/coverages/:coverageId Actualiza el precio de una cobertura en el servicio.
DELETE /api/services/:id/coverages/:coverageId Elimina una cobertura del pricing matrix del servicio.

Catálogo: Coberturas

MétodoRutaDescripción
GET /api/coverages Lista las coberturas médicas (obra social, prepaga, particular).
POST /api/coverages Crea una nueva cobertura.
PATCH /api/coverages/:id Actualiza una cobertura.
DELETE /api/coverages/:id Elimina una cobertura.

Horarios y excepciones

MétodoRutaDescripción
GET /api/schedules Lista los horarios de atención semanales por profesional y sede.
POST /api/schedules Crea un horario de atención (ej: Lunes 9:00–17:00 para un profesional en una sede).
PATCH /api/schedules/:id Actualiza un horario de atención.
DELETE /api/schedules/:id Elimina un horario de atención.
GET /api/blackouts Lista las excepciones de horario (vacaciones, feriados, ausencias).
POST /api/blackouts Crea una excepción de horario. Soporta recurrencia: WEEKLY, MONTHLY, YEARLY con fecha de fin opcional.
PATCH /api/blackouts/:id Actualiza una excepción de horario.
DELETE /api/blackouts/:id Elimina una excepción de horario.

Widget (Power Inbox)

MétodoRutaDescripción
GET /api/widget/:tenantSlug/patient Busca un paciente por teléfono o PID. Autenticación por widgetToken (header X-Widget-Token).
POST /api/widget/:tenantSlug/patients Crea un nuevo paciente desde el widget.
GET /api/widget/:tenantSlug/availability Consulta disponibilidad de turnos desde el widget.
POST /api/widget/:tenantSlug/appointments Crea un turno desde el widget (hold → booked).
POST /api/widget/:tenantSlug/appointments/:id/confirm Confirma un turno desde el widget.
POST /api/widget/:tenantSlug/appointments/:id/cancel Cancela un turno desde el widget.
POST /api/widget/:tenantSlug/appointments/:id/reschedule Reagenda un turno desde el widget.
GET /api/widget/:tenantSlug/catalog Catálogo completo del tenant: especialidades, sedes, profesionales, servicios y coberturas.