---
title: "Create a custom availability rule for a practitioner"
method: POST
path: "/shop/practitioners/{practitionerId}/custom-availability"
tags: ["Practitioners"]
---

# Create a custom availability rule for a practitioner

`POST /shop/practitioners/{practitionerId}/custom-availability`

Creates a new `PractitionerCustomAvailability` rule. Use this
to open an extra working window (`is_available: true`) or to
block one off (`is_available: false`, e.g. leave or sickness).

The server validates that no confirmed appointments or sessions
fall inside `is_available: false` windows, and automatically
merges adjacent or overlapping rules with the same
`is_available` value. The response is the resulting rule, which
may have been merged with neighbours.

## Request body

- object
  - `date_time_from` string, date-time, required — Start of the window, as an ISO 8601 date-time. Times without an explicit offset are interpreted in the practitioner's timezone.
  - `date_time_to` string, date-time, required — End of the window, as an ISO 8601 date-time. Must be after `date_time_from`.
  - `is_available` boolean, required — `true` opens an extra working window; `false` blocks bookings (e.g. leave). `false` rules will fail validation if existing confirmed appointments or sessions overlap the window.
  - `offerings` OfferingIdentifier[] — The offerings the practitioner is assigned to during this window. An empty array (or omitted) means the practitioner is not linked to specific offerings for this window.
    - `offering_id` string, mongo-id, required — The ID of the offering.
    - `offering_name` string, required — The name of the offering.
    - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.

## Response `201`

A single `PractitionerCustomAvailability` rule.

- object
  - `data` PractitionerCustomAvailability, required — A `PractitionerCustomAvailability` is an ad-hoc override to a practitioner's regular rota for a specific date-time window. Setting `is_available: true` opens an extra working window — for example, picking up a Saturday shift; `is_available: false` blocks the practitioner from being booked — for example, leave or sickness. Custom availability rules take precedence over the rota for the period they cover. Adjacent rules with the same `is_available` value, `room_id`, `category_ids`, and `offerings` are automatically merged when created or updated.
    - `id` string, object-id, required — The unique identifier of the custom availability rule.
    - `has_availability_id` string, object-id, required — The ID of the resource this rule belongs to. For rules created through this endpoint, this is the practitioner ID.
    - `date_time_from` string, date-time, required — The start of the window the rule covers, in ISO 8601 with the practitioner's timezone offset.
    - `date_time_to` string, date-time, required — The end of the window the rule covers, in ISO 8601 with the practitioner's timezone offset.
    - `is_available` boolean, required — `true` means the practitioner is bookable during the window; `false` blocks bookings. A `false` rule overrides any regular rota availability for the same period.
    - `room_id` string, object-id, nullable, required — The ID of the room the practitioner is assigned to during this window, if any.
    - `category_ids` string[], required — The IDs of the service categories the practitioner is available for during this window. An empty array means all categories are available.
    - `offerings` OfferingIdentifier[], required — The offerings the practitioner is assigned to during this window. An empty array means the practitioner is not linked to specific offerings for this window.
      - `offering_id` string, mongo-id, required — The ID of the offering.
      - `offering_name` string, required — The name of the offering.
      - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.

## Other responses

- `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)
