Wise Health Scheduling API

Versión 2.19.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.

Códigos legibles (displayCode)

Cada paciente, turno, profesional, sede y servicio tiene un código corto, correlativo y único por clínica, además de su UUID: pacientes P-0001, turnos T-00001, profesionales M-001, sedes S-01, servicios SV-001.

  • Es de solo lectura: lo asigna el sistema al crear el registro; no se puede enviar ni modificar.
  • Es correlativo por clínica y nunca se recicla, aunque se elimine el registro. El padding es un mínimo: después de T-99999 sigue T-100000.
  • Los UUIDs siguen siendo los identificadores para todas las llamadas a la API; el código es solo para mostrar y comunicar (ej: "te confirmamos tu turno T-0345").
  • Viene incluido en las respuestas (campo displayCode) y en los payloads de webhooks de turnos (data.appointment.displayCode, data.patient.displayCode).
  • Se puede buscar por código: GET /api/patients?search=P-0012 y GET /api/appointments?search=T-0345.

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

La configuración de webhooks (webhookUrl, webhookSecret de mínimo 16 caracteres y activación) la gestiona el soporte de la plataforma; podés verificar el estado con GET /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. La configuración es de solo lectura para integraciones: los cambios los gestiona el soporte de la plataforma.

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, y búsqueda por código legible (search=T-0345).
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, código legible (search=P-0012), 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/identifier/:value/appointments Turnos del paciente buscado por documento (DNI, RUT, cédula, CURP, etc.). También disponible vía ?identifierValue=. Mismo formato y filtros que la variante por teléfono.
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. Si necesitás reintentar un webhook fallido, contactá al soporte de la plataforma.

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. Para modificar una excepción, eliminala y creala de nuevo.
DELETE /api/blackouts/:id Elimina una excepción de horario.