Booking questions
The booking questions feature facilitates the collection of additional traveler details
Early access preview
This documentation is part of an early access preview initiative for selected partners only. Beta programs will launch in Q3 2026, with general availability in 2027.
If you are interested in becoming a beta partner, please reach out to your account manager.
Overview
The booking questions feature enables the collection of additional traveler data (e.g. height, weight, travel document information, dietary restrictions, etc.) in a flexible, type-safe manner.
Key benefits
- Flexible: Add new data types without API versioning
- Type-safe: JSON schema ensures correct structure
- Discoverable: Ability to query available types via a catalog endpoint
- Filtered: You only see activities you can support
- Localized: Questions support multiple languages
Document glossary
- Solution architecture
Core concepts, generic data type models, activity requirements, partner capabilities, and structured answer submission. - API endpoints
The data types catalog, activity filtering, and Price Check endpoints that expose booking questions. - Conditional questions
How parent/child questions work and the operators that drive show/hide logic. - Integration flow
End-to-end steps from discovery through booking submission. - Data type example
A sample data type showing its schema definition and answer structure. - Localization
How questions and options are returned in multiple languages while keeping IDs constant. - Validation
Client-side and server-side validation rules and the error response format.
Solution architecture
Core concepts
Generic data type models
Reusable data type models represent categories of information (more can be added when needed), e.g. measurement, selection, address, and phone.
>> Find out more about data type models
For the full catalog of data-types call GET /experiences/booking-questions/data-types
Activity requirements
Activities declare which data types they require through booking questions, specifying:
- Unique string ID for the question
- Question text (localized)
- Description of the question text (localized)
- Data type reference
- Whether it applies per-traveler or per-booking
- Validation constraints (min/max values, lengths, etc.)
- Which ticket(s) it applies to
- Defines the child question for a given parent
- Optional conditional logic (questions that depend on other answers)
Partner capabilities
You declare which data types you support using the supported_booking_data_types filter parameter on the search/content endpoints. This filters activities to only show those you can handle.
- To handle any type dynamically, send
supported_booking_data_types=*. - To support no booking questions, send
supported_booking_data_types=none.
Structured answer submission
Answers are nested appropriately:
- Per-traveler answers — In the
booking_question_answersarray on each traveler object. - Per-booking answers — In the
booking_question_answersarray at the booking level.
API endpoints
Get data types catalog
Endpoint: GET /experiences/booking-questions/data-types
Query Parameters: ?date_updated_start
>> See the Integration Flow: Step 1 for usage
Purpose: Returns a technical reference catalog of all available data type models.
Example request:
GET /experiences/booking-questions/data-typesExample response:
[
{
"date_added": "2026-07-14T11:30:08.104575+02:00",
"date_updated": "2026-07-14T11:30:08.104575+02:00",
"description": "Used for collecting any measurement with a numeric value and unit. Common examples include height (in/cm/foot/meter), weight (lb/kg/stone), shoe size (us_men/us_women/eu/uk/cm), helmet size (in/cm), waist size (in/cm), and chest size (in/cm). The allowed_units field specifies which units are valid for this measurement.",
"name": "Measurement",
"schema_definition": {
"properties": {
"unit": {
"description": "Unit of measurement - must be one of the allowed_options specified for the question",
"type": "string"
},
"value": {
"description": "Numeric value as string to preserve precision",
"pattern": "^[0-9]+(\\.[0-9]+)?$",
"type": "string"
}
},
"required": [
"value",
"unit"
],
"type": "object"
},
"type": "measurement"
},
]Activity filtering
Query Parameter: supported_booking_data_types
Applies to: /experiences/activities/content and /experiences/activities/availability endpoints
Purpose: Filters results to only include activities whose required questions use the specified data types.
Example:
GET /experiences/activities/content
?activity_id=123&activity_id=456
&language=en-US
&supported_booking_data_types=measurement
&supported_booking_data_types=selection
&supported_booking_data_types=text- To handle all types and show all activities, use
supported_booking_data_types=*. You are then responsible for handling all question types in Price Check and Booking. - To handle no booking questions use
supported_booking_data_types=none. This will return only activities where there are no booking questions.
Price Check (includes booking questions)
Endpoint: GET /experiences/activities/{activity_id}/price-check
Purpose: Performs a price check and returns booking questions (if any) for the activity.
Example request:
GET /experiences/activities/12345/price-check?token=abc123&tickets=...Example response:
{
"status": "available",
"offer_pricing": {
"total": {
"value": "150.00",
"currency": "USD"
}
},
"booking_questions": [
{
"id": "height_1",
"type": "measurement",
"question": "What is your height?",
"description": "Required for safety equipment fitting",
"applies_to": "per_traveler",
"ticket_ids": ["12346","12345"]
"allowed_options": [
{ "id": "in", "label": "in" },
{ "id": "cm", "label": "cm" }
]
},
{
"id": "weight_1",
"type": "measurement",
"question": "What is your weight?",
"description": "Required for zipline weight limits",
"applies_to": "per_traveler",
"ticket_ids": ["12346","12345"]
"allowed_options": [
{ "id": "lb", "label": "lb" },
{ "id": "kg", "label": "kg" }
]
}
],
"links": {
"create": {
"method": "POST",
"href": "/itineraries/activity"
}
}
}Note: If you filtered activities using supported_booking_data_types in your earlier search/content calls, all returned questions will use data types you support.
Conditional questions
Questions can be conditional based on answers to previous questions. This is useful for collecting different information based on user choices.
How it works
- Parent question — A question (typically a
selectiontype) whose answer determines what follows. - Child questions — Questions with a
conditionalfield that references the parent. - Bidirectional relationship — The parent lists children in its
childrenarray; children reference the parent with full conditional logic.
Example: Contact method selection
Parent question:
{
"id": "contact_method_1",
"type": "selection",
"question": "How would you prefer to be contacted?",
"applies_to": "per_traveler",
"ticket_ids": ["12346","12345"]
"children": ["contact_phone_1", "contact_whatsapp_1", "contact_email_1"],
"allow_multiple": false,
"allowed_options": [
{ "id": "phone", "label": "Phone Call" },
{ "id": "whatsapp", "label": "WhatsApp" },
{ "id": "email", "label": "Email" },
{ "id": "no_contact", "label": "No Contact" }
]
}Conditional child questions:
[
{
"id": "contact_phone_1",
"type": "phone",
"question": "What is your phone number?",
"applies_to": "per_traveler",
"conditional": {
"parent_question_id": "contact_method_1",
"show_when": {
"operator": "equals",
"field": "selected",
"values": ["phone"]
}
}
},
{
"id": "contact_whatsapp_1",
"type": "text",
"question": "What is your WhatsApp username?",
"applies_to": "per_traveler",
"conditional": {
"parent_question_id": "contact_method_1",
"show_when": {
"operator": "equals",
"field": "selected",
"values": ["whatsapp"]
}
}
},
{
"id": "contact_email_1",
"type": "email",
"question": "What is your email address?",
"applies_to": "per_traveler",
"conditional": {
"parent_question_id": "contact_method_1",
"show_when": {
"operator": "equals",
"field": "selected",
"values": ["email"]
}
}
}
]Conditional operators
| Operator | Meaning |
|---|---|
contains | Field contains any of the specified values |
equals | Field exactly matches any of the specified values |
not_contains | Field does not contain any of the specified values |
not_equals | Field does not match any of the specified values |
Integration flow
Step 1: Discovery phase
Call the data types catalog to determine which types can be supported:
GET /experiences/booking-questions/data-types?date_updated_start=2026-02-01If date_updated_start is provided, only data types that have been added on or after the given date are returned.
Step 2: Search with filtering
Filter activities to only show those with compatible questions:
GET /experiences/activities/content
?activity_id=123&activity_id=456&activity_id=789
&language=en-US
&supported_booking_data_types=measurement
&supported_booking_data_types=selection
&supported_booking_data_types=textThis filters results to only include activities whose required questions use the specified data types.
Step 3: Price check
During price check, you receive booking questions in the response:
GET /experiences/activities/12345/price-check?token=abc123&tickets=...The response includes a booking_questions array (if any). All questions use data types from your filter.
Step 4: Collect answers
Build UI to collect answers:
- Render an appropriate input for each data type
- Validate client-side using the schema from the data types catalog
- For per-traveler questions, collect answers for each traveler
- For per-booking questions, collect once
- Handle conditional questions (show/hide based on parent answers)
Step 5: Submit booking
Submit answers with the booking request:
POST /itineraries/activity{
"primary_traveler": [
{
"given_name": "John",
"family_name": "Doe",
"booking_question_answers": [
{
"question_id": "height_1",
"answer": {
"value": "72",
"unit": "in"
}
},
{
"question_id": "weight_1",
"answer": {
"value": "180",
"unit": "lb"
}
}
]
}
],
"booking_question_answers": [
{
"question_id": "emergency_contact_1",
"answer": {
"value": "Jane Doe, +1-555-1234"
}
}
]
}Data type example
Size (dimensional measurements)
Schema Definition:
{
"type": "object",
"required": ["value", "unit"],
"properties": {
"value": {
"type": "string",
"pattern": "^[0-9]+(\\.[0-9]+)?$"
},
"unit": {
"type": "string"
}
}
}Answer example:
{
"value": "72",
"unit": "in"
}Localization
Questions support multiple languages through the language parameter on Price Check.
English example:
GET /experiences/activities/12345/price-check?token=...&language=en-US{
"id": "dietary_1",
"type": "selection",
"question": "Dietary preferences (optional)",
"description": "Please share any dietary restrictions or allergies."
"applies_to": "per_traveler",
"allow_multiple": false
"ticket_ids": ["12345", "12346"]
"options": [
{ "id": "vegetarian", "label": "Vegetarian" },
{ "id": "vegan", "label": "Vegan" }
]
}Spanish example:
Same question with language=es-ES.
GET /experiences/activities/12345/price-check?token=...&language=es-ES{
"id": "dietary_1",
"type": "selection",
"question": "Preferencias alimentarias (opcional)",
"description": "Por favor, indica las restricciones alimentarias o alergias. "
"applies_to": "per_traveler",
"allow_multiple": false
"ticket_ids": ["12345", "12346"]
"options": [
{ "id": "vegetarian", "label": "Vegetariano" },
{ "id": "vegan", "label": "Vegano" }
]
}Note: Question IDs and option IDs remain constant across languages for consistent answer submission.
Validation
Client-side validation
Partners should validate answers client-side using the schema from the data types catalog to ensure the correct structure.
Server-side validation
The booking endpoint validates that:
- All required questions have answers
- Answer structure matches the data type schema
- Values meet validation constraints
- Conditional questions are answered appropriately
- Per-traveler questions are provided for each traveler
- Per-booking questions are provided once
Error response
{
"type": "validation_failed",
"message": "One or more booking question answers are invalid",
"errors": [
{
"type": "missing_required_answer",
"message": "Required question 'height_1' not answered for traveler 1",
"fields": [
{
"path": "$.travelers[0].booking_question_answers",
"value": null
}
]
}
]
}