Extras
Extras are supplier-defined add-ons customers can tack onto a booking β helmets, insurance, photo packages. They live in one central catalog and can be offered on rental products, experiences, or both.
- Charged
once(a flat charge, added to a line once),per_item(a price for each one the customer picks, as many as they like),per_person(multiplied by participants on experience bookings), orper_time(multiplied by the rental length: settime_unittohour/day/week, e.g. a bike light at $2/day). Per-time bills whole periods rounded up, minimum 1; on experiences it falls back to a single charge. - How many per line:
max_quantityis1for a charge takenonce, andnull(no cap) for everything else. A booking that asks for two of aonceextra is refused with a field-named422; see Create booking. Existingonceextras that customers had booked two or more of were moved toper_item, so they keep selling the same way. Bookings already taken keep their own snapshot. - Availability targeting:
rental_applies_to=none|all|categories|products, andexperience_applies_to=none|all|experiences. Targeted ids are exposed ascategory_ids,product_ids, andexperience_ids. - Stock:
stock_quantityisnullfor unlimited (e.g. insurance). When set, availability is checked against overlapping bookings for the requested window. - Snapshots: when an extra is sold, its name and price are copied onto the booking line. Later catalog edits or deletions never change existing bookings.
Required charges per rented itemβ
Use charge_per: "per_rental_item" for a charge such as cleaning that applies to every rented item. It is available on rentals only. Set experience_applies_to to none and keep fulfillment_type as charge.
The booking and pricing preview include each applicable active charge automatically. Its quantity matches the parent rental quantity, even when the request omits it or sends zero. A rental of three items with a charge of 10 adds 30 once for that rental, regardless of its duration. Optional per_item extras still use the quantity the customer selects.
The Extra Objectβ
{
"id": 3,
"name": "Helmet",
"description": "Certified bike helmet, all sizes",
"price": 5.0,
"price_set_when_booked": false,
"rental_price": null,
"fulfillment_type": "charge",
"linked_product_id": null,
"linked_store_product_id": null,
"charge_per": "once",
"time_unit": null,
"max_quantity": 1,
"quantity_follows_rental": false,
"rental_applies_to": "all",
"experience_applies_to": "none",
"product_ids": [],
"category_ids": [],
"experience_ids": [],
"stock_quantity": null,
"active": true,
"created_at": "2026-06-10T21:30:00+00:00",
"updated_at": "2026-06-10T21:30:00+00:00"
}
Rental add-ons with a separate priceβ
A rental extra reserves its linked product for the parent rental or activity window. By default, it uses that product's schedule or seasonal rate. Set rental_price to charge a separate amount per borrowed item for the whole window; 30 with quantity 2 adds 60. Zero is free, while null restores the normal rental rate. The linked product's stock limits still apply, and its standalone rental rates stay unchanged.
Extras priced when bookedβ
Some add-ons don't have one price. Create the extra with price_set_when_booked: true and its price is 0. Staff set the price on each booking.
- Send the price on the booking line. Each entry in a line's
extrasarray takes an optionalunit_priceon Create Booking, Create Quote and the pricing preview. It's used only for an extra priced when booked; any other extra keeps its catalog price, whatever you send. Per-person and per-time extras multiply it as usual. - Or leave it for later. Without
unit_pricethe line is stored at0withprice_pending: true, and the booking confirms as normal. This is what happens when a customer adds the extra on the booking page. The confirmation email tells them the price follows. - Set it with Set Booking Extra Price. The booking total and balance update, and the customer gets the booking-updated email.
- Edits keep it. Rebuilding a booking (new dates, a reschedule) keeps the price you set unless you send a new
unit_price.
Booked extras on each line include:
{
"id": 912,
"extra_id": 7,
"name": "Pickup",
"quantity": 1,
"unit_price": 0.0,
"price": 0.0,
"price_pending": true
}
quantity_follows_rental is true for per_rental_item. Its quantity always matches the rented items, including items inside a bundle; clients cannot omit or change that charge.
Where extras appearβ
GET /v1/products/{id}andGET /v1/experiences/{id}includeavailable_extrasβ the active extras offered on that item.POST /v1/bookingsacceptsextrasinside eachproducts[]/experiences[]entry β see Create Booking.- Booking responses include the sold extras (snapshots) on each line item's
extrasarray.
Endpointsβ
| Method | Endpoint | Scope |
|---|---|---|
| GET | /v1/extras | products:read |
| GET | /v1/extras/{id} | products:read |
| POST | /v1/extras | products:write |
| PATCH | /v1/extras/{id} | products:write |
| DELETE | /v1/extras/{id} | products:write |
| PATCH | /v1/bookings/{id}/extras/{extraLineId} | bookings:write |
Ask Dash and MCPβ
create_extra and update_extra accept fulfillment_type: "rental", an owned
linked_product_id, and an optional rental_price. Set rental_price to a number for one price
per selected item, including zero. Set it to null to use the linked productβs rental rates; omit
it on updates to keep the saved choice. Quantity and booking dates still determine the stock reserved.