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

# Cancel Booking

> PATCH /partners/bookings/:id/cancel — Cancel a booking.

## Overview

Cancels an existing booking. You must first fetch valid reasons from `GET /partners/bookings/cancellation-reasons` and pass the selected `reasonId` in the request body.

The cancellation behavior depends on your partner account's `paymentResponsibility`:

* **`CLEANOS` responsibility:** The system cancels the booking **and issues a refund** if applicable.
* **`PARTNER` responsibility:** The system cancels the booking only — no refund is processed by CleanLife. Your system is responsible for any refund to your customer.

***

## Endpoint

```
PATCH /partners/bookings/:bookingId/cancel
```

## Authentication

Requires a valid API Key with the `partner_bookings_cancel` permission.

***

## Path Parameters

| Parameter   | Type | Required | Description                               |
| ----------- | ---- | -------- | ----------------------------------------- |
| `bookingId` | UUID | **Yes**  | The booking ID returned at creation time. |

***

## Request Body

```json theme={null}
{
  "reasonId": "aaaaaaaa-0000-0000-0000-000000000001",
  "notes": "Customer requested cancellation."
}
```

| Field      | Type   | Required | Description                                                                    |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `reasonId` | UUID   | **Yes**  | ID of a cancellation reason from `GET /partners/bookings/cancellation-reasons` |
| `notes`    | string | No       | Free-text notes about the cancellation                                         |

***

## Example Request

```bash theme={null}
curl -X PATCH "https://apiv3.thecleanlife.dev/v1/partners/bookings/11111111-0000-0000-0000-000000000001/cancel" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reasonId": "aaaaaaaa-0000-0000-0000-000000000001",
    "notes": "Customer requested reschedule to a later date."
  }'
```

***

## Success Response

**HTTP Status:** `200 OK`

```json theme={null}
{
  "success": true,
  "data": {
    "bookingId": "11111111-0000-0000-0000-000000000001",
    "externalReference": "ORDER-20260615-001",
    "appointmentId": "22222222-0000-0000-0000-000000000002",
    "status": "canceled",
    "paymentStatus": "CANCELLED",
    "trackingReference": "SA-0042",
    "date": "2026-06-20T00:00:00.000Z",
    "timeslot": {
      "startAt": "09:00",
      "endAt": "12:00",
      "endsAtNextDay": false
    },
    "appointment": {
      "id": "22222222-0000-0000-0000-000000000002",
      "name": "SA-0042",
      "status": "Cancelled",
      "scheduledStartDateTime": "2026-06-20T09:00:00+03:00",
      "scheduledEndDateTime": "2026-06-20T12:00:00+03:00"
    }
  }
}
```

***

## Error Responses

| HTTP Status | Code                        | Description                                                   |
| ----------- | --------------------------- | ------------------------------------------------------------- |
| `400`       | `VALIDATION_ERROR`          | Missing or invalid `reasonId`, or invalid path/body parameter |
| `401`       | `UNAUTHORIZED`              | Missing or invalid API key                                    |
| `403`       | `FORBIDDEN`                 | Missing `partner_bookings_cancel` permission                  |
| `404`       | `RESOURCE_NOT_FOUND`        | Booking not found or does not belong to your partner account  |
| `422`       | `BOOKING_ALREADY_CANCELLED` | Booking is already in `canceled` status                       |

***

## Business Rules

1. **Cancellation reason is required.** Call `GET /partners/bookings/cancellation-reasons` first, then pass the selected `reasonId` when cancelling.

2. **Cannot cancel an already-cancelled booking.** If the booking is already in `canceled` status, the API returns `422 BOOKING_ALREADY_CANCELLED`. You can safely check for this error and treat it as a successful no-op.

3. **Refund behavior:**
   * `CLEANOS` responsibility: The service appointment is cancelled with action `CANCEL_AND_REFUND`. The CleanLife system will initiate a refund if applicable.
   * `PARTNER` responsibility: The service appointment is cancelled with action `CANCEL_ONLY`. No refund is initiated by CleanLife.

***

## Notes

* There is no restriction on which booking statuses can be cancelled via this endpoint (other than already-cancelled bookings). You can cancel a booking in `waiting payment`, `in progress`, or `success` status.
* If you need to cancel and then rebook for a different date, cancel the existing booking and create a new one.

***

## Related Endpoints

* `GET /partners/bookings/cancellation-reasons` — List valid cancellation reasons
* `GET /partners/bookings/:bookingId/status` — Verify booking status before cancelling
* `POST /partners/bookings` — Create a replacement booking
