---
uuid: 19419fe6-e785-47bc-a3c4-0c8aabab1f93
date_created: 2026-02-27T06:19:34.456Z
date_updated: 2026-04-03T08:26:30.242Z
seo_url: book-a-spa
category: Booking upsell
tags: 
  - Services
  - Booking
routes: 
  - GET /v0/products/{product_id}/spas
  - GET /v0/products/{product_id}/spas/cares/{care_code}
  - GET /v0/customers/{customer_id}/bookings/{booking_id}/spas
  - POST /v0/customers/{customer_id}/bookings/{booking_id}/spas
  - DELETE /v0/customers/{customer_id}/bookings/{booking_id}/spas/{appointment_id}
---

# Book a spa

This scenario documents how a customer can browse spa information, inspect care availability, review existing appointments, book a spa slot, and cancel it when needed from a booking context.

## Flow

```mermaid
flowchart LR
    step0["Retrieve spa information"]
    step1["Check treatment availabilities"]
    step2["Retrieve existing spa appointments"]
    step3["Book the spa appointment"]
    step4["Cancel a spa appointment"]
    step0 --> step1
    step1 --> step2
    step2 --> step3
    step3 --> step4
    classDef optional fill:transparent,stroke:#ffffff,color:#ffffff,stroke-width:1px,stroke-dasharray: 6\,4
    class step2 optional
    class step4 optional
```

## Overview

The route sequence combines product-level spa discovery with customer booking actions. It helps build a complete spa booking journey from care selection to appointment cancellation.

## Prerequisites

* `product_id` is needed to list spas and cares.
* `customer_id` and `booking_id` are required for customer booking actions.
* Customer-scoped routes require `authorization`, and all documented calls require `accept-language` and `x-api-key`.

## 1 - Retrieve spa information

Use `GET /v0/products/{product_id}/spas` to retrieve the spa metadata exposed for a product, including the spa identity, contact details, cancellation limit and the list of available cares.

#### Prerequisites

* Header `accept-language`
* Header `x-api-key`
* Path `product_id`

#### Calling CURL

```bash
curl -X GET "https://api.clubmed.com/v0/products/MPAC/spas" \
  -H "accept-language: en-US" \
  -H "x-api-key: <your-api-key>"
```

#### Example answer

```json
{
  "id": 432423,
  "label": "Aginum Thermae",
  "currency": "EUR",
  "location": "Location",
  "are_children_accepted": true,
  "cancellation_hours_limit": 24,
  "cares": [
    {
      "id": 432423,
      "label": "Anti-Aging",
      "sub_category": "Anti-aging",
      "duration": 60,
      "total_duration": 75,
      "price": {
        "value": 44,
        "currency": "EUR"
      }
    }
  ]
}
```

> **info:** Reuse the returned care identifiers in the availability step. The spa-level metadata is also useful to display contact information and cancellation rules before booking.

***

**Response codes**

* `200`: spa information returned successfully.
* `400`: bad request or validation error.
* `404`: unknown product or no spa exposed for the targeted product.

**Related route**: [GET https://api.clubmed.com//v0/products/{product\_id}/spas](https://api.clubmed.com/doc?search=GET%20%2Fv0%2Fproducts%2F%7Bproduct_id%7D%2Fspas)

## 2 - Check treatment availabilities

Use `GET /v0/products/{product_id}/spas/cares/{care_code}` to retrieve the available time slots for one care in the selected product.

#### Prerequisites

* Header `accept-language`
* Header `x-api-key`
* Path `product_id`
* Path `care_code`
* Optional query `date_format`
* Optional query `start_date`
* Optional query `end_date`

#### Calling CURL

```bash
curl -X GET "https://api.clubmed.com/v0/products/MPAC/spas/cares/3922446?start_date=2022-04-15T10:23:00.234Z&end_date=2022-04-16T10:23:00.234Z&date_format=ISO" \
  -H "accept-language: en-US" \
  -H "x-api-key: <your-api-key>"
```

#### Example answer

```json
[
  {
    "start_date_time": "2022-04-15T10:23:00.234Z",
    "end_date_time": "2022-04-15T10:23:00.234Z",
    "employees": [
      {
        "id": 432423,
        "name": "Thomas",
        "gender": "MALE"
      }
    ]
  }
]
```

> **info:** Use this response to let the customer choose a slot and, when relevant, a practitioner before creating the appointment.

***

**Response codes**

* `200`: availabilities returned successfully.
* `400`: invalid date range, invalid care code, bad request or validation error.
* `404`: unknown product or inaccessible care for the targeted product.

**Related route**: [GET https://api.clubmed.com//v0/products/{product\_id}/spas/cares/{care\_code}](https://api.clubmed.com/doc?search=GET%20%2Fv0%2Fproducts%2F%7Bproduct_id%7D%2Fspas%2Fcares%2F%7Bcare_code%7D)

## 3 - Retrieve existing spa appointments

Use `GET /v0/customers/{customer_id}/bookings/{booking_id}/spas` to list the spa appointments already linked to a booking before adding or cancelling one.

#### Prerequisites

* Header `authorization`
* Header `accept-language`
* Header `x-api-key`
* Path `customer_id`
* Path `booking_id`
* Required query `product_id`
* Optional query `date_format`

#### Calling CURL

```bash
curl -X GET "https://api.clubmed.com/v0/customers/123456789/bookings/0123456789/spas?product_id=MPAC&date_format=ISO" \
  -H "authorization: Bearer <token>" \
  -H "accept-language: en-US" \
  -H "x-api-key: <your-api-key>"
```

#### Example answer

```json
[
  {
    "booking_number": "100565795179",
    "appointment_id": 565795179,
    "order_id": 710834209,
    "status": "Confirmed",
    "start_date_time": "2022-04-15T10:23:00.234Z",
    "end_date_time": "2022-04-15T10:23:00.234Z",
    "price": {
      "value": 105,
      "currency": "EUR"
    },
    "spa_care": {
      "id": 432423,
      "label": "Anti-Aging"
    }
  }
]
```

> **info:** The response gives you the appointment identifiers required to cancel an existing booking and helps avoid duplicate reservations on the same booking.

***

**Response codes**

* `200`: existing spa appointments returned successfully.
* `400`: missing `product_id`, bad request or validation error.
* `401`: unauthorized.
* `404`: booking not found for the targeted customer.

**Related route**: [GET https://api.clubmed.com//v0/customers/{customer\_id}/bookings/{booking\_id}/spas](https://api.clubmed.com/doc?search=GET%20%2Fv0%2Fcustomers%2F%7Bcustomer_id%7D%2Fbookings%2F%7Bbooking_id%7D%2Fspas)

## 4 - Book the spa appointment

Use `POST /v0/customers/{customer_id}/bookings/{booking_id}/spas` to create a spa appointment for a selected booking and customer.

#### Prerequisites

* Header `authorization`
* Header `accept-language`
* Header `x-api-key`
* Path `customer_id`
* Path `booking_id`
* The route expects a request body. The exact full schema is not visible in the available contract excerpt, but it must carry the selected slot and booking context.

#### Calling CURL

```bash
curl -X POST "https://api.clubmed.com/v0/customers/123456789/bookings/0123456789/spas" \
  -H "authorization: Bearer <token>" \
  -H "accept-language: en-US" \
  -H "x-api-key: <your-api-key>" \
  -H "Content-Type: application/json"
```

#### Example answer

```json
{
  "booking_number": "100565795179",
  "appointment_id": 565795179,
  "order_id": 710834209,
  "status": "Confirmed",
  "price": {
    "value": 105,
    "currency": "EUR"
  },
  "upsells": [
    {
      "id": 432423,
      "label": "Anti-Aging",
      "type": "AFTER"
    }
  ]
}
```

> **info:** Save the returned `appointment_id` immediately if your channel supports later cancellation or booking recap pages.

***

**Response codes**

* `200`: appointment created successfully.
* `400`: bad request, validation error or invalid JSON payload.
* `401`: unauthorized.
* `404`: booking not found for the targeted customer.
* `409`: a booking request already exists for the same criteria.

**Related route**: [POST https://api.clubmed.com//v0/customers/{customer\_id}/bookings/{booking\_id}/spas](https://api.clubmed.com/doc?search=POST%20%2Fv0%2Fcustomers%2F%7Bcustomer_id%7D%2Fbookings%2F%7Bbooking_id%7D%2Fspas)

## 5 - Cancel a spa appointment

Use `DELETE /v0/customers/{customer_id}/bookings/{booking_id}/spas/{appointment_id}` to cancel a previously booked spa appointment.

#### Prerequisites

* Header `authorization`
* Header `accept-language`
* Header `x-api-key`
* Path `customer_id`
* Path `booking_id`
* Path `appointment_id`

#### Calling CURL

```bash
curl -X DELETE "https://api.clubmed.com/v0/customers/123456789/bookings/0123456789/spas/565795179" \
  -H "authorization: Bearer <token>" \
  -H "accept-language: en-US" \
  -H "x-api-key: <your-api-key>"
```

#### Example answer

```text
HTTP/1.1 204 No Content
```

> **info:** No response body is returned on success. Keep the original appointment identifier from the retrieval or booking step to target the correct appointment.

***

**Response codes**

* `204`: appointment cancelled successfully.
* `400`: bad request or validation error.
* `401`: unauthorized.
* `404`: booking or appointment not found for the targeted customer.

**Related route**: [DELETE https://api.clubmed.com//v0/customers/{customer\_id}/bookings/{booking\_id}/spas/{appointment\_id}](https://api.clubmed.com/doc?search=DELETE%20%2Fv0%2Fcustomers%2F%7Bcustomer_id%7D%2Fbookings%2F%7Bbooking_id%7D%2Fspas%2F%7Bappointment_id%7D)
