Citas
Base path: /api/bookings
GET /bookings
Obtener todas las citas. Los empleados ven solo las suyas cuando staff_personal_agenda_enabled está activo. Las canceladas se excluyen.
Auth: Autenticado
Query parameters: page, limit
GET /bookings/:id
Obtener una cita específica.
Auth: Autenticado
Errores: 404 — Cita no encontrada
POST /bookings
Crear nueva cita.
Auth: Autenticado
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
client_id | integer | Sí | ID del cliente |
staff_id | integer | Sí | ID del empleado |
service_id | integer | Sí | ID del servicio |
start_at | datetime | Sí | Hora de inicio |
end_at | datetime | Sí | Hora de fin |
notes | string | No | Notas (visibles al cliente) |
internal_notes | string | No | Notas internas |
provisional | boolean | No | Si true: estado=provisional, se envía email al cliente |
waitlist_id | integer | No | Enlace a entrada de lista de espera |
base_url | string | No | URL base para enlaces de confirmación/rechazo |
nota
Las citas en días festivos se rechazan con error 400.
Response (200): Objeto Booking
PUT /bookings/:id
Actualizar una cita. Los cambios de hora encolan un email con 30 minutos de retraso. Al completar se inician secuencias de seguimiento.
DELETE /bookings/:id
Cancelar cita (pone estado en cancelled).
Estados de cita
| Estado | Descripción |
|---|---|
scheduled | Cita confirmada |
provisional | Esperando confirmación del cliente |
completed | Cita completada |
cancelled | Cita cancelada |
no-show | Cliente no se presentó |
Objeto Booking
{
"id": 1,
"client_id": 5,
"staff_id": 2,
"service_id": 3,
"start_at": "2026-03-24 10:00:00",
"end_at": "2026-03-24 10:30:00",
"status": "scheduled",
"notes": "",
"internal_notes": "",
"provisional_token": null,
"feedback_token": null,
"waitlist_id": null,
"client_name": "María García"
}