Offerings catalog

Packages

A Package represents a collection of Offerings that can be purchased together.

get/shop/packages

List packages

listPackages

Returns a paginated list of Packages configured at the given site, ordered by name. Use this to power a settings dashboard or to populate a shopfront browse page. The list includes archived (soft-deleted) packages only when archived=true is passed.

Requires the RESERVATIONS_VIEW permission on the site. Pass include_option_offerings=true to embed each item choice's option offering details (helpful when rendering the package contents inline).

Query parameters

  • site_idstringrequired

    Filter results by the site they belong to

  • pageintegeroptional

    The page to retrieve results from

  • per_pageintegeroptional

    The number of results to return per page

  • archivedbooleanoptional

    Whether to include archived resources in the response. When true, archived resources are returned; when false or omitted, only non-archived resources are returned.

  • category_idstringoptional

    Filter results to packages that include the given category in their category_ids. Comma-separate to OR multiple categories (e.g. category_id=5e932c0901d210625e3a8766,5e932c0901d210625e3a8767).

  • When true, each Package's item_choices[].options[].offering is populated with a hydrated PackageShopOffering (name, price, image, etc.) — useful when rendering the package contents on an admin page without making a follow-up request per option. Defaults to false to keep responses small.

Responses

  • 200

    A paginated list of Packages for the requested site.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

post/shop/packages

Create a package

createPackage

Creates a new Package at the given site. The minimum body is name + site_id; everything else has sensible defaults. Requires the SETTINGS_MANAGE permission on site_id.

Server-side behaviour worth noting:

  • separate_couples_package_choices is forced to false unless both min_guests and max_guests equal 2.
  • permitted_membership_type_ids is filtered to membership types within the site's brand; others are silently dropped.
  • When overnight_package_config.enabled=true, both rate_id and num_nights are required — otherwise the request fails with 422.
  • organisation_id defaults to the caller's primary organisation when omitted.

Query parameters

  • site_idstringrequired

    Filter results by the site they belong to

  • pageintegeroptional

    The page to retrieve results from

  • per_pageintegeroptional

    The number of results to return per page

  • archivedbooleanoptional

    Whether to include archived resources in the response. When true, archived resources are returned; when false or omitted, only non-archived resources are returned.

  • category_idstringoptional

    Filter results to packages that include the given category in their category_ids. Comma-separate to OR multiple categories (e.g. category_id=5e932c0901d210625e3a8766,5e932c0901d210625e3a8767).

  • When true, each Package's item_choices[].options[].offering is populated with a hydrated PackageShopOffering (name, price, image, etc.) — useful when rendering the package contents on an admin page without making a follow-up request per option. Defaults to false to keep responses small.

Request body

  • namestringrequired

    Display name for the package. Visible to customers in the shopfront and to staff in the admin UI. Plain text only.

  • descriptionstringoptional

    Long-form description shown to customers when they're browsing the package. Markdown is rendered.

  • product_codestringoptionalnullable

    Optional product code used to map this package to an external POS or PMS catalog. Free-form string; uniqueness is not enforced server-side.

  • external_idstringoptionalnullable

    External identifier used by integrations to reference this offering. Free-form.

  • currencystringoptional

    The ISO-4217 currency code.

  • standard_priceintegeroptionalnullable

    The standard price for this package, in the smallest currency unit (e.g. pence). Optional at create time — packages can be created without a standard price and have one configured later.

  • site_idstringrequired

    ID of the site to offer this package at. The caller's API key must have access to the site; requests for a site they don't own get 422.

  • organisation_iduuidoptional

    Optional organisation to attribute this offering to. Defaults to the caller's primary organisation if omitted.

  • availability_rulesobject[]optional

    Per-day availability rules controlling when this package can be booked. See AvailabilityRule for shape.

  • offered_onlinebooleanoptional

    When true, the package is bookable via the public shopfront. When false, it's bookable only via the admin UI. Defaults to false.

  • privatebooleanoptional

    When true, only customers with the direct link can book this package — it's hidden from category pages and search engines.

  • visibilitystringoptional

    Visibility override controlling who can see this package on the shopfront. public shows it everywhere; link_only keeps it out of browse/search (still bookable by direct link); private restricts it to admin booking flows.

    Possible values:publiclink_onlyprivate
  • customers_onlybooleanoptional

    When true, only registered customers (not guests) can book this package.

  • members_onlybooleanoptional

    When true, only members of permitted membership types can book this package.

  • permitted_membership_type_idsstring[]optionalnullable

    Membership type IDs whose members are allowed to book this package. Only relevant when members_only=true. Membership types from outside the site's brand are silently filtered out.

  • When true, members can book this package further in advance than the standard window. The exact extra advance per membership type is defined in membership_booking_windows.

  • Per-membership-type advance-booking-window overrides.

  • item_choicesobject[]optional

    The choices customers make when booking this package (e.g. "pick a massage", "pick a lunch course"). Each choice has an allocation, options, start-time rules, and visibility flags. The detailed shape is documented as PackageItemChoice under the Package schema — the create endpoint accepts the same object shape.

  • upsell_offeringsobject[]optional

    Other offerings to upsell on the booking confirmation page.

  • cross_sell_offeringsobject[]optional

    Other offerings to cross-sell during the booking flow.

  • category_idsstring[]optional

    Category IDs the package belongs to. Used for shopfront grouping.

  • metaobjectoptional

    SEO metadata for the public shopfront page.

  • customer_cancellation_permittedstringoptionalnullable

    Whether and when customers can cancel a booking of this package themselves. allowed = always; if_unpaid = only if no payment has been taken; disallowed = never (admin only).

    Possible values:allowedif_unpaiddisallowed
  • ISO 8601 duration before the package's start during which cancellation is no longer permitted. e.g. PT24H = no cancellation in the last 24 hours.

  • customer_reschedule_permittedstringoptionalnullable

    Whether and when customers can reschedule a booking of this type themselves. allowed = always. unpaid = only if no payment has been taken against the order. disallowed = never (admin only).

    Possible values:alloweddisallowedunpaid
  • customer_reschedule_min_durationstringoptionalnullable

    ISO 8601 duration before the package's start during which rescheduling is no longer permitted. e.g. PT24H = no rescheduling in the last 24 hours.

  • max_daily_durationintegeroptionalnullable

    Maximum minutes between the start of the first and end of the last item on each day of the package. Use this to cap how spread-out a single-day package can become.

  • max_advance_bookings_intervalstringoptionalnullable

    ISO 8601 duration limiting how far in advance customers can book this package. e.g. P2W = up to two weeks ahead.

  • min_advance_bookings_intervalstringoptionalnullable

    ISO 8601 duration limiting how soon before the package start a customer can book. e.g. P2D = at least two days' notice.

  • min_guestsintegeroptionalnullable

    Minimum number of guests for a single booking of this package.

  • max_guestsintegeroptionalnullable

    Maximum number of guests for a single booking. Must be >= min_guests. Server-side, separate_couples_package_choices is forced to false unless both min_guests and max_guests equal 2.

  • prevent_choice_overlapsbooleanoptionalnullable

    Whether to prevent booking choices in this package from overlapping times.

  • separate_couples_package_choicesbooleanoptionalnullable

    For couples packages (both min_guests and max_guests equal 2), whether each guest can independently pick choices. Forced to false for any other guest configuration.

  • email_optionsobjectoptional

    Email-rendering options for this package.

  • Configuration for overnight packages — packages that include a hotel room reservation alongside their other items. When enabled=true, both rate_id and num_nights are required.

  • Whether to surface the price alongside this package in calendar views.

  • max_per_basketintegeroptionalnullable

    Maximum bookings of this package per basket.

  • max_per_guestintegeroptionalnullable

    Maximum bookings of this package per individual guest within a basket.

Responses

  • 201

    A single Package.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 422

    The request didn't pass validation

get/shop/packages/{packageId}

Retrieve a Package

getPackage

Use this endpoint to retrieve a single Package model.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Query parameters

  • basketItemIdobject-idoptional

    The ID of the basket item associated with the package. If provided, the returned package will include additional fields relevant to the basket item.

Responses

  • 200

    The Package was successfully retrieved.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

put/shop/packages/{packageId}

Update a package

updatePackage

Partially updates a Package. Every field is optional; only fields you send are written. Fields you omit retain their current values.

Requires the SETTINGS_MANAGE permission on the package's site. site_id and organisation_id are fixed at create time and cannot be changed here. Server-side, the same separate_couples_package_choices and permitted_membership_type_ids rules apply as on create.

When overnight_package_config.enabled flips, the package's hotel-room item choice is created (or removed) automatically — you don't need to send it explicitly.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Query parameters

  • basketItemIdobject-idoptional

    The ID of the basket item associated with the package. If provided, the returned package will include additional fields relevant to the basket item.

Request body

  • namestringoptional

    Display name. Plain text only.

  • descriptionstringoptional

    Long-form description shown to customers. Markdown is rendered.

  • product_codestringoptionalnullable

    External POS/PMS product code.

  • external_idstringoptionalnullable

    External identifier used by integrations.

  • currencystringoptional

    The ISO-4217 currency code.

  • standard_priceintegeroptionalnullable

    The standard price for this package, in the smallest currency unit (e.g. pence). Pass null to clear a previously-set standard price.

  • availability_rulesobject[]optional

    Per-day availability rules.

  • offered_onlinebooleanoptional

    Whether the package is bookable via the public shopfront.

  • privatebooleanoptional

    When true, only customers with the direct link can book this package.

  • visibilitystringoptional

    Visibility override controlling who can see this package on the shopfront. Same semantics as on create.

    Possible values:publiclink_onlyprivate
  • customers_onlybooleanoptional

    Restrict booking to registered customers.

  • members_onlybooleanoptional

    Restrict booking to permitted membership-type holders.

  • permitted_membership_type_idsstring[]optionalnullable

    Membership types whose members can book when members_only=true.

  • Whether to apply per-membership-type advance-booking windows.

  • Per-membership-type advance-window overrides.

  • item_choicesobject[]optional

    Replacement set of item choices for this package. Same shape as PackageItemChoice on the Package schema.

  • upsell_offeringsobject[]optional

    Upsell candidates at booking confirmation.

  • cross_sell_offeringsobject[]optional

    Cross-sell candidates during booking.

  • category_idsstring[]optional

    Category IDs for shopfront grouping.

  • metaobjectoptional

    SEO metadata for the shopfront page.

  • customer_cancellation_permittedstringoptionalnullable

    Customer self-cancellation policy.

    Possible values:allowedif_unpaiddisallowed
  • ISO 8601 duration before start at which cancellation is locked.

  • customer_reschedule_permittedstringoptionalnullable

    Whether and when customers can reschedule a booking of this type themselves. allowed = always. unpaid = only if no payment has been taken against the order. disallowed = never (admin only).

    Possible values:alloweddisallowedunpaid
  • customer_reschedule_min_durationstringoptionalnullable

    ISO 8601 duration before start at which rescheduling is locked.

  • max_daily_durationintegeroptionalnullable

    Maximum minutes between first-item start and last-item end on each day.

  • max_advance_bookings_intervalstringoptionalnullable

    ISO 8601 maximum advance-booking duration.

  • min_advance_bookings_intervalstringoptionalnullable

    ISO 8601 minimum advance-booking duration.

  • min_guestsintegeroptionalnullable

    Minimum guests per booking.

  • max_guestsintegeroptionalnullable

    Maximum guests per booking. When either min_guests or max_guests is not exactly 2, separate_couples_package_choices is forced to false server-side.

  • prevent_choice_overlapsbooleanoptionalnullable

    Whether to prevent booking choices in this package from overlapping times.

  • separate_couples_package_choicesbooleanoptionalnullable

    For couples packages, whether each guest can independently pick choices. Forced to false for any other guest configuration.

  • image_idstringoptionalnullable

    ID of an uploaded Media to use as the cover image. Pass null to clear.

  • default_revenue_centrestringoptionalnullable

    Default revenue centre identifier to fall back to when balancing allocations. Must be a valid revenue centre at the package's site.

  • email_optionsobjectoptional

    Email-rendering options for this package.

  • Overnight-package configuration. When enabled=true, both rate_id and num_nights must be set (either in this request or already on the package).

  • Surface prices in calendar views.

  • max_per_basketintegeroptionalnullable

    Max of this package per basket.

  • max_per_guestintegeroptionalnullable

    Max of this package per guest per basket.

Responses

  • 200

    A single Package.

  • 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

delete/shop/packages/{packageId}

Delete a package

deletePackage

Soft-deletes the package. Existing orders containing it are unaffected; the package is removed from new-booking flows. Use POST .../restore to bring it back.

Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Query parameters

  • basketItemIdobject-idoptional

    The ID of the basket item associated with the package. If provided, the returned package will include additional fields relevant to the basket item.

Responses

  • 204

    Package deleted successfully.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

post/shop/packages/{packageId}/copy

Duplicate a package

copyPackage

Creates a copy of an existing Package with new fields applied from the request body. Useful when seeding a new offering off an existing one rather than building from scratch. The new package is created under the same site and organisation as the original; fields not listed in the body are inherited from the source unchanged.

Requires the SETTINGS_MANAGE permission on the original package's site. As with create/update, separate_couples_package_choices is forced to false unless both min_guests and max_guests equal 2, and overnight_package_config.enabled=true requires rate_id and num_nights.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Request body

  • namestringoptional

    Display name for the new copy. Strongly recommended so the copy is distinguishable from the source.

  • descriptionstringoptional

    Override the customer-facing long-form description on the copy. Defaults to the source's description when omitted. Markdown rendered.

  • external_idstringoptionalnullable

    Override external identifier on the copy. Defaults to null so integrations don't accidentally see two offerings with the same external id.

  • priceintegeroptional

    Flat base price (in the smallest currency unit, e.g. pence/cents) to set on the copy. Most packages prefer price_rules; this field is a convenience for the simple case.

  • standard_priceintegeroptionalnullable

    Override the standard price on the copy, in the smallest currency unit (e.g. pence). Defaults to the source's standard price when omitted.

  • currencystringoptional

    The ISO-4217 currency code.

  • availability_rulesobject[]optional

    Override the per-day availability rules on the copy.

  • offered_onlinebooleanoptional

    Whether the copy is bookable via the public shopfront. Defaults to the source's value.

  • privatebooleanoptional

    When true, only customers with the direct link can book the copy.

  • visibilitystringoptional

    Visibility override on the copy. Same semantics as on the source.

    Possible values:publiclink_onlyprivate
  • customers_onlybooleanoptional

    When true, only registered customers (not guests) can book the copy.

  • members_onlybooleanoptional

    When true, only members of permitted membership types can book the copy.

  • permitted_membership_type_idsstring[]optionalnullable

    Membership types whose members can book the copy when members_only=true.

  • Whether to apply per-membership-type advance-booking windows on the copy.

  • Per-membership-type advance-window overrides on the copy.

  • upsell_offeringsobject[]optional

    Override the upsell candidates surfaced at booking confirmation on the copy.

  • cross_sell_offeringsobject[]optional

    Override the cross-sell candidates surfaced during the booking flow on the copy.

  • metaobjectoptional

    SEO metadata for the copy's shopfront page.

  • customer_cancellation_permittedstringoptionalnullable

    Customer self-cancellation policy on the copy. allowed = always; if_unpaid = only if no payment has been taken; disallowed = never.

    Possible values:allowedif_unpaiddisallowed
  • ISO 8601 duration before the package start during which cancellation is no longer permitted on the copy.

  • customer_reschedule_permittedstringoptionalnullable

    Whether and when customers can reschedule a booking of this type themselves. allowed = always. unpaid = only if no payment has been taken against the order. disallowed = never (admin only).

    Possible values:alloweddisallowedunpaid
  • customer_reschedule_min_durationstringoptionalnullable

    ISO 8601 duration before the package start during which rescheduling is no longer permitted on the copy.

  • max_daily_durationintegeroptional

    Maximum minutes between first-item start and last-item end on each day for the copy.

  • max_advance_bookings_intervalstringoptionalnullable

    ISO 8601 duration limiting how far in advance customers can book the copy.

  • min_advance_bookings_intervalstringoptionalnullable

    ISO 8601 duration limiting how soon before the package start a customer can book the copy.

  • min_guestsintegeroptionalnullable

    Minimum guests per booking of the copy.

  • max_guestsintegeroptionalnullable

    Maximum guests per booking of the copy.

  • Whether to prevent booking choices in the copy from overlapping times.

  • separate_couples_package_choicesbooleanoptionalnullable

    For couples packages, whether each guest can independently pick choices on the copy. Forced to false for any other guest configuration.

  • email_optionsobjectoptional

    Email-rendering options for the copy.

  • Overnight-package configuration on the copy. When enabled=true, both rate_id and num_nights are required.

  • Whether to surface the price alongside the copy in calendar views.

  • max_per_basketintegeroptionalnullable

    Maximum number of the copy per basket.

  • max_per_guestintegeroptionalnullable

    Maximum number of the copy per individual guest per basket.

Responses

  • 201

    A single Package.

  • 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

post/shop/packages/{packageId}/restore

Restore a deleted package

restorePackage

Un-deletes a previously soft-deleted Package. The package returns to its pre-deletion state, including price, item choices, availability rules, and overnight configuration. Existing orders that contained the package remain unaffected.

Requires the SETTINGS_MANAGE permission on the package's site. No request body.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Responses

  • 200

    The package was restored successfully.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

get/shop/packages/{packageId}/locale-strings/{locale}

Retrieve locale strings for a Package

getPackageLocaleStrings

Returns the localised name, description, meta_title and meta_description for the given locale.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • localestringrequired

    A supported locale code (e.g. fr, en_GB). The bare en locale is not accepted — base English strings are stored directly on the offering's name and description fields. Regional English variants such as en_GB and en_US are valid.

Responses

  • 200

    The locale strings for the package were successfully retrieved.

  • 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

put/shop/packages/{packageId}/locale-strings/{locale}

Update locale strings for a Package

updatePackageLocaleStrings

Sets the localised name, description, meta_title and/or meta_description for the given locale. Pass null to clear a translation and fall back to the default value.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • localestringrequired

    A supported locale code (e.g. fr, en_GB). The bare en locale is not accepted — base English strings are stored directly on the offering's name and description fields. Regional English variants such as en_GB and en_US are valid.

Request body

  • namestringoptionalnullable

    The localised name for this package in the given locale.

  • descriptionstringoptionalnullable

    The localised description for this package in the given locale.

  • meta_titlestringoptionalnullable

    The localised meta title for this package in the given locale.

  • meta_descriptionstringoptionalnullable

    The localised meta description for this package in the given locale.

Responses

  • 200

    The locale strings for the package were successfully updated.

  • 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

get/shop/packages/{packageId}/item-choices/{itemChoiceId}/locale-strings/{locale}

Retrieve locale strings for a Package Item Choice

getPackageItemChoiceLocaleStrings

Returns the localised name and description for the given locale.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

  • localestringrequired

    A supported locale code (e.g. fr, en_GB). The bare en locale is not accepted — base English strings are stored directly on the offering's name and description fields. Regional English variants such as en_GB and en_US are valid.

Responses

  • 200

    The locale strings for the package item choice were successfully retrieved.

  • 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

put/shop/packages/{packageId}/item-choices/{itemChoiceId}/locale-strings/{locale}

Update locale strings for a Package Item Choice

updatePackageItemChoiceLocaleStrings

Sets the localised name and/or description for the given locale. Pass null to clear a translation and fall back to the default value.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

  • localestringrequired

    A supported locale code (e.g. fr, en_GB). The bare en locale is not accepted — base English strings are stored directly on the offering's name and description fields. Regional English variants such as en_GB and en_US are valid.

Request body

  • namestringoptionalnullable

    The localised name for this item choice in the given locale.

  • descriptionstringoptionalnullable

    The localised description for this item choice in the given locale.

Responses

  • 200

    The locale strings for the package item choice were successfully updated.

  • 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

get/shop/packages/{packageId}/availability-rules

List availability rules for a package

listPackageAvailabilityRules

Returns all AvailabilityRules configured on the given Package. Availability rules carve up the working calendar into windows when the package can or cannot be booked — useful for blocking holidays, restricting weekend hours, or making the package available only during specific seasons.

Rule semantics: any is_available: false rule overrides any is_available: true rule for the same time period. Results are paginated.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Query parameters

  • pageintegeroptional

    The page to retrieve results from

  • per_pageintegeroptional

    The number of results to return per page

Responses

  • 200

    A paginated list of AvailabilityRules on a Package.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

post/shop/packages/{packageId}/availability-rules

Create an availability rule for a package

createPackageAvailabilityRule

Adds a new AvailabilityRule to a Package. With is_available: true the rule opens new bookable windows; with is_available: false it blocks them. Any false rule overrides any true rule for the same period. Omitting date/time/weekday filters means the rule applies always.

date_from defaults to today in the package's timezone when omitted. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Request body

  • is_availablebooleanrequired

    When true, this rule opens bookable windows for the package. When false, it closes them. Any false rule overrides any true rule for the same time period.

  • date_fromdateoptionalnullable

    First date this rule applies (inclusive). Defaults to today in the package's timezone when omitted.

  • date_todateoptionalnullable

    Last date this rule applies (inclusive). When omitted, the rule has no end date.

  • time_fromstringoptionalnullable

    Start of the daily time window in 24-hour HH:MM format.

  • time_tostringoptionalnullable

    End of the daily time window in 24-hour HH:MM format.

  • min_durationintegeroptionalnullable

    Match the rule only when the package's total duration is ≥ this many minutes. Omit to apply to any duration.

  • max_durationintegeroptionalnullable

    Match the rule only when the package's total duration is ≤ this many minutes.

  • weekdaysstring[]optional

    Days of the week the rule applies on. Empty / omitted means every day.

Responses

  • 201

    A single AvailabilityRule belonging to a Package.

  • 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

get/shop/packages/{packageId}/availability-rules/{availabilityRuleId}

Retrieve a package availability rule

getPackageAvailabilityRule

Returns a single AvailabilityRule belonging to the given Package. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

Responses

  • 200

    A single AvailabilityRule belonging to a Package.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

put/shop/packages/{packageId}/availability-rules/{availabilityRuleId}

Update a package availability rule

updatePackageAvailabilityRule

Replaces an AvailabilityRule on a Package. The server validates the same shape as on create, so is_available is required. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

Request body

  • is_availablebooleanrequired

    Whether the window is bookable. false rules override true rules.

  • date_fromdateoptionalnullable

    First date this rule applies (inclusive).

  • date_todateoptionalnullable

    Last date this rule applies (inclusive).

  • time_fromstringoptionalnullable

    Daily start time in HH:MM.

  • time_tostringoptionalnullable

    Daily end time in HH:MM.

  • min_durationintegeroptionalnullable

    Match only for total package durations ≥ this many minutes.

  • max_durationintegeroptionalnullable

    Match only for total package durations ≤ this many minutes.

  • weekdaysstring[]optional

Responses

  • 200

    A single AvailabilityRule belonging to a Package.

  • 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

delete/shop/packages/{packageId}/availability-rules/{availabilityRuleId}

Delete a package availability rule

deletePackageAvailabilityRule

Removes an AvailabilityRule from a Package. Calendar availability is recomputed from the remaining rules. Existing bookings are unaffected. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

Responses

  • 204

    Availability rule deleted successfully.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

get/shop/packages/{packageId}/item-choices

List item choices on a package

listPackageItemChoices

Returns every PackageItemChoice configured on the given Package. Item choices are the building blocks of a package — each one defines a set of options the customer picks from (e.g. "Pick a 60-minute treatment", "Pick lunch or afternoon tea"). The package's overall price is the sum of the chosen options, with optional option_budget and price_change overrides per choice / option.

Order is preserved across reads — it reflects the customer-facing order in the booking flow, and can be modified through the reorder endpoint on the parent package.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Responses

  • 200

    A list of PackageItemChoices configured on a Package.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

post/shop/packages/{packageId}/item-choices

Create an item choice on a package

createPackageItemChoice

Adds a new PackageItemChoice to a Package. The new choice is appended to the package's existing item_choices list. Every option's item_type must match the choice's offering_type and must reference an offering on the package's site that the authenticated user has access to.

Server-side defaults: when min_options is omitted it falls back to 1 (or 0 if optional: true); when max_options is omitted it falls back to 1. With max_options: 1 the option_budget is ignored. Only one hotel_room_reservation choice is allowed per package — attempting to create a second returns 422.

Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Request body

  • namestringoptional

    A short, customer-facing label for the choice.

  • descriptionstringoptionalnullable

    A longer explanation rendered alongside the options at booking time.

  • min_optionsintegeroptionalnullable

    Minimum number of options the customer must pick. Defaults to 1 (or 0 when optional is true) when omitted.

  • max_optionsintegeroptionalnullable

    Maximum number of options the customer may pick. Defaults to 1 when omitted. With max_options: 1 any option_budget is ignored.

  • option_budgetintegeroptionalnullable

    An "included" budget for the chosen options in the smallest currency unit. Each option uses its standalone price; the overall package price is bumped up by any excess over this budget.

  • auto_select_timeslotbooleanoptional

    When true, the booking engine auto-picks a timeslot for this choice instead of asking the customer. Only allowed when offering_type is appointment.

  • hide_timesbooleanoptional

    Hide individual option start times from the customer-facing booking flow.

  • allocationobjectoptionalnullable

    An accounting allocation for this choice — splits the choice's portion of the package revenue into a named revenue centre at a fixed amount.

  • optionalbooleanoptional

    Whether the customer can skip this choice entirely.

  • visiblebooleanoptional

    Whether the choice is visible to the customer. Hidden choices are only allowed for product offering types.

  • offering_typestringoptional

    The type of offerings this choice's options reference. Only one hotel_room_reservation choice is allowed per package.

    Possible values:appointmentarea_bookinghotel_room_reservationproductsessiontable_reservation
  • optionsobject[]optional

    The list of selectable options. Each option references an offering on the package's site; the option's item_type must match this choice's offering_type.

Responses

  • 201

    A single PackageItemChoice on a Package.

  • 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

get/shop/packages/{packageId}/item-choices/{itemChoiceId}

Retrieve a package item choice

getPackageItemChoice

Returns a single PackageItemChoice belonging to the given Package, including the full option list and any configured start-time rules.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

Responses

  • 200

    A single PackageItemChoice on a Package.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

put/shop/packages/{packageId}/item-choices/{itemChoiceId}

Update a package item choice

updatePackageItemChoice

Updates a PackageItemChoice on a Package. Every field is optional; only the fields you send are written. Update is the only place where start_time_rules, allow_overlaps and choice_configuration can be set.

Setting visible: false is only valid when offering_type is product; other types return 400. When max_options becomes 1 any option_budget is dropped server-side. When the parent package's prevent_choice_overlaps is not true, allow_overlaps is forced to null.

Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

Request body

  • namestringoptional

    A short, customer-facing label for the choice.

  • descriptionstringoptionalnullable

    A longer explanation rendered alongside the options at booking time.

  • min_optionsintegeroptional

    Minimum number of options the customer must pick.

  • max_optionsintegeroptionalnullable

    Maximum number of options the customer may pick. With max_options: 1 any option_budget is dropped.

  • option_budgetintegeroptionalnullable

    Included budget for the chosen options in the smallest currency unit.

  • auto_select_timeslotbooleanoptional

    Whether the booking engine should auto-pick a timeslot for this choice.

  • hide_timesbooleanoptional

    Hide individual option start times from the customer-facing booking flow.

  • allocationobjectoptionalnullable

    An accounting allocation for this choice. Send null fields to clear the existing allocation.

  • optionalbooleanoptional

    Whether the customer can skip this choice entirely.

  • visiblebooleanoptional

    Whether the choice is visible to the customer. Setting visible: false is only allowed when offering_type is product; other types return 400.

  • offering_typestringoptional

    The type of offerings this choice's options reference.

    Possible values:appointmentarea_bookinghotel_room_reservationproductsessiontable_reservation
  • start_time_rulesobject[]optional

    Rules restricting which start times are offered for this choice's options. Each rule is either absolute (fixed HH:MM window) or relative (offset in minutes from a base point such as the start of the package's first item).

  • allow_overlapsbooleanoptional

    Allow this choice's items to overlap with other items even when prevent_choice_overlaps is true on the parent package. Has no effect unless the package opts in to overlap prevention.

  • optionsobject[]optional

    The list of selectable options. At least one option is required unless offering_type is hotel_room_reservation. Each option's item_type must match offering_type.

  • choice_configurationobjectoptional

    Free-form additional configuration for the choice. Shape depends on offering_type.

Responses

  • 200

    A single PackageItemChoice on a Package.

  • 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

delete/shop/packages/{packageId}/item-choices/{itemChoiceId}

Delete a package item choice

deletePackageItemChoice

Removes a PackageItemChoice from a Package. The remaining choices keep their order. Existing bookings of the package are unaffected. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

Responses

  • 204

    Item choice deleted successfully.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

get/shop/packages/{packageId}/price-rules

List price rules for a package

listPackagePriceRules

Returns all PriceRules configured on the given Package. Price rules determine the price the customer pays based on when the package is booked — peak vs off-peak, weekday vs weekend, seasonal overrides. The first rule whose conditions match the booking wins; when no rule matches, the package falls back to a sensible default.

Results are paginated. Requires read access to the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Query parameters

  • pageintegeroptional

    The page to retrieve results from

  • per_pageintegeroptional

    The number of results to return per page

Responses

  • 200

    A paginated list of price rules for a package.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

post/shop/packages/{packageId}/price-rules

Create a price rule for a package

createPackagePriceRule

Adds a new PriceRule to a Package. Combine date ranges, time windows and weekday filters to express most pricing scenarios — peak vs off-peak, weekday vs weekend, seasonal overrides. The first rule whose conditions match a given booking wins. Sending no filters creates a fallback "always applies" rule.

date_from defaults to today in the site's timezone when omitted. The package's standard_price must be set before a price rule can be created. A zero amount counts as set. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Request body

  • priceintegerrequired

    Price in the smallest currency unit (e.g. pence, cents). 20000 means £200.00 in a GBP-denominated site.

  • date_fromdateoptionalnullable

    First date this rule applies (inclusive). Defaults to today in the site's timezone when omitted.

  • date_todateoptionalnullable

    Last date this rule applies (inclusive). When omitted, the rule has no end date.

  • time_fromstringoptionalnullable

    Start of the time-of-day window in 24-hour HH:MM format. When time_to is set, must be earlier than time_to (the rule does not wrap past midnight).

  • time_tostringoptionalnullable

    End of the time-of-day window in 24-hour HH:MM format. Must be later than time_from if both are set.

  • weekdaysstring[]optional

    Days of the week this rule applies on. Empty / omitted means every day.

Responses

  • 201

    A single PriceRule belonging to a Package.

  • 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

get/shop/packages/{packageId}/price-rules/{priceRuleId}

Retrieve a package price rule

getPackagePriceRule

Returns a single PriceRule belonging to the given Package. Requires read access to the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • priceRuleIdobject-idrequired

    The unique identifier of the price rule.

Responses

  • 200

    A single PriceRule belonging to a Package.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

put/shop/packages/{packageId}/price-rules/{priceRuleId}

Update a package price rule

updatePackagePriceRule

Replaces a PriceRule on a Package. The server validates the same shape as on create, so price is required. The package's standard_price must be set before a price rule can be updated. A zero amount counts as set. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • priceRuleIdobject-idrequired

    The unique identifier of the price rule.

Request body

  • priceintegerrequired

    Price in the smallest currency unit.

  • date_fromdateoptionalnullable

    First date this rule applies (inclusive).

  • date_todateoptionalnullable

    Last date this rule applies (inclusive).

  • time_fromstringoptionalnullable

    Start of the time-of-day window in HH:MM.

  • time_tostringoptionalnullable

    End of the time-of-day window in HH:MM.

  • weekdaysstring[]optional

Responses

  • 200

    A single PriceRule belonging to a Package.

  • 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

delete/shop/packages/{packageId}/price-rules/{priceRuleId}

Delete a package price rule

deletePackagePriceRule

Removes a PriceRule from a Package. Existing bookings priced under this rule are unaffected — they retain the price recorded at booking time. The package's standard_price must be set before a price rule can be deleted. A zero amount counts as set. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • priceRuleIdobject-idrequired

    The unique identifier of the price rule.

Responses

  • 204

    Price rule deleted successfully.

  • 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

get/shop/packages/{packageId}/price-preview

Preview package prices

previewPackagePrices

Prices every start time of a Package over a window of up to seven days, exactly as the shop would price a package booked to start then. Use it to check what the package's price rules actually charge, for instance which days a weekend rule lifts the price: each cell carries the resolved price, the price rule that produced it, and whether the standard price applied because no rule matched.

Cells step through each day from midnight at the start_time_interval in the response, in the package's timezone. The package's own price is previewed, not what its parts contribute, and availability is not reported, since a package has no availability rules of its own. The price_rules in the response are the package's rules whose date range touches the window, in the same shape as the price rules endpoint, so a client can draw a legend from one payload.

Requires the RESERVATIONS_VIEW permission on the package's site, the same as listing its price rules.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Query parameters

  • date_fromdaterequired

    The first day of the window, ISO-8601 YYYY-MM-DD, in the offering type's timezone.

  • daysintegeroptional

    The number of days to preview from date_from, at most seven.

Responses

  • 200

    The resolved price for every start time in the window.

  • 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

post/shop/packages/{packageId}/item-choices/reorder

Reorder a package's item choice groups

actionReorderPackageItemChoices

Reorders the item_choices groups on a Package to match the supplied sequence of group IDs. Pass every existing item_choices[].id exactly once in the desired display order.

IDs not included in the order array are pushed to the tail in their original relative order, so a partial reorder simply moves the listed IDs to the front. Unknown IDs are ignored.

Returns the freshly-sorted Package. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

Request body

  • orderstring[]required

    The desired sequence of item-choice group IDs. IDs not listed are appended to the tail in their existing relative order. Unknown IDs are silently ignored.

Responses

  • 200

    A single Package.

  • 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

get/shop/packages/{packageId}/item-choices/{itemChoiceId}/options

List options for a package item choice

listPackageItemChoiceOptions

Returns every PackageItemChoiceOption configured on the named PackageItemChoice. Each option names a specific offering (e.g. a particular appointment type or retail product) that the parent choice may be filled by, plus the price uplift the option carries.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

Responses

  • 200

    A list of PackageItemChoiceOptions on a PackageItemChoice.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

post/shop/packages/{packageId}/item-choices/{itemChoiceId}/options

Add an option to a package item choice

createPackageItemChoiceOption

Adds a new PackageItemChoiceOption to the parent PackageItemChoice. The body sets the offering the option points at and any price uplift; the option is appended to the choice's existing list.

Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

Request body

  • idstringrequired

    Identifier of the offering this option points at — an AppointmentType, SessionType or retail Product, depending on item_type. The guest sees the offering's name and image when picking this option in the storefront.

  • item_typestringrequired

    The type of item this option represents.

  • offeringobjectrequirednullable
  • price_changeintegerrequirednullable

    A currency amount that this option would increase the package price by.

Responses

  • 201

    A single PackageItemChoiceOption.

  • 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

get/shop/packages/{packageId}/item-choices/{itemChoiceId}/options/{optionId}

Get a package item choice option

getPackageItemChoiceOption

Returns a single PackageItemChoiceOption on the named PackageItemChoice.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

  • optionIdobject-idrequired

    The unique identifier of the PackageItemChoiceOption — one of the offerings exposed by the parent PackageItemChoice as a pickable slot in the package.

Responses

  • 200

    A single PackageItemChoiceOption.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found

put/shop/packages/{packageId}/item-choices/{itemChoiceId}/options/{optionId}

Update a package item choice option

updatePackageItemChoiceOption

Updates the offering or price uplift on an existing PackageItemChoiceOption. Fields omitted from the body are left unchanged.

Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

  • optionIdobject-idrequired

    The unique identifier of the PackageItemChoiceOption — one of the offerings exposed by the parent PackageItemChoice as a pickable slot in the package.

Request body

  • idstringrequired

    Identifier of the offering this option points at — an AppointmentType, SessionType or retail Product, depending on item_type. The guest sees the offering's name and image when picking this option in the storefront.

  • item_typestringrequired

    The type of item this option represents.

  • offeringobjectrequirednullable
  • price_changeintegerrequirednullable

    A currency amount that this option would increase the package price by.

Responses

  • 200

    A single PackageItemChoiceOption.

  • 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

delete/shop/packages/{packageId}/item-choices/{itemChoiceId}/options/{optionId}

Delete a package item choice option

deletePackageItemChoiceOption

Removes a PackageItemChoiceOption from its parent PackageItemChoice. Existing bookings of the package are unaffected; the option is just hidden from the choice's available options going forward. Requires the SETTINGS_MANAGE permission on the package's site.

Path parameters

  • packageIdobject-idoptional

    The ID of the package

  • itemChoiceIdobject-idrequired

    The unique identifier of the item choice (also known as a choice group) within the package.

  • optionIdobject-idrequired

    The unique identifier of the PackageItemChoiceOption — one of the offerings exposed by the parent PackageItemChoice as a pickable slot in the package.

Responses

  • 204

    The option was successfully deleted.

  • 401

    The user is unauthenticated

  • 403

    The authenticated user does not have permission.

  • 404

    The resource couldn't be found