Skip to main content

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), or per_time (multiplied by the rental length: set time_unit to hour/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_quantity is 1 for a charge taken once, and null (no cap) for everything else. A booking that asks for two of a once extra is refused with a field-named 422; see Create booking. Existing once extras that customers had booked two or more of were moved to per_item, so they keep selling the same way. Bookings already taken keep their own snapshot.
  • Availability targeting: rental_applies_to = none | all | categories | products, and experience_applies_to = none | all | experiences. Targeted ids are exposed as category_ids, product_ids, and experience_ids.
  • Stock: stock_quantity is null for 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 extras array takes an optional unit_price on 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_price the line is stored at 0 with price_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} and GET /v1/experiences/{id} include available_extras β€” the active extras offered on that item.
  • POST /v1/bookings accepts extras inside each products[] / experiences[] entry β€” see Create Booking.
  • Booking responses include the sold extras (snapshots) on each line item's extras array.

Endpoints​

MethodEndpointScope
GET/v1/extrasproducts:read
GET/v1/extras/{id}products:read
POST/v1/extrasproducts: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.