Skip to main content
PATCH
/
appointments
/
:id
Update Appointment
curl --request PATCH \
  --url https://api.example.com/appointments/:id \
  --header 'Content-Type: application/json' \
  --data '
{
  "patientID": 123,
  "professionalID": 123,
  "date": "<string>",
  "time": "<string>",
  "description": "<string>",
  "state": "<string>"
}
'
{
  "appointment": {
    "id": 123,
    "patientID": 123,
    "professionalID": 123,
    "date": "<string>",
    "time": "<string>",
    "description": "<string>",
    "state": "<string>",
    "createdAt": "<string>",
    "updatedAt": "<string>"
  }
}

Overview

This endpoint updates an existing appointment in the system. It performs the same comprehensive validation as creating an appointment, but allows changing the state and excludes the current appointment from conflict checks.
This endpoint requires admin role. Regular users cannot update appointments.

Authentication

Requires a valid JWT token with admin privileges.
Authorization: Bearer <jwt_token>

Path Parameters

id
number
required
The unique identifier of the appointment to update. Must be a numeric value.Example: 123

Request Body

patientID
number
required
The ID of the patient for this appointment. Must correspond to an existing patient’s DNI in the system.Validation:
  • Patient with this DNI must exist
  • Patient must not have another appointment at the same date/time (excluding this appointment)
Example: 45
professionalID
number
required
The ID of the professional who will conduct the appointment. Must correspond to an existing professional’s DNI.Validation:
  • Professional with this DNI must exist
  • Professional must not have another appointment at the same date/time (excluding this appointment)
  • Professional must work on the selected day of the week
  • Time must be within professional’s work schedule
Example: 12
date
string
required
The date for the appointment in ISO 8601 format (YYYY-MM-DD).Validation:
  • Must be a valid date format
  • Patient must be available at this date/time
  • Professional must work on this day of the week
Example: "2026-03-15"
time
string
required
The time for the appointment in 24-hour format (HH:mm).Validation:
  • Must be within professional’s work schedule for that day
  • Must not conflict with existing appointments (excluding this appointment)
  • Format: HH:mm (e.g., “09:30”, “14:00”)
Example: "10:30"
description
string
required
The reason for the appointment or notes about what will be addressed.Example: "Control mensual de diabetes - Revisión de glucosa"
state
string
required
The current state of the appointment. Must be one of the valid states:
  • Pendiente - Scheduled and waiting
  • Atendido - Patient was seen and appointment completed
  • Cancelado - Appointment was cancelled
  • Ausente - Patient did not show up
Example: "Atendido"

Complex Validations

This endpoint runs several complex validation checks:

1. Patient Availability (checkPatientAvailability)

Verifies the patient doesn’t have another appointment at the same date/time. Excludes the current appointment from the check. Error message: "El paciente ya tiene un turno el {date} a las {time}"

2. Appointment Availability (checkAppointmentAvailability)

Ensures the professional doesn’t have another appointment at the same date/time. Excludes the current appointment from the check. Error message: "El profesional ya tiene un turno ocupado el {date} a las {time}"

3. Professional Schedule (checkProfessionalSchedule)

Validates the appointment time against the professional’s work schedule:
  • Checks if professional works on the selected day of the week
  • Verifies time falls within professional’s start/end time for that day
Error messages:
  • "El profesional no trabaja en la fecha seleccionada."
  • "El horario {time} está fuera de la jornada laboral ({startTime} a {endTime})"
  • "Formato de fecha u hora inválido"

Response

Returns the updated appointment object:
appointment
object

Examples

Update Appointment State to Completed

curl -X PATCH "https://api.clinicavitalis.com/appointments/123" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "patientID": 45,
    "professionalID": 12,
    "date": "2026-03-15",
    "time": "10:30",
    "description": "Control mensual de diabetes - Paciente atendido",
    "state": "Atendido"
  }'

Reschedule Appointment

curl -X PATCH "https://api.clinicavitalis.com/appointments/123" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "patientID": 45,
    "professionalID": 12,
    "date": "2026-03-18",
    "time": "14:00",
    "description": "Control mensual de diabetes - Reprogramado",
    "state": "Pendiente"
  }'

Cancel Appointment

curl -X PATCH "https://api.clinicavitalis.com/appointments/123" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "patientID": 45,
    "professionalID": 12,
    "date": "2026-03-15",
    "time": "10:30",
    "description": "Control mensual de diabetes - Cancelado por el paciente",
    "state": "Cancelado"
  }'

Success Response

Status Code: 200 OK
{
  "appointment": {
    "id": 123,
    "patientID": 45,
    "professionalID": 12,
    "date": "2026-03-15",
    "time": "10:30:00",
    "description": "Control mensual de diabetes - Paciente atendido",
    "state": "Atendido",
    "createdAt": "2026-03-11T15:30:00.000Z",
    "updatedAt": "2026-03-15T10:45:00.000Z"
  }
}

Error Responses

400 Bad Request - Invalid ID

Returned when the ID parameter is missing or not numeric:
{
  "msg": "Debe enviar un ID y debe ser numérico"
}

400 Bad Request - Validation Errors

Returned when validation fails. The response includes an array of all validation errors:
{
  "errors": [
    {
      "msg": "El estado es obligatorio",
      "param": "state",
      "location": "body"
    }
  ]
}

Common Validation Errors

Missing required fields:
{
  "errors": [
    { "msg": "El paciente es obligatorio", "param": "patientID" },
    { "msg": "El profesional es obligatorio", "param": "professionalID" },
    { "msg": "La fecha es obligatoria", "param": "date" },
    { "msg": "El horario es obligatorio", "param": "time" },
    { "msg": "La descripción es obligatoria", "param": "description" },
    { "msg": "El estado es obligatorio", "param": "state" }
  ]
}
Patient has conflict (different appointment):
{
  "errors": [
    {
      "msg": "El paciente ya tiene un turno el 2026-03-15 a las 10:30",
      "param": "date"
    }
  ]
}
Professional has conflict (different appointment):
{
  "errors": [
    {
      "msg": "El profesional ya tiene un turno ocupado el 2026-03-15 a las 10:30",
      "param": "_"
    }
  ]
}
Professional doesn’t work on that day:
{
  "errors": [
    {
      "msg": "El profesional no trabaja en la fecha seleccionada.",
      "param": "_"
    }
  ]
}
Time outside professional’s work hours:
{
  "errors": [
    {
      "msg": "El horario 18:00 está fuera de la jornada laboral (08:00 a 16:00)",
      "param": "_"
    }
  ]
}

404 Not Found

Returned when the appointment with the specified ID doesn’t exist:
{
  "msg": "El turno no está cargando en el sistema"
}

401 Unauthorized

Returned when the JWT token is missing or invalid:
{
  "msg": "Token inválido o no proporcionado"
}

403 Forbidden

Returned when the user doesn’t have admin privileges:
{
  "msg": "No tiene permisos de administrador"
}

500 Server Error

Returned when a server error occurs:
{
  "msg": "Error del servidor"
}

Appointment State Transitions

1

Pendiente (Pending)

Initial state when appointment is created. Can transition to:
  • Atendido - When patient shows up and is seen
  • Cancelado - When cancelled by patient or clinic
  • Ausente - Automatically set when date/time passes
2

Atendido (Completed)

Patient was seen successfully. This is a terminal state.
3

Cancelado (Cancelled)

Appointment was cancelled. Could potentially be rescheduled by creating a new appointment.
4

Ausente (No-show)

Patient didn’t show up. Could be rescheduled or marked as completed if they arrived late.

Key Differences from Create

FeatureCreateUpdate
State fieldNot required (defaults to “Pendiente”)Required
Conflict checkChecks all appointmentsExcludes current appointment
Status code201 Created200 OK
ID validationNot neededValidates ID exists and is numeric

Rescheduling Workflow

When rescheduling an appointment:
  1. Fetch current appointment using GET /appointments/:id
  2. Modify date/time to new values
  3. Keep state as “Pendiente” (unless changing for other reasons)
  4. Update description to note it was rescheduled
  5. Submit update with all required fields
  6. Validation runs:
    • Checks new time slot availability
    • Excludes current appointment from conflicts
    • Validates professional works at new time
  7. Appointment updated successfully

Best Practices

  • Always fetch the current appointment data before updating
  • Include all required fields in the update request, not just changed values
  • Update the description when changing state to document the reason
  • When rescheduling, verify the new time slot is available before submitting
  • Handle validation errors gracefully, especially time conflicts
  • Consider the appointment state workflow when updating
  • For cancellations, keep the original date/time but change state to “Cancelado”

Use Cases

  • Mark as completed: Update state to “Atendido” after patient is seen
  • Reschedule: Change date/time while keeping state as “Pendiente”
  • Cancel: Update state to “Cancelado” and add cancellation reason to description
  • Change professional: Assign a different professional while maintaining the time slot
  • Update notes: Modify description to add more details about the appointment
  • Correct errors: Fix mistakes in patient ID, professional ID, or other details

Build docs developers (and LLMs) love