Docs

Cart items

Last updated: 26 Oct 2026

Cart items are line items inside a cart — bookings, stays, tickets, and passes. The API currently supports creating and removing cart items.

Unsupported operations

Some route definitions may suggest additional operations (like "new" or "update"), but they are not implemented as part of the public API contract.

If you attempt an unsupported operation, you should expect a 404 or similar failure.

All endpoints are location- and cart-scoped:

/store/v0/carts/{cart_public_id}

Add item to cart

POST /store/v0/carts/{cart_public_id}/items

Request body

{
  "cart_item": {
    "type": "booking",
    "attributes": {}
  }
}

type is one of booking, stay, ticket or pass, and determines which attributes are required. Any other value returns a 400 (see Errors).

Changes on 4 November 2026

Bookings used to be called appointments. Until 4 November 2026, "type": "appointment" still adds a booking, and the response carries Deprecation and Sunset headers. On that date it returns a 400, so send "booking" before then.

On the same date a booking's kind in the cart changes from "appointment" to "booking". Handle both values before then, so your storefront keeps working when it changes. A service's own kind (appointment or class) does not change.

Booking cart item

Use this for bookings ("type": "booking").

Request body

{
  "cart_item": {
    "type": "booking",
    "attributes": {
      "service_id": "9c1a2b3c-4d5e-4f60-8123-9a0b1c2d3e4f",
      "service_variant_id": "4a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
      "starts_at": "2026-03-20T08:30:00+01:00",
      "guest_count": 2,
      "preferred_staff_resource_id": "7f6e5d4c-3b2a-4c1d-9e0f-1a2b3c4d5e6f"
    }
  }
}

Attributes

AttributeTypeRequiredDescription
service_idstringYesService public ID
service_variant_idstringYesService variant public ID
starts_atstringYesISO 8601 timestamp for the slot start
guest_countintegerNoNumber of guests for this booking. Defaults to 1
preferred_staff_resource_idstringNoOptional; only meaningful if service allows customer resource preference

Guest count and shared services

The guest_count attribute controls how many guests are included in the booking. This is particularly important for shared services (e.g., a sauna session where multiple guests can book the same time slot).

  • Pricing: The cart item price is calculated as unit_price x guest_count. For example, a service variant priced at 250 NOK with guest_count: 4 results in a subtotal of 1,000 NOK.
  • Quantity: The cart item's quantity field in the response reflects the guest_count value.
  • Capacity: The guest_count must not exceed the slot's available_capacity as reported by the Service availability endpoint. If the requested guest_count exceeds available capacity, the API returns a 422.

For exclusive services (where only one booking occupies a slot), guest_count still controls pricing but the slot is fully reserved regardless of the count.

Note: The attribute name is guest_count, not participant_count. Unrecognized attributes are silently ignored, which means sending participant_count will result in a guest_count of 1.

Important

  • starts_at must correspond to a currently bookable slot from Service availability.
  • If availability changes between fetching slots and adding to cart, you may get a 422.
  • Always check the slot's available_capacity before choosing a guest_count value to avoid rejected requests.

Stay cart item

Use this for accommodation bookings (stays).

Request body

{
  "cart_item": {
    "type": "stay",
    "attributes": {
      "accommodation_id": "2f1b2d7c-6a51-4d35-9b5a-9b0c3b8efb2a",
      "check_in_date": "2026-02-01",
      "check_out_date": "2026-02-05",
      "occupancy": {
        "adults": 2,
        "children": 1,
        "infants": 0
      }
    }
  }
}

Attributes

AttributeTypeRequiredDescription
accommodation_idstringYesAccommodation public ID
check_in_datestringYesYYYY-MM-DD
check_out_datestringYesYYYY-MM-DD
occupancyobjectNoSee Types

Ticket cart item

Use this for event ticket purchases.

Request body

{
  "cart_item": {
    "type": "ticket",
    "attributes": {
      "ticket_variant_id": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7a8b",
      "quantity": 2
    }
  }
}

Attributes

AttributeTypeRequiredDescription
ticket_variant_idstringYesTicket variant public ID
quantityintegerNoDefaults to 1

Pass cart item

Use this for pass purchases (prepaid punch cards).

Request body

{
  "cart_item": {
    "type": "pass",
    "attributes": {
      "pass_product_id": "8b2c3d4e-5f60-4a71-9234-0b1c2d3e4f5a",
      "quantity": 1
    }
  }
}

Attributes

AttributeTypeRequiredDescription
pass_product_idstringYesPass public ID (from the Passes endpoint)
quantityintegerNoNumber of passes. Defaults to 1

Adding the same pass again merges into the existing cart item by increasing its quantity. Only public passes can be added — draft or private passes return a 404.

Response

On success, the API returns the updated cart:

  • Status: 201 Created
  • Body: { "cart": { ... } }

Remove item from cart

DELETE /store/v0/carts/{cart_public_id}/items/{public_id}

On success, returns the updated cart.

Removing an item that belongs to a package removes the whole package and all its items. See Cart packages.

Cart item object reference (common fields)

Cart items include a set of common fields:

FieldTypeDescription
public_idstringCart item identifier
kindstring"appointment", "stay", "ticket", or "pass"; a package can also add "product" items
titlestringDisplay title
summarystringBrief summary
quantityintegerQuantity
starts_atstringISO 8601 timestamp (when applicable)
ends_atstringISO 8601 timestamp (when applicable)
thumbnailobject | nullMedia
pricesobjectPrice breakdown
package_idstring | nullThe cart package this item belongs to

Booking fields

When kind is "appointment" ("booking" from 4 November 2026):

FieldTypeDescription
service_namestringService name
service_variant_namestringVariant name
guest_countintegerNumber of guests (determines quantity and pricing)

Stay-specific fields

When kind is "stay":

FieldTypeDescription
accommodation_namestringAccommodation name
duration_nightsintegerNights
occupancyobjectOccupancy

Ticket-specific fields

When kind is "ticket":

FieldTypeDescription
event_namestringEvent name
ticket_variant_namestringTicket variant name

Pass-specific fields

When kind is "pass":

FieldTypeDescription
pass_product_idstringPass public ID
pass_product_namestringPass name
unit_countintegerUnits per pass