Booking Questions (v1.3)

v1.3

Some products require specific guest information before a booking can be confirmed. The Booking Questions capability provides a structured, typed mechanism for collecting this data - with localized question text, dependency rules, PII flags, and clearly defined phases for when answers must be submitted.

🔗 Find the full details here: Reseller API Reference

Info

v1.2 partners: Booking Questions is a v1.3 only capability. Your existing integration is unaffected. You can adopt it at any time by switching to the /v1.3/ base path.

Where Questions Come From

Booking Questions are returned as part of the Rate object. To retrieve Booking Questions, you must use the bookingQuestions=true query parameter.

If the Rate has associated questions, the response includes a bookingQuestions[] array. Always check for this array when building checkout flows. Questions can be added to a Rate by the Supplier at any time, so do not assume a Rate has no questions based on past behavior.

Filtering by Language

Add the locale= parameter to return only text in specific languages. Accepts a comma-separated list of BCP 47 language tags:

GET /v1.3/suppliers/{id}/products/{id}bookingQuestions=true&locale=en-US,es-ES,de-DE

If locale= is omitted, all available language variants are returned.

LocalizedTextSet

Content fields use the LocalizedTextSet pattern to support multi-lingual and multi-format content.

Field

Format

Description

text

string

The content string

format

enum

The content format. Allowed values: plaintext, html, markdown

locale

string

This MUST be a valid BCP 47 RFC 5646 RFC 4647 language tag

LocalizedText

Represents a single text entry in a specific language and format. If a supplier provides this object, all its internal fields (text, format, and locale) are mandatory.

LocalizedTextSet

A collection of LocalizedText objects. While a set can contain multiple entries to accommodate various locales and formats, each locale + format combination must be unique within a single LocalizedTextSet. The system will reject duplicate combinations from the Supplier side.

"description": [ { "text": "Join us for a 3-hour kayaking tour around the Barcelona coastline.", "locale": "en", "format": "plain" }, { "text": "Únete a nosotros para un recorrido en kayak de 3 horas por la costa de Barcelona.", "locale": "es", "format": "plain" } ]

Booking Questions Object Field

Field

Type

Description

Notes

id

string

Unique question identifier

Required to be populated by the Supplier if bookingQuestions is provided.

type

string(enum) AnswerType

Data type of the expected answer (see table below)

Required to be populated by the Supplier if bookingQuestions is provided.

text

LocalizedTextSet

The question text to display to the guest

Required to be populated by the Supplier if bookingQuestions is provided.

required

boolean

If true, the question must be answered, or the hold/booking request might fail

Required to be populated by the Supplier if bookingQuestions is provided.

pii

boolean

If true, the answer contains Personally Identifiable Information

Required to be populated by the Supplier if bookingQuestions is provided.

scope

QuestionScope

booking or guest - who the answer applies to, the entire booking or peer guest

Required to be populated by the Supplier if bookingQuestions is provided.

phase

AnswerPhase

hold or booking - when the answer must be submitted

Required to be populated by the Supplier if bookingQuestions is provided.

options[]

AnswerOption[]

Predefined choices for choice and multiple_choice question types

Optional for the Supplier to populate.

constraints[]

Constraints[]

Validation rules applied to the answer

Optional for the Supplier to populate.

dependency

BookingQuestionDependency

Makes this question conditional on another question's answer

Optional for the Supplier to populate.

Answer Types

Type

Description

Example

text

Free-form string

"Window seat preferred"

email

Valid email address

"jane@example.com"

phone

Phone number

"+1 212 555 0100"

integer

Whole number

"3"

decimal

Decimal number

"52.5"

boolean

true or false

"true"

choice

Single selection from options[]

The answer value of the chosen AnswerOption

multiple_choice

Multiple selections from options[]

Array of answer values

date

Date value

"2026-06-20"

time

Time value

"09:00:00"

datetime

Date and time

"2026-06-20T09:00:00"

For choice and multiple_choice types, use the answer value from the matching AnswerOption - not the display label. The label is for rendering to the guest; the answer is what you submit.

Scope

scope defines who an answer applies to:

Value

Meaning

Where to submit

booking

One answer covers the entire booking

At the top-level answers[] array of the Hold or Booking request

guest

One answer is required per traveler

Inside each traveler's context within items[]

For scope guest, collect a separate answer for each traveler in the booking and submit them individually. A common example is dietary requirements or passport details, which differ per guest.

Phase

phase defines when an answer must be submitted:

Value

Meaning

Where to submit

hold

The answer is needed to commit inventory

Hold request

booking

The answer is needed at purchase confirmation

Booking request

hold-phase questions are typically used when the answer affects what inventory is reserved, for example, a meal choice that determines which catering block is allocated. booking-phase questions are for information that only needs to be finalized at the time of purchase, for example, a transfer preference or a language selection.

Conditional Questions

A question may carry a dependency field that makes it conditional on another question's answer. Only render and submit a dependent question when its condition is satisfied.

"dependency": { "questionId": "q_001", "answer": true }

This means: only show this question if question q_001 has been answered with true. If the condition is not met, do not include the question's questionId in the answers array.

Dependencies only reference one level - a question depends on at most one other question. Check whether the referenced question is itself conditional before assuming it will always be present.

PII Handling

Questions with pii: true collect Personally Identifiable Information, for example, passport numbers, birth dates, physical measurements, or health data. Apply the following when handling PII answers:

  • Do not log PII values in application or server logs

  • Do not cache PII answers beyond what is operationally required to complete the booking

  • Store PII in compliance with your applicable data privacy regulations (GDPR, CCPA, or equivalent)

  • Treat PII fields in your internal data model with appropriate access controls

Submitting Answers

Answers are submitted as an answers[] array, a list of { questionId, answer } pairs. Include this array in the Hold or Booking request body, depending on each question's phase.

In the Hold Request (phase: hold)

POST /v1.3/holds { "hold": { "id": "f7393cf6-097d-443a-919a-ae3ca518e040", "partnerId": "your-partner-id", "items": [...], "answers": [ { "questionId": "q_123", "answer": "Window seat" }, { "questionId": "q_456", "answer": true }, { "questionId": "q_789", "answer": "2026-06-20" } ] } }

Required hold-phase questions (required: true) will cause the Hold request to fail if omitted.

Optional questions (required: false) should still be rendered and offered to the guest - omit them from the payload only if the guest left them blank.

In the Booking Request (phase: booking)

POST /v1.3/bookings { "booking": { "holdId": "f7393cf6-097d-443a-919a-ae3ca518e040", "customer": {...}, "items": [...], "answers": [ { "questionId": "q_101", "answer": "Gluten-free" }, { "questionId": "q_102", "answer": "Spanish" } ] } }

Required booking-phase questions will cause the Booking request to fail if omitted.

Guest-Scoped Answers (scope: guest)

For questions with scope: guest, submit one answer per traveler. The exact structure for guest-scoped answers depends on the Supplier integration - refer to the API Reference for the traveler-level answer placement specific to your Supplier's configuration.

Full Example Flow

  1. GET /rates/{id} → Rate response includes bookingQuestions[]

  2. Review questions:

  • q_001: scope=booking, phase=hold, type=boolean, required=true

    • text: "Do you require a vegetarian meal?"

  • q_002: scope=booking, phase=hold, type=choice, required=false

    • text: "If yes, which preference?"

    • dependency: { questionId: "q_001", answer: true }

    • options:

      • { label: "Vegan", answer: "vegan" },

      • { label: "Lacto-vegetarian", answer: "lacto" }

  • q_003: scope=guest, phase=booking, type=text, required=true, pii=true

    • text: "Passport number"

  1. POST /holds → answers:

  • { questionId: "q_001", answer: true },

  • { questionId: "q_002", answer: "vegan" } (q_003 is phase=booking, so omit from Hold)

  1. POST /bookings → answers:

  • { questionId: "q_003", answer: "AB1234567" } (per traveler, if scope=guest)