---
title: "Update an Appointment"
method: PUT
path: "/shop/appointments/{appointmentId}"
tags: ["Appointments"]
---

# Update an Appointment

`PUT /shop/appointments/{appointmentId}`

Updates an `Appointment` in place. Common uses are reassigning the
practitioner, moving the appointment to a different `Room`,
rescheduling the `start_time`, or progressing the underlying
`Order` through stages (e.g. marking the customer as `arrived`,
`in_treatment`, or `checked_out`).

The update is routed through the basket / availability layer, so
the request is validated against the same rules a fresh booking
would face — overlapping practitioner bookings, room capacity,
site opening hours, and equipment availability are all enforced.
Users with the `reservations.override-rules` permission can bypass
these checks server-side; everyone else will receive a `400 Bad
Request` with the specific availability conflict.

The `move` object is a convenience for calendar drag-and-drop:
pass `move.resource_type` of `practitioner` or `room` plus the
`from_id` and `to_id` to swap the assigned resource without
spelling out the full `practitioner_ids` list. When only `stage`
is supplied the appointment slot is left untouched and the change
is applied to the parent order, saving the availability round-trip
entirely.

## Request body

- UpdateAppointment — Body for `updateAppointment`. Every field is optional; pass only the fields you want to change. Time-based fields are validated against the same availability rules as the booking flow.
  - `practitioner_ids` string[], nullable — Replace the set of practitioners assigned to this appointment. Pass an empty array to clear all assignments. Each ID must belong to a practitioner who can perform this `AppointmentType` at this site.
  - `room_id` string, object-id, nullable — Replace the room assigned to this appointment. The room must be one of the rooms permitted by the `AppointmentType` and available for the appointment's time slot.
  - `start_time` string, date-time — Reschedule the appointment to start at this date and time. The end time is recalculated from the appointment's `duration` and `end_buffer`. Must be an RFC 3339 timestamp with offset.
  - `time` string, date-time — **Deprecated**. Legacy alias for `start_time`. Will be removed once all calendar drag-and-drop clients have migrated.
  - `move` object — Convenience block for calendar drag-and-drop. Specifies which practitioner or room is being swapped without restating the whole list. When `resource_type` is `practitioner`, `practitioner_ids` is updated automatically; when `room`, the `room_id` is updated.
    - `from_id` string, nullable — ID of the resource being moved off the appointment.
    - `to_id` string, required — ID of the resource being moved onto the appointment.
    - `resource_type` 'practitioner' | 'room', required — Which resource is being moved.
  - `stage` 'arrived' | 'in_treatment' | 'checked_out' | 'not_arrived', nullable — Move the underlying order through its check-in flow. When `stage` is the only field provided the availability layer is skipped entirely. Pass `null` to clear the stage back to the default.

## Response `200`

The `Appointment` was successfully updated.

- object
  - `data` SchemasAppointment, required
    - `id` string, object-id, required — The ID of the appointment.
    - `appointment_type_id` string, object-id, required — The ID of the appointment type.
    - `appointment_type_name` string, required — The name of the appointment type.
    - `currency` string — The ISO-4217 currency code.
    - `customer_id` string, object-id, required — The ID of the customer this appointment is for.
    - `duration` integer, required — The duration of the appointment in minutes.
    - `email` string, required — The email address of the customer.
    - `end_buffer` integer, required — The number of minutes blocked out at the end of the appointment for cleaning or changeover.
    - `end_time` string, date-time, required — The end time this appointment is for.
    - `first_name` string, required — The first name of the customer.
    - `full_name` string — The full name of the customer.
    - `guests` Guest[], required
      - `id` string, object-id, required — Stable identifier for the guest slot on an order. Used to attach intake-form answers, check the guest in or out, and link the slot to a `Customer` once one is resolved.
      - `checked_in_at` string, date-time, nullable, required — ISO-8601 timestamp at which the guest checked in for their visit. `null` until check-in happens.
      - `checked_out_at` string, date-time, nullable, required — ISO-8601 timestamp at which the guest checked out / finished their visit. `null` while the visit is still in progress.
      - `customer_id` string, uuid, nullable, required — The `Customer` the guest slot has been linked to, if any. `null` for walk-ins or anonymous guests that haven't been matched to a customer record yet.
      - `email` string, email, nullable — Email address captured for this guest, used to send the pre-visit intake form and post-visit follow-ups. `null` when no email has been supplied for the slot.
      - `first_name` string, required — The first name of the guest.
      - `intake_form_submission_id` string, object-id — Identifier of the most recent intake-form submission for this guest, if one exists. Use this to fetch the submitted answers from the guest-intake API.
      - `intake_form_complete` boolean, required — Whether the intake form for the guest is complete.
      - `is_lead_booker` boolean, required — Whether the guest is the lead booker.
      - `last_name` string, required — The last name of the guest.
      - `name` string, required — Full display name for the guest — typically `first_name` plus `last_name`, but kept as a separate field so the platform can render it consistently across receipts, intake forms and check-in screens.
    - `has_notes` boolean, required — Whether the appointment belongs to an order that has notes.
    - `has_outstanding_balance` boolean, required — Whether the appointment belongs to an order that has an outstanding balance.
    - `has_special_requests` boolean, required — Whether the appointment belongs to an order that has special requests.
    - `is_group_booking` boolean, required — Whether the appointment belongs to an order that has multiple guests.
    - `is_hotel_room_booking` boolean — Whether the appointment belongs to an order that is associated with a hotel room.
    - `is_locked` boolean — Whether the appointment is locked and should not be moved.
    - `is_part_of_package` boolean, required — Whether the appointment was sold as part of a package
    - `last_name` string, required — The last name of the customer.
    - `net_total` integer, required — The net total of the appointment.
    - `order_id` string, object-id, required — The ID of the order associated with this appointment.
    - `order_is_locked` boolean, required — Whether the order is locked
    - `order_item_id` string, object-id, required — The ID of the order item associated with this appointment.
    - `order_labels` SchemasLabel[], required
      - `id` string, object-id, required — The ID of the label.
      - `color` string, required — The color of the label.
      - `name` string, required — The name of the label.
      - `order_id` string, object-id, required
    - `order_locked_at` string, date-time — The date the order was locked at
    - `order_ref` string, required — The order reference associated with this appointment.
    - `organisation_id` string, uuid, required — The ID of the organisation the appointment belongs to.
    - `package_product_code` string — The product code for the package.
    - `phone` string, required — The customer's phone number.
    - `practitioner_ids` string[], required — The IDs of the practitioners this appointment assigned to.
    - `practitioners` PractitionerSummary[], required
      - `id` string, object-id, required — The ID of the practitioner.
      - `name` string, required — The full name of the practitioner.
    - `product_code` string, nullable, required — A custom product code for the product.
    - `room` RoomSummary, required — The summary of a `Room` object
      - `id` string, object-id, required — The ID of the room.
      - `capacity` integer, required
      - `name` string, required — The name of the room.
    - `room_id` string, object-id, required — The ID of the room this appointment assigned to.
    - `site_id` string, uuid, required — The ID of the site the appointment belongs to.
    - `stage` 'arrived' | 'checked_out' | 'in_treatment' | 'not_arrived', required — The current stage of the order the appointment belongs to.
    - `start_time` string, date-time, required — The start time this appointment is for.
    - `status` 'confirmed' | 'in_progress' | 'new', required — The status of the appointment.
    - `submitted_at` string, date-time, required — The date and time the appointment was submitted.
    - `total_cost` integer, required — The total cost of the appointment.
    - `created_at` string, date-time, required — When then resource was created.
    - `updated_at` string, date-time, required — When then resource was last updated.

## Other responses

- `400` — The request failed.
- `401` — The user is unauthenticated
- `403` — The authenticated user does not have permission.
- `404` — The resource couldn't be found
- `422` — The request didn't pass validation

---

[API](https://skmtc.dev/try/apis/trybe-api.md) · [All operations](https://skmtc.dev/try/apis/trybe-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/try/trybe-api/revisions/f37f92702da5/schema)
