# Packages

To use this capability, add `octo/packages` to your `Octo-Capabilities` header.

Packages are products that contain selectable sub-products ("includes"). You can sell package products without this capability, but enabling it exposes include-level product schema, include-aware availability, and include booking operations.

## Package Products

This capability extends product routes documented in [Products](https://docs.ventrata.com/octo-core/products):

* `GET /products`
* `GET /products/{productId}`

Each `option.packageIncludes[].includes[]` item follows the include object schema shown for product responses.

Base product schema: [Products](https://docs.ventrata.com/octo-core/products). This page documents only package additions.

## Package Availability

This capability extends availability routes documented in [Availability](https://docs.ventrata.com/octo-core/availability):

* `POST /availability`
* `POST /availability/calendar`

`/availability` responses add:

Each `packageAvailabilities[]` item is a full availability object (same fields as top-level availability) plus nested `packageAvailabilities`. `/availability/calendar` keeps the normal calendar schema and does not add `packageAvailabilities`.

Base availability schema: [Availability](https://docs.ventrata.com/octo-core/availability).

## Package Booking

This capability extends booking write routes documented in [Bookings](https://docs.ventrata.com/octo-core/bookings#endpoints):

* `POST /bookings`
* `PATCH /bookings/{uuid}`

Additional booking route variants that use the same package payload handling:

* `POST /bookings/{uuid}/confirm`

### Variant 1: Parent Booking With `packageBookings[]`

You can add include bookings while creating or updating the parent package booking by sending `packageBookings`.

Base booking schema: [Bookings](https://docs.ventrata.com/octo-core/bookings#endpoints).

### Variant 2: Direct Include Booking With `packageUuid`

You can create/update a single include booking directly by sending package context at the top level.

Base booking schema: [Bookings](https://docs.ventrata.com/octo-core/bookings#endpoints).

Booking responses include package-specific fields.

These are additive response fields on the base booking schema from [Bookings](https://docs.ventrata.com/octo-core/bookings#endpoints).

You can target include booking UUIDs on standard booking endpoints (`GET`, `PATCH`, `POST .../confirm`, `POST .../cancel`, `POST .../extend`). Always check the returned `updatable` and `cancellable` flags to determine whether a specific include booking can be changed or cancelled. In `packageBookings[]`, child rows with hidden includes (or cancellation state mismatched to the parent row) are excluded from serialization.

## Listing Include Bookings

Include bookings are returned from `GET /bookings` (base route in [Bookings](https://docs.ventrata.com/octo-core/bookings#endpoints)).

## Schema Additions (JSON)

These are additive fragments showing only fields introduced by this capability.

### `Availability`

```json
{
  "// ...rest of availability object": "...",
  "packageAvailabilities": [
    {
      "id": "9fa4425f-12ee-4cd9-8dd3-21509a7ec0c7",
      "localDateTimeStart": "2026-03-01T09:00:00-08:00",
      "localDateTimeEnd": "2026-03-01T12:00:00-08:00",
      "allDay": false,
      "available": true,
      "status": "AVAILABLE",
      "statusMessage": "Available",
      "utcCutoffAt": "2026-02-28T17:00:00Z",
      "openingHours": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "packageIncludeId": "11111111-2222-4333-8444-555555555555"
    }
  ]
}
```

### `AvailabilityBatchRow`

```json
{
  "// ...rest of availability batch row object": "...",
  "packageAvailabilities": [
    {
      "id": "9fa4425f-12ee-4cd9-8dd3-21509a7ec0c7",
      "localDateTimeStart": "2026-03-01T09:00:00-08:00",
      "localDateTimeEnd": "2026-03-01T12:00:00-08:00",
      "allDay": false,
      "available": true,
      "status": "AVAILABLE",
      "statusMessage": "Available",
      "utcCutoffAt": "2026-02-28T17:00:00Z",
      "openingHours": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "packageIncludeId": "11111111-2222-4333-8444-555555555555"
    }
  ]
}
```

### `Booking`

```json
{
  "// ...rest of booking object": "...",
  "packageUuid": "89fe0192-ddcd-430a-b285-e1396a4725d2",
  "packageIncludeId": "package_include_id-example",
  "packageUnitItemUuid": "89fe0192-ddcd-430a-b285-e1396a4725d2"
}
```

### `BookingUnitItem`

```json
{
  "// ...rest of booking unit item object": "...",
  "packageIncludeId": "package_include_id-example",
  "packageUnitItemUuid": "89fe0192-ddcd-430a-b285-e1396a4725d2"
}
```

### `Option`

```json
{
  "// ...rest of option object": "...",
  "packageIncludes": [
    {
      "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
      "title": "Summer Promotion",
      "description": "Morning departure with central pickup included.",
      "includes": [
        {
          "id": "e7cc8bb4-8d1c-4848-8824-5dbedb718681",
          "productId": "e7cc8bb4-8d1c-4848-8824-5dbedb718681",
          "optionId": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
          "required": true
        }
      ]
    }
  ]
}
```

### `PackageAvailability`

```json
{
  "// ...rest of package availability object": "...",
  "packageAvailabilities": [
    {
      "id": "9fa4425f-12ee-4cd9-8dd3-21509a7ec0c7",
      "localDateTimeStart": "2026-03-01T09:00:00-08:00",
      "localDateTimeEnd": "2026-03-01T12:00:00-08:00",
      "allDay": false,
      "available": true,
      "status": "AVAILABLE",
      "statusMessage": "Available",
      "utcCutoffAt": "2026-02-28T17:00:00Z",
      "openingHours": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "packageIncludeId": "11111111-2222-4333-8444-555555555555"
    }
  ]
}
```

### `Product`

```json
{
  "// ...rest of product object": "...",
  "isPackage": true,
  "isPackagePass": true,
  "packageProduct": true
}
```
