# Memberships

This capability allows member benefits to be redeemed when making new bookings.

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

All paths below are public `/octo` routes.

## Member Login

First, provide a member login entry point in your interface (for example a "Member Login" button) and collect one of the following identifiers:

* **Email** We send a verification code to the customer's email, and you repeat that code in a follow-up request to verify identity.
* **Mobile** We send a verification code to the customer's mobile number, and you repeat that code in a follow-up request to verify identity.
* **Reference** If a booking exists, we ask for the customer's last name to verify identity.

{% openapi src="<https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media>" path="/memberships/lookup" method="post" %}
[openapi.yaml](https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media)
{% endopenapi %}

**Request Body / Query Parameters**

You should send either `email`, `mobile`, or `reference`. If using `reference`, it must be at least 3 characters.

See the lookup operation above for request/response schemas.

The response returns `400 Bad Request` if no memberships are found. Otherwise, it returns a message with `"verified": false`; prompt for the verification code and repeat the request with that value.

For `reference`, the verification value is the guest's last name. For `email` and `mobile`, the verification value is a 6-digit code sent to the provided email address or mobile number.

Once you repeat the request, including the `verification` field with the verification code, it will verify the member and return a list of memberships that they have.

If multiple memberships are returned, provide an interface to pick one, using `title` and/or `contact` to differentiate between them.

## Membership Object For Requests

After lookup, include a `membership` object on membership-aware requests (or `membership[...]` query parameters for `GET` endpoints).

`membership[id]` is required.

Also include one of `membership[email]`, `membership[mobile]`, or `membership[reference]`, together with `membership[verification]`.

If using `membership[mobile]`, include `membership[country]`.

## Product Benefits

Memberships can have multiple benefits. Once you have logged in and selected a membership, include a membership object in each request.

Product benefits are returned on base product routes:

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

Call the product endpoint and include the membership object as query parameters.

You should repeat the same identifier (`email`, `mobile` or `reference`) and `verification` from the login step, and include `id` to specify which membership to apply.

Base product schema: [Products](https://docs.ventrata.com/octo-core/products).

Memberships with product benefits add additional units to the list. You can identify units that belong to a membership benefit via the `membershipBenefit` object, which is otherwise `null`.

If you're rendering this on a page showing the available units to choose from, we recommend grouping units by `membershipBenefit.id` and displaying those units in a highlighted box.

Units with `"membershipBenefit": null` should go at the end as they are now, these are the regular units that weren't made available with the membership.

Include these units in the `unitItems` array as normal, ensuring you also include the `membership` object in the booking request.

When a membership unit benefit has limits, `unit.restrictions.maxQuantity` will be reduced to the lowest effective limit.

{% openapi src="<https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media>" path="/memberships/bookings" method="get" %}
[openapi.yaml](https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media)
{% endopenapi %}

Returns bookings linked to the selected membership.

**Query Parameters**

The `membership` object is required on this endpoint. Include `membership[id]`, one lookup identifier (`membership[email]`, `membership[mobile]` or `membership[reference]`), and `membership[verification]`.

## Offers Benefits

Memberships also provide discounts on availability when using the `octo/offers` capability.

When this is used alongside `octo/offers`, a `membershipBenefit` field is added to the offer object:

`offer.membershipBenefit` uses the same fields as `unit.membershipBenefit` (`id`, `title`, `description`).

No additional action is required to select this offer. It is applied automatically, just like an entered `offerCode` or a public promotion. If `offer.membershipBenefit` is set, display `membershipBenefit.title/description` in place of `offer.title/description` wherever you show offer text.

## Booking / Order

Finally, when creating the booking or order (if you're using the `octo/cart` capability), include the membership object as in the steps above.

Membership-related request fields are included on the operations in this section.

This will associate the booking to the membership and automatically apply any benefits available.

Membership-related response fields are returned on the same operations.

When bookings are nested inside an order response, the membership summary is returned on the order object (`order.membership`) and omitted from each nested booking item.

## Schema Additions (JSON)

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

### `AvailabilityBatchRequest`

```json
{
  "// ...rest of availability batch request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  }
}
```

### `AvailabilityCalendarBatchRequest`

```json
{
  "// ...rest of availability calendar batch request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  }
}
```

### `AvailabilityCalendarRequest`

```json
{
  "// ...rest of availability calendar request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  }
}
```

### `AvailabilityRequest`

```json
{
  "// ...rest of availability request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  }
}
```

### `Booking`

```json
{
  "// ...rest of booking object": "...",
  "membership": {
    "id": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
    "title": "Annual Membership",
    "contact": {
      "firstName": "Jane",
      "lastName": "Doe",
      "emailAddress": "jane.doe@goldengatetours.com",
      "phoneNumber": "+12025550123",
      "country": "US"
    },
    "reference": "REF-2026-001",
    "resellerReference": "RES-MEM-10045",
    "supplierReference": "SUP-MEM-7782",
    "availabilityLocalDateStart": "2026-01-01",
    "availabilityLocalDateEnd": "2026-12-31"
  },
  "appendMembershipValidity": true
}
```

### `BookingWriteRequest`

```json
{
  "// ...rest of booking write request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  },
  "appendMembershipValidity": true
}
```

### `Gift`

```json
{
  "// ...rest of gift object": "...",
  "membership": {
    "id": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
    "title": "Annual Membership",
    "contact": {
      "firstName": "Jane",
      "lastName": "Doe",
      "emailAddress": "jane.doe@goldengatetours.com",
      "phoneNumber": "+12025550123",
      "country": "US"
    },
    "reference": "MEM-2026-001",
    "resellerReference": "RES-MEM-10045",
    "supplierReference": "SUP-MEM-7782",
    "availabilityLocalDateStart": "2026-01-01",
    "availabilityLocalDateEnd": "2026-12-31"
  }
}
```

### `GiftCreateRequest`

```json
{
  "// ...rest of gift create request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  }
}
```

### `Offer`

```json
{
  "// ...rest of offer object": "...",
  "membershipBenefit": {
    "id": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
    "title": "VIP Member Discount",
    "description": "Reduced pricing for active members."
  }
}
```

### `Order`

```json
{
  "// ...rest of order object": "...",
  "membership": {
    "id": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
    "title": "Annual Membership",
    "contact": {
      "firstName": "Jane",
      "lastName": "Doe",
      "emailAddress": "jane.doe@goldengatetours.com",
      "phoneNumber": "+12025550123",
      "country": "US"
    },
    "reference": "MEM-2026-001",
    "resellerReference": "RES-MEM-10045",
    "supplierReference": "SUP-MEM-7782",
    "availabilityLocalDateStart": "2026-01-01",
    "availabilityLocalDateEnd": "2026-12-31"
  }
}
```

### `OrderCreateRequest`

```json
{
  "// ...rest of order create request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  }
}
```

### `OrderUpdateRequest`

```json
{
  "// ...rest of order update request object": "...",
  "membership": {
    "id": "89fe0192-ddcd-430a-b285-e1396a4725d2",
    "email": "jane.doe@goldengatetours.com",
    "verification": "123456"
  }
}
```

### `Product`

```json
{
  "// ...rest of product object": "...",
  "isMembership": true,
  "membershipAutoRenew": true
}
```

### `Unit`

```json
{
  "// ...rest of unit object": "...",
  "membershipBenefit": {
    "id": "f1a5d2e8-8d57-4f0b-9c3f-6a12d7a8bc90",
    "title": "VIP Member Discount",
    "description": "Reduced pricing for active members."
  },
  "isMembership": true
}
```
