Docs

Packages

Last updated: 26 Oct 2026

Packages sell several things as one product at one price: a stay with a room plus meals, a sauna hour or tickets, or a bundle without a room. Use these endpoints to list packages and show one with everything it contains.

All endpoints are scoped to the organization that owns the API key:

/store/v0

List packages

GET /store/v0/packages

Returns the packages that are public, on sale now and bookable (no closed_reason).

Response

{
  "packages": [
    {
      "public_id": "9630b448-147c-424a-8ed5-f9d41cdc7421",
      "name": "Autumn calm at Jølstraholmen",
      "short_description": "3–10 nights with a private sauna hour included.",
      "description": "…",
      "kind": "stay",
      "asks_for_day": false,
      "dates_label": "3–10 nights",
      "nights_min": 3,
      "smallest_party": 1,
      "largest_party": 6,
      "room_choices": "Lodgen or Deluxe elvasus",
      "price_label": "Depends on your dates",
      "price_unit_label": null,
      "price_range": null,
      "thumbnail_url": "https://assets.servos.dk/derivations/media/thumbnail/400/400/…",
      "medias": [],
      "components": [
        {
          "public_id": "f7fc65b6-f266-408f-b5c5-5bbf8f344022",
          "kind": "room",
          "name": "Lodgen or Deluxe elvasus",
          "inclusion": "included",
          "booking_role": "room",
          "quantity_rule": "per_stay",
          "quantity_label": "once per booking",
          "guest_picks": true,
          "price": null,
          "prices_vary": false,
          "thumbnail_url": "https://assets.servos.dk/derivations/media/thumbnail/400/400/…",
          "options": [
            {
              "public_id": "d031cf87-a78d-4b6e-997b-bc8a6ff37f41",
              "name": "Lodgen",
              "capacity": 6,
              "capacity_label": "Up to 6 guests",
              "accommodation_id": "e212ccd5-aa5d-4603-936f-0a0151cc0ebd",
              "service_id": null,
              "service_variant_id": null,
              "price": null,
              "thumbnail_url": "https://assets.servos.dk/derivations/media/thumbnail/400/400/…"
            }
          ]
        },
        {
          "public_id": "1054ad56-72da-4149-bc41-4216887d98be",
          "kind": "service",
          "name": "Private sauna",
          "inclusion": "included",
          "booking_role": "included",
          "quantity_rule": "per_stay",
          "quantity_label": "once per booking",
          "guest_picks": false,
          "price": null,
          "prices_vary": false,
          "thumbnail_url": null,
          "options": [
            {
              "public_id": "5a74bfac-5a61-46bf-b830-fd2c71087ce7",
              "name": "Private sauna",
              "capacity": 6,
              "capacity_label": "Up to 6 guests",
              "accommodation_id": null,
              "service_id": "c12037f4-12da-4f9d-8462-30ccb754661f",
              "service_variant_id": "5b603b73-47e6-41fb-a298-5abfbaf2a67c",
              "price": null,
              "thumbnail_url": null
            }
          ]
        },
        {
          "public_id": "99f1cb76-4180-456b-b880-b8e09c600d84",
          "kind": "addon",
          "name": "Breakfast",
          "inclusion": "extra",
          "booking_role": "extra",
          "quantity_rule": "per_guest_night",
          "quantity_label": "per guest per night",
          "guest_picks": false,
          "prices_vary": false,
          "price": {
            "cents": 25000,
            "currency": "NOK",
            "amount": 250.0,
            "formatted": "250 NOK",
            "abbreviated": "250 NOK"
          },
          "thumbnail_url": null,
          "options": [
            {
              "public_id": "96fa5303-146e-4a06-9ce6-8cb4467c7373",
              "name": "Breakfast",
              "capacity": null,
              "capacity_label": null,
              "accommodation_id": null,
              "service_id": null,
              "service_variant_id": null,
              "price": {
                "cents": 25000,
                "currency": "NOK",
                "amount": 250.0,
                "formatted": "250 NOK",
                "abbreviated": "250 NOK"
              },
              "thumbnail_url": null
            }
          ]
        }
      ],
      "component_groups": [
        ["f7fc65b6-f266-408f-b5c5-5bbf8f344022"],
        ["1054ad56-72da-4149-bc41-4216887d98be"],
        ["99f1cb76-4180-456b-b880-b8e09c600d84"]
      ]
    }
  ]
}

Get a package

GET /store/v0/packages/{public_id}

Returns { "package": { … } } with the fields of the list plus a stay's check_ins. A private package opens here and in the search and cart endpoints, but is not in the list, so you can sell it by direct link. A draft returns 404.

Package object reference

FieldTypeDescription
public_idstringPackage public identifier
namestringPackage name
short_descriptionstring | nullOne-line summary
descriptionstring | nullFull description, plain text with line breaks
kind"stay" | "bundle"A stay books a room for a range of nights. A bundle has no room and no dates.
asks_for_daybooleanBundles only. The guest picks one day, and its services are booked on that day. Send it as check_in_date; closed days lists the days to disable.
dates_labelstringHow long the stay is, for example "2 nights" or "3–10 nights"
nights_minintegerStays only. Shortest stay in nights.
check_inscheck-in[]Stays, from GET /store/v0/packages/{public_id} only. Every date a stay can start on, from today for a year, with the nights it can last. Dates not listed can't be booked.
smallest_party / largest_partyintegerThe fewest and most guests the package takes. Offer party sizes between them.
room_choicesstring | nullStays where the guest picks the room: the rooms to choose from, like "Lodgen or Deluxe elvasus"
price_labelstring | nullThe price as a sentence, for example "Depends on your dates" or "2,345 NOK per guest per night"
price_unit_labelstring | nullThe unit of a fixed price, for example "per guest per night"
price_rangeobject | null{ "min": money, "max": money, "from": boolean } for fixed-price packages; null at item prices. Show min as "From …" when from.
closed_reasonstring | nullWhy nobody can book the package now, like "Not on sale" or "Jazz has ended". Show it instead of the booking form.
todaydate (YYYY-MM-DD)The venue's date today. Dates before it can't be booked.
event_starts_on / event_ends_ondate | nullBundles with an event only. The event's first and last day; the bundle books its services on them.
thumbnail_urlstring | nullCover image
mediasmedia[]Package images, see Types
componentscomponent[]What the package contains, in display order
component_groupsstring[][]Every component's public ID in display order, grouped. See Component groups.

A check-in is { "date": "YYYY-MM-DD", "min_nights": 3, "max_nights": 10, "nights": [3, 4, …, 10] }. nights lists every stay length that can start on date; the check-out is date plus one of them. The rules behind it (season, closed dates, start days, shortest and longest stay, and which rooms are free) are applied on the server, so the calendar only needs these dates.

Component

FieldTypeDescription
public_idstringComponent public identifier. Use it in choices, extra_component_ids and slots.
kindstringroom, addon, product, service, service_addon or ticket. A service_addon is booked onto the booking of a service component in the same package
namestringDisplay name; lists the options when there are several
inclusion"included" | "extra"Included components are in the package price. Extras are optional and cost their own price on top.
booking_rolestringWhere the booking form shows it: room (the quotes), pick (the guest chooses an option), included or extra (a tick box)
quantity_rulestringHow many are booked: per_stay, per_guest, per_night or per_guest_night
quantity_labelstringThe quantity rule in English, like "per guest per night"
guest_picksbooleantrue when the guest chooses one of several options
asks_for_timebooleantrue for services: the guest picks a time, sent in slots
thumbnail_urlstring | nullThe first option's image
pricemoney | nullExtras only. The cheapest option's price per unit.
prices_varybooleantrue when the options cost different amounts, so show price as "From …"
optionsoption[]The items the component can book

Option

FieldTypeDescription
public_idstringOption public identifier. Use it as the value in choices.
namestringItem name
capacityinteger | nullRooms and services: how many guests it has space for
capacity_labelstring | nullcapacity in English, like "Up to 6 guests"
accommodation_idstring | nullRooms only. The accommodation's public ID.
service_id / service_variant_idstring | nullServices only. Use them with Service availability to list times.
pricemoney | nullExtras only. This option's price per unit.
party_seatsbooleanServices only. true when each guest takes a seat, so a time needs as many free seats as the party.
starts_at / starts_labelstring | nullTickets only. The event's start, as a timestamp and as a label in the venue's time zone, like "Thu 8 Oct, 20:00".

Component groups

component_groups lists every component's public ID in display order, in groups. Components with booking_role included that a guest can't tell apart share a group: show it once with its count, like "3 × Packed lunch". Every other component, each extra and pick list among them, has a group of its own. In a group of services, each component still takes its own time in slots.

Booking a package

  1. Show the package with GET /store/v0/packages/{public_id}.
  2. Price it for the guest's dates and party with the package search.
  3. For every service component the guest books, list times with Service availability using the option's service_id and service_variant_id, the search's service_starts_on and service_ends_on, and the option's seats from the search.
  4. Add it to a cart with Cart packages.