> ## Documentation Index
> Fetch the complete documentation index at: https://opencals.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer reschedules keep the booking length

> PUT /customer/appointments/:id/reschedule now rejects a new slot of a different length and always keeps the appointment's own product.

**October 19, 2026**

## Reschedules keep the booking length

A customer reschedule moves an appointment to a new time. It now also has to
keep the length of the booking:

* The new slot must cover the same number of billed units as the current one.
  For a custom-duration product priced per hour, a 2-hour booking can move to
  any other free 2-hour slot, but not to 3 hours. A different length returns
  `400` ("The new time must be the same length as the current booking …").
* The appointment's product can't change. A `slot.productId` that isn't the
  appointment's own product is ignored, and the slot is checked against the
  appointment's product.

A different length changes the price, and only the merchant can settle the
difference. Merchants change the length, the product or the appointments of an
order from the dashboard, which re-prices the order.

Units are counted the same way as at booking, so a stay moved across a
daylight-saving change still counts as the same number of nights.

### What to change

Nothing, if your reschedule UI already keeps the booking length. The
open-source templates and the Opencals storefront already do. If you let
customers pick a new end time, fix the length to the current booking's and pass
it as `duration` when you load availability:

```ts theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
import { Products } from '@opencals/storefront-sdk';

const seconds = (new Date(appointment.to).getTime() - new Date(appointment.from).getTime()) / 1000;

const { data: slots } = await Products.getCurrentAvailabilities({
  path: { productId: appointment.productId },
  query: { date, duration: String(seconds), excludeAppointmentId: appointment.id },
});
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.