# Custom Questions

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

Custom questions let you collect additional guest information during booking and order flows. These questions are informational and do not change availability or pricing.

{% hint style="info" %}
Operations below use the `/octo` prefix.
{% endhint %}

## Question Definitions

Supported product routes:

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

With this capability enabled, question definitions are added to option and unit schemas in product responses.

Questions are sorted by configured question position.

The same `questions` arrays are also returned on:

* `booking.option.questions[]`
* `booking.option.units[].questions[]`
* `booking.unitItems[].unit.questions[]`
* The same nested booking paths under `order.bookings[]`

### Question Object Fields

`inputType` is derived from options:

* `textarea`: no options
* `radio`: 1-5 options
* `select`: more than 5 options

Question objects are returned in the product and booking/order schemas from [Products](https://docs.ventrata.com/octo-core/products), [Bookings](https://docs.ventrata.com/octo-core/bookings#endpoints), and [Multi-Booking Cart](https://docs.ventrata.com/capabilities/cart).

You should display booking-level questions once per booking, and ticket-level questions once per unit item.

Submit question answers before or on your final booking/order confirmation call so they are persisted with the confirmed records.

## Submit Answers On Booking Routes

Booking question fields are supported by these booking write routes:

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

### Request Body Fields

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

## Submit Answers On Order Routes (`octo/cart` Required)

To submit order-level question answers, include both capabilities in the header:

* `octo/questions`
* `octo/cart`

Order question fields are supported by:

* `POST /orders`
* `PATCH /orders/{orderId}`
* `PATCH /orders/{orderId}/preview`
* `POST /orders/{orderId}/confirm`

## Returned Answer Fields

Booking objects include question answers on these routes:

* `POST /bookings`
* `PATCH /bookings/{uuid}`
* `POST /bookings/{uuid}/confirm`
* `POST /bookings/{uuid}/extend`
* `POST /bookings/{uuid}/cancel`
* `GET /bookings`
* `GET /bookings/{uuid}`

Order objects include question answers on these routes (`octo/cart` required):

* `POST /orders`
* `PATCH /orders/{orderId}`
* `PATCH /orders/{orderId}/preview`
* `POST /orders/{orderId}/confirm`
* `POST /orders/{orderId}/extend`
* `POST /orders/{orderId}/cancel`
* `DELETE /orders/{orderId}`
* `GET /orders`
* `GET /orders/{orderId}`

Each answer object field is included in the booking and order schemas.

Base schemas: [Bookings](https://docs.ventrata.com/octo-core/bookings#endpoints) and [Multi-Booking Cart](https://docs.ventrata.com/capabilities/cart).

`questionAnswers` arrays are returned in question position order and include all currently valid questions for that object, plus any existing persisted answers that are still attached.

{% hint style="info" %}
On update routes, omitting `questionAnswers` leaves existing answers unchanged.
{% endhint %}

{% hint style="info" %}
To clear an existing answer, send the same `questionId` with `value: null` (or empty string) in the relevant `questionAnswers` array.
{% endhint %}

{% hint style="info" %}
If a submitted `questionId` is unknown for that scope (`order`, `booking`, or `ticket`), the API returns `INVALID_QUESTION_ID` and includes `questionId` in the error body.
{% endhint %}

**Recommended flow:** create or fetch the booking/order first, then render your form from `questionAnswers` (and `unitItems[].questionAnswers` for unit items). Unanswered questions are returned with `value: null`.

## Schema Additions (JSON)

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

### `Booking`

```json
{
  "// ...rest of booking object": "...",
  "questionAnswers": [
    {
      "questionId": "question_dietary_requirements",
      "value": "Vegetarian"
    }
  ]
}
```

### `BookingUnitItem`

```json
{
  "// ...rest of booking unit item object": "...",
  "questionAnswers": [
    {
      "questionId": "question_dietary_requirements",
      "value": "Vegetarian"
    }
  ]
}
```

### `BookingUnitItemWriteRequest`

```json
{
  "// ...rest of booking unit item write request object": "...",
  "questionAnswers": [
    {
      "questionId": "question_dietary_requirements",
      "value": "Vegetarian"
    }
  ]
}
```

### `BookingWriteRequest`

```json
{
  "// ...rest of booking write request object": "...",
  "questionAnswers": [
    {
      "questionId": "question_dietary_requirements",
      "value": "Vegetarian"
    }
  ]
}
```

### `Option`

```json
{
  "// ...rest of option object": "...",
  "questions": [
    {
      "id": "3d6f0a3a-59d4-4b16-a0c5-11d2d8a4e6b7",
      "title": "Summer Promotion",
      "required": true,
      "inputType": "select"
    }
  ]
}
```

### `Order`

```json
{
  "// ...rest of order object": "...",
  "questionAnswers": [
    {
      "questionId": "question_dietary_requirements",
      "value": "Vegetarian"
    }
  ]
}
```

### `OrderCreateRequest`

```json
{
  "// ...rest of order create request object": "...",
  "questionAnswers": [
    {
      "questionId": "question_dietary_requirements",
      "value": "Vegetarian"
    }
  ]
}
```

### `OrderUpdateRequest`

```json
{
  "// ...rest of order update request object": "...",
  "questionAnswers": [
    {
      "questionId": "question_dietary_requirements",
      "value": "Vegetarian"
    }
  ]
}
```

### `Unit`

```json
{
  "// ...rest of unit object": "...",
  "questions": [
    {
      "id": "3d6f0a3a-59d4-4b16-a0c5-11d2d8a4e6b7",
      "title": "Summer Promotion",
      "required": true,
      "inputType": "select"
    }
  ]
}
```
