Skip to main content
When a customer selects more than one service (quantity > 1), add-ons and sub-bookings must be associated with each individual booking instance. This guide covers the add_ons_by_service and sub_bookings_by_service payload structures used in checkout.

The Problem with the Old Format

The legacy format sent add-ons as a flat list:
This made it impossible to associate add-ons with specific booking instances when quantity > 1.

New Structure

The new format groups selections by service and booking instance:

add_ons_by_service

  • Top level key: service ID
  • Outer array: one entry per booking of that service
  • Inner array: the add-ons selected for that specific booking instance
quantity is resolved against the add-on’s min_quantity and always_apply (default true). When always_apply is true, omitting an add-on or sending 0 still includes it at min_quantity. When always_apply is false, omit it or send 0 to skip; a quantity greater than 0 is still floored to min_quantity. Admin org edits treat an explicit 0 as removal. See Add-On.

sub_bookings_by_service

Same structure: service → booking instances → selections per instance.

Example

Two services, each booked twice:

UI Requirements

  • Allow selecting add-ons independently for each booking instance (similar to a shopping cart)
  • Provide an “Apply to all” option that copies the same add-ons/sub-resources to all instances of the same service
  • Show the add-on/sub-resource filter and search UI only when 5+ options are available
  • Filtering by group and name is client-side only

Sub-Resource Availability

When fetching sub-resources with the availability filter, the response includes number_available in the resource metadata:
The number_available attribute indicates how many times a resource can still be booked. Enforce this constraint client-side across all booking instances in the current selection.
The API validates availability on submission but is unaware of the user’s current in-progress selection. If a resource is available twice and the user selects it for two bookings, it must be marked as unavailable for any additional bookings locally before the request is sent.