# Availability

The first step when making a sale is to check for availability. Note if `allowFreesale` is set to true on the product then this step is optional but it is advised you check it anyway if you can to check for closures.

Peek Pro has two main availability calls:

`POST /availability/calendar` this endpoint is highly optimized and will return a single object per day. It's designed to be queried for large date ranges and the result is used to populate an availability calendar.

`POST /octo/availability` this endpoint is slightly slower as it will return an object for each individual departure time (or day). You have to perform this step to retrieve an `availabilityId` in order to confirm a sale, so if you just want to use this endpoint and skip the calendar endpoint then that's perfectly ok.

## Availability Calendar

<mark style="color:green;">`POST`</mark> `https://octo.peek.com/integrations/octo/availability/calendar`

The availability calendar endpoint for quick retrieval of availability over a date range

#### Request Body

| Name                                                | Type    | Description                                         |
| --------------------------------------------------- | ------- | --------------------------------------------------- |
| productId<mark style="color:red;">\*</mark>         | String  | The product id                                      |
| optionId                                            | String  | The option id                                       |
| localDateStart<mark style="color:red;">\*</mark>    | String  | Start date to query for (YYYY-MM-DD)                |
| localDateEnd<mark style="color:red;">\*</mark>      | String  | End date to query for (YYYY-MM-DD)                  |
| units                                               | Array   | A list of product option units and their quantities |
| units\[].id<mark style="color:red;">\*</mark>       | String  | The unit id                                         |
| units\[].quantity<mark style="color:red;">\*</mark> | Integer | The quantity of the unit                            |

{% tabs %}
{% tab title="200: OK " %}

```javascript
[
  {
    
    "localDate": "2020-07-01",
    "status": "AVAILABLE",
    "available": true,
    "capacity": 24,
    "openingHours": [
      { "from": "09:00", "to": "12:00" },
      { "from": "15:00", "to": "18:00" }
    ]
  },
  {
    "localDate": "2020-07-02",
    "status": "CLOSED",
    "available": false,
    "capacity": null,
    "openingHours": []
  }
]

```

{% endtab %}
{% endtabs %}

The availability calendar can optionally take an array of units if you already know what they are and will automatically show availabilities as sold out if they have insufficient space.

{% code title="POST /availability/calendar" %}

```javascript
{
  "productId": "av_123",
  "optionId": "av_123",
  "localDateStart": "2020-07-01",
  "localDateEnd": "2020-07-03",
  "units": [
    { "id": "ecbdb23e-9840-4d15-b6f4-254a9ea401b2", "quantity": 2 },
    { "id": "480d0c3e-80a1-4bf2-a39b-aa06332739df", "quantity": 1 }
  ]
}
```

{% endcode %}

The response will be an array of objects, one for each day between the range given in `localDateStart` and `localDateEnd`. Each object is defined as:

| Field                 | Description                                                                                                                                                                                                                                                                                                                                                                                  |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `localDate`           | The date (in format YYYY-MM-DD)                                                                                                                                                                                                                                                                                                                                                              |
| `status`              | <p>The status of that date. Possible values are:</p><p><code>AVAILABLE</code> There are availabilities available on this date for sale.</p><p><code>SOLD\_OUT</code> This date was available but is now fully sold out.</p><p><code>LIMITED</code> This date is available but has less than 50% capacity left.</p><p><code>CLOSED</code> This date is closed and not available for sale.</p> |
| `available`           | A boolean value (true or false) indicating whether you're able to sell tickets. This is basically just an alias for: `status == 'AVAILABLE' \|\| status == 'LIMITED'`                                                                                                                                                                                                                        |
| `capacity`            | The total capacity on this day. We cannot give exact vacancies on the calendar endpoint as this endpoint is cached for speed and is only meant to give an indication.                                                                                                                                                                                                                        |
| `openingHours`        | A list of opening hours that the product is open on this day.                                                                                                                                                                                                                                                                                                                                |
| `openingHours[].from` | When this product opens (HH:MM)                                                                                                                                                                                                                                                                                                                                                              |
| `openingHours[].to`   | When this product closes (HH:MM)                                                                                                                                                                                                                                                                                                                                                             |

## Availability Check

<mark style="color:green;">`POST`</mark> `https://octo.peek.com/integrations/octo/availability`

Get final availability for a given product. If in doubt between the calendar endpoint and this one, you should use this endpoint.

#### Request Body

| Name                                                | Type    | Description                                         |
| --------------------------------------------------- | ------- | --------------------------------------------------- |
| productId<mark style="color:red;">\*</mark>         | String  | The product id                                      |
| optionId                                            | String  | The option id                                       |
| localDateStart<mark style="color:red;">\*</mark>    | String  | Start date to query for (YYYY-MM-DD)                |
| localDateEnd<mark style="color:red;">\*</mark>      | String  | End date to query for (YYYY-MM-DD)                  |
| units                                               | Array   | A list of product option units and their quantities |
| units\[].id<mark style="color:red;">\*</mark>       | String  | End date to query for (YYYY-MM-DD)                  |
| units\[].quantity<mark style="color:red;">\*</mark> | Integer | The quantity of the unit                            |

{% tabs %}
{% tab title="200: OK " %}

```javascript
[
  {
    "id": "20200701113000_720_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-01T11:30:00-08:00",
    "localDateTimeEnd": "2020-07-01T23:30:00-08:00",
    "utcCutoffAt": "2020-07-01T16:30:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  },
  {
    "id": "20200701120000_720_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-01T12:00:00-08:00",
    "localDateTimeEnd": "2020-07-02T00:00:00-08:00",
    "utcCutoffAt": "2020-07-01T17:00:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  },
  {
    "id": "20200701143000_720_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-01T14:30:00-08:00",
    "localDateTimeEnd": "2020-07-02T02:30:00-08:00",
    "utcCutoffAt": "2020-07-01T19:30:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  },
  {
    "id": "20200701150000_720_5214a9d6-5271-4958-a306-14a07e4084c6",,
    "localDateTimeStart": "2020-07-01T15:00:00-08:00",
    "localDateTimeEnd": "2020-07-02T03:00:00-08:00",
    "utcCutoffAt": "2020-07-01T20:00:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  }
]
```

{% endtab %}
{% endtabs %}

The availability calendar can optionally take an array of units if you already know what they are and will automatically show availabilities as sold out if they have insufficient space.

{% code title="POST /availability" %}

```javascript
{
  "productId": "av_123",
  "optionId": "av_123",
  "localDateStart": "2020-07-01",
  "localDateEnd": "2020-07-03",
  "units": [
    { "id": "ecbdb23e-9840-4d15-b6f4-254a9ea401b2", "quantity": 2 },
    { "id": "480d0c3e-80a1-4bf2-a39b-aa06332739df", "quantity": 1 }
  ]
}
```

{% endcode %}

The response will be an array of availability objects which are defined below:

| Field                | Description                                                                                                                                                                                                                                                                                                                                                    |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                 | The availability id, you'll need this when booking                                                                                                                                                                                                                                                                                                             |
| `localDateTimeStart` | The start time for this availability. This will be in the local time zone to the product.                                                                                                                                                                                                                                                                      |
| `localDateTimeEnd`   | The end time for this availability. This will be in the local time zone to the product.                                                                                                                                                                                                                                                                        |
| `allDay`             | A boolean field indicating whether this is an all day availability and not a fixed departure time. If this value is true then there will be no other availability object on the same day.                                                                                                                                                                      |
| `status`             | <p>The status of that date. Possible values are:</p><p><code>AVAILABLE</code> This availability is available for sale</p><p><code>FREESALE</code> This availability has no capacity and is available.</p><p><code>SOLD\_OUT</code> This availability is not</p><p><code>LIMITED</code> This availability is available but has less than 50% capacity left.</p> |

Depending on the value of `product.availabilityType` the response will keep the same structure but will generally look slightly different. We've provided examples of that below:

{% tabs %}
{% tab title="OPENING\_HOURS" %}
Products with this availability type are typically Museums, Attractions or Hop on Hop off tours where the guest just picks a date they wish to travel and can show up at any point whilst the product is open.

This is a typical response from a product with `OPENING_HOURS` availability type:

```javascript
[
  {
    "id": "20200701120000_1440_ecbdb23e-9840-4d15-b6f4-254a9ea401b2",
    "localDateTimeStart": "2020-07-01T00:00:00-08:00",
    "localDateTimeEnd": "2020-07-01T23:59:59-08:00",
    "utcCutoffAt": "2020-07-01T05:00:00Z",
    "allDay": true,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": null,
    "capacity": null,
    "maxUnits": null,
    "openingHours": [
      { "from": "09:00", "to": "12:00" },
      { "from": "15:00", "to": "18:00" }
    ]
  },
  {
    "id": "20200702120000_1440_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-02T12:00:00-08:00",
    "localDateTimeEnd": "2020-07-02T23:59:59-08:00",
    "utcCutoffAt": "2020-07-02T05:00:00Z",
    "allDay": true,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": null,
    "capacity": null,
    "maxUnits": null,
    "openingHours": [
      { "from": "09:00", "to": "12:00" },
      { "from": "15:00", "to": "18:00" }
    ]
  },
  {
    "id": "20200703120000_1440_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-03T12:00:00-08:00",
    "localDateTimeEnd": "2020-07-03T23:59:59-08:00",
    "utcCutoffAt": "2020-07-03T05:00:00Z",
    "allDay": true,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": null,
    "capacity": null,
    "maxUnits": null,
    "openingHours": [
      { "from": "09:00", "to": "12:00" },
      { "from": "15:00", "to": "18:00" }
    ]
  }
]
```

Notice how vacancies, capacity and max units are all null indicating unlimited, and the allDay flag is set true. You should just render this as a calendar with no further times to chose from once the guest has chosen the date.
{% endtab %}

{% tab title="START\_TIME" %}
Products with this availability type are typically walking tours, day trips and other activities where the guest has to book onto a specific departure time. There may be just one or multiple throughout the day.

This is a typical response from a product with `START_TIME` availability type:

```javascript
[
  {
    "id": "20200701113000_720_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-01T11:30:00-08:00",
    "localDateTimeEnd": "2020-07-01T23:30:00-08:00",
    "utcCutoffAt": "2020-07-01T16:30:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  },
  {
    "id": "20200701120000_720_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-01T12:00:00-08:00",
    "localDateTimeEnd": "2020-07-02T00:00:00-08:00",
    "utcCutoffAt": "2020-07-01T17:00:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  },
  {
    "id": "20200701143000_720_5214a9d6-5271-4958-a306-14a07e4084c6",
    "localDateTimeStart": "2020-07-01T14:30:00-08:00",
    "localDateTimeEnd": "2020-07-02T02:30:00-08:00",
    "utcCutoffAt": "2020-07-01T19:30:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  },
  {
    "id": "20200701150000_720_5214a9d6-5271-4958-a306-14a07e4084c6",,
    "localDateTimeStart": "2020-07-01T15:00:00-08:00",
    "localDateTimeEnd": "2020-07-02T03:00:00-08:00",
    "utcCutoffAt": "2020-07-01T20:00:00Z",
    "allDay": false,
    "status": "AVAILABLE",
    "available": true,
    "vacancies": 24,
    "capacity": 24,
    "maxUnits": 24,
    "openingHours": []
  }
]
```

These are all availabilities for the same day. Once the guest has chosen the date (in this example `2020-07-01` then they must then pick a departure time. Again in this example the departure times would be:

* 11:00 AM
* 12:00 PM
* 2:30 PM
* 3:00 PM
  {% endtab %}
  {% endtabs %}

{% hint style="info" %}
Unlike the calendar endpoint, the availability check endpoint will not return an availability object if the product is closed. If there are no availabilities for a given date you should just mark it as closed in your interface.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://octodocs.peek.com/booking-flow/availability.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
