5. Questions#
In this step, the flow retrieves the information required to progress a booking to confirmation (billing, contact, and activity requirements), and updates the booking with the traveler answers.
getQuestions#
Given the booking ID, retrieves the list of questions to be answered for the booking to be confirmable. The questions are divided in questions about the customer (under the optional customer property), relative to the booking ( under the optional booking property) or questions about the participants (under the optional participants property).
Path
GET /booking-flow/v1/bookings/:bookingId/questions
Input body example
none
Output body example
{
"id": "60cdd167-e2ff-4746-b609-c2bee07d9985",
"availabilityDateTime": "2023-12-19T11:00Z",
"resellerRef": "MY_COMPANY",
"status": "ON_HOLD",
"paymentStatus": "ON_HOLD",
"creationDate": "2023-12-14T08:53:05.349043Z",
"availability": {
"id": "01d0597b-a819-478b-b32d-f99290b70e88",
"availabilityDate": "2023-12-19",
"availabilityOptions": [
{
"label": "Ticket Type",
"level": "0",
"id": "24deeda6-bcda-4c04-9659-e2ca2b2beedc",
"selectedOptionId": "528446",
"optionChoices": {
"528446": "Eiffel ,2 Day Bus Pass &Cruise"
}
},
{
"label": "Start Time",
"level": "1",
"id": "01d28c41-0b26-4d3a-a0ec-229125e07c63",
"selectedOptionId": "420013_20231219",
"optionChoices": {
"420013_20231219": "12:00"
}
}
],
"unitOptions": [
{
"label": "Adult",
"id": "143731",
"restrictions": {
"minQuantity": 1,
"maxQuantity": 10,
"accompagniedBy": []
},
"price": {
"retail": 114.9,
"currency": "EUR"
},
"unitQuantity": 2,
"minAge": 13,
"maxAge": 99
},
{
"label": "Child",
"id": "112820",
"restrictions": {
"minQuantity": 1,
"maxQuantity": 10,
"accompagniedBy": []
},
"price": {
"retail": 99.9,
"currency": "EUR"
},
"unitQuantity": 1,
"minAge": 4,
"maxAge": 12
},
{
"label": "Infant",
"id": "112821",
"restrictions": {
"minQuantity": 1,
"maxQuantity": 10,
"accompagniedBy": []
},
"price": {
"retail": 0.0,
"currency": "EUR"
},
"unitQuantity": 0,
"minAge": 0,
"maxAge": 3
}
],
"maxParticipants": 10,
"minParticipants": 1,
"isOptionStepCompleted": true,
"isPricingStepCompleted": true
},
"questions": {
"customer": [
{
"id": "65649496-4230-4b3e-8fb3-9a0ed6409f6a",
"question": "First name",
"dataType": "TEXT"
},
{
"id": "5302ca5a-25de-424a-b402-7a0d2ff11c8a",
"question": "Last name",
"dataType": "TEXT"
},
{
"id": "004d7c3f-6584-4e44-b7b5-aa6d76a8f1b4",
"question": "Email Address",
"dataType": "TEXT",
"dataFormat": "EMAIL_ADDRESS"
},
{
"id": "77e3b045-968d-4c0d-bc71-564696e3001a",
"question": "Phone Number",
"dataType": "TEXT",
"dataFormat": "PHONE_NUMBER"
},
{
"id": "fb22cfef-dfd7-45ee-ae03-7411706b519b",
"question": "Date of birth",
"dataType": "DATE"
}
],
"booking": [
{
"id": "c07bf8c2-6237-4c89-9ad1-5ad9f5ab2f90",
"question": "Arrival transfer mode",
"dataType": "OPTIONS",
"questionChoices": {
"AIR": "Air",
"RAIL": "Rail",
"SEA": "Sea",
"OTHER": "Other"
},
"followUpQuestions": [
{
"id": "680802e1-4d8b-4e8b-82de-c1d6d5408fbe",
"parentId": "c07bf8c2-6237-4c89-9ad1-5ad9f5ab2f90",
"level": "1",
"requirementType": "CONDITIONAL",
"question": "Arrival airline",
"dataType": "TEXT",
"conditions": [
{
"op": "equals",
"value": "AIR"
}
],
"followUpQuestions": []
},
{
"id": "de6fc268-0af2-4df7-b5d3-7337f9929f79",
"parentId": "c07bf8c2-6237-4c89-9ad1-5ad9f5ab2f90",
"level": "1",
"requirementType": "CONDITIONAL",
"question": "Arrival flight number",
"dataType": "TEXT",
"conditions": [
{
"op": "equals",
"value": "AIR"
}
],
"followUpQuestions": []
}
]
}
],
"participants": [
{
"id": "6f830e19-c76c-4b61-a05f-7fa72229082f",
"questions": [
{
"id": "0084f15c-c21c-4f2f-a4df-0b94d9f199c4",
"question": "Date of birth",
"dataType": "DATE"
}
]
},
{
"id": "de974904-b701-4465-9ee3-53eacd5f3c95",
"questions": [
{
"id": "635a5588-2b4e-480e-ae12-ac06df15f9b6",
"question": "Date of birth",
"dataType": "DATE"
}
]
},
{
"id": "f4de002e-f208-4a7c-98e2-b85d8e6ca46f",
"questions": [
{
"id": "05b35fc6-8ebf-4781-88ae-bc0de971dd3f",
"question": "Date of birth",
"dataType": "DATE"
}
]
}
]
},
"cancellation": {
"isCancellable": false,
"cancellationPolicy": []
},
"isQuestionStepComplete": false,
"travelerDetails": {
"externalClientId": "ABCDEF"
}
}
setQuestions#
This endpoint updates the booking with the traveler answers. Always send the full list of known answers in each call. Depending on previous answers, additional conditional questions can be returned and must be answered in a subsequent call together with the already provided answers.
Path
PUT /booking-flow/v1/bookings/:bookingId/questions
Input body example
[
{
"id": "65649496-4230-4b3e-8fb3-9a0ed6409f6a",
"value": "Abraham"
}, {
"id": "5302ca5a-25de-424a-b402-7a0d2ff11c8a",
"value": "Abraham"
}, {
"id": "004d7c3f-6584-4e44-b7b5-aa6d76a8f1b4",
"value": "Abraham@mail.com"
}, {
"id": "77e3b045-968d-4c0d-bc71-564696e3001a",
"value": "0601020304"
}, {
"id": "fb22cfef-dfd7-45ee-ae03-7411706b519b",
"value": "2000-01-01"
}, {
"id": "0084f15c-c21c-4f2f-a4df-0b94d9f199c4",
"value": "2000-01-01"
}, {
"id": "635a5588-2b4e-480e-ae12-ac06df15f9b6",
"value": "2000-01-01"
}, {
"id": "05b35fc6-8ebf-4781-88ae-bc0de971dd3f",
"value": "2000-01-01"
}, {
"id": "c07bf8c2-6237-4c89-9ad1-5ad9f5ab2f90",
"value": "AIR"
}, {
"id": "680802e1-4d8b-4e8b-82de-c1d6d5408fbe",
"value": "Air France"
}, {
"id": "de6fc268-0af2-4df7-b5d3-7337f9929f79",
"value": "AF1234"
}
]
Output body example
{
"id": "60cdd167-e2ff-4746-b609-c2bee07d9985",
"availabilityDateTime": "2023-12-19T11:00Z",
"resellerRef": "MY_COMPANY",
"status": "ON_HOLD",
"paymentStatus": "ON_HOLD",
"creationDate": "2023-12-14T08:53:05.349043Z",
"updateDate": "2023-12-14T09:02:39.511359739Z",
"availability": {
"id": "01d0597b-a819-478b-b32d-f99290b70e88",
"availabilityDate": "2023-12-19",
"availabilityOptions": [
{
"label": "Ticket Type",
"level": "0",
"id": "24deeda6-bcda-4c04-9659-e2ca2b2beedc",
"selectedOptionId": "528446",
"optionChoices": {
"528446": "Eiffel ,2 Day Bus Pass &Cruise"
}
},
{
"label": "Start Time",
"level": "1",
"id": "01d28c41-0b26-4d3a-a0ec-229125e07c63",
"selectedOptionId": "420013_20231219",
"optionChoices": {
"420013_20231219": "12:00"
}
}
],
"unitOptions": [
{
"label": "Adult",
"id": "143731",
"restrictions": {
"minQuantity": 1,
"maxQuantity": 10,
"accompagniedBy": []
},
"price": {
"retail": 114.9,
"currency": "EUR"
},
"unitQuantity": 2,
"minAge": 13,
"maxAge": 99
},
{
"label": "Child",
"id": "112820",
"restrictions": {
"minQuantity": 1,
"maxQuantity": 10,
"accompagniedBy": []
},
"price": {
"retail": 99.9,
"currency": "EUR"
},
"unitQuantity": 1,
"minAge": 4,
"maxAge": 12
},
{
"label": "Infant",
"id": "112821",
"restrictions": {
"minQuantity": 1,
"maxQuantity": 10,
"accompagniedBy": []
},
"price": {
"retail": 0.0,
"currency": "EUR"
},
"unitQuantity": 0,
"minAge": 0,
"maxAge": 3
}
],
"maxParticipants": 10,
"minParticipants": 1,
"isOptionStepCompleted": true,
"isPricingStepCompleted": true
},
"questions": {
"customer": [
{
"id": "65649496-4230-4b3e-8fb3-9a0ed6409f6a",
"question": "First name",
"value": "Abraham",
"dataType": "TEXT",
"followUpQuestions": []
},
{
"id": "5302ca5a-25de-424a-b402-7a0d2ff11c8a",
"question": "Last name",
"value": "Abraham",
"dataType": "TEXT",
"followUpQuestions": []
},
{
"id": "004d7c3f-6584-4e44-b7b5-aa6d76a8f1b4",
"question": "Email Address",
"value": "Abraham@mail.com",
"dataType": "TEXT",
"dataFormat": "EMAIL_ADDRESS",
"followUpQuestions": []
},
{
"id": "77e3b045-968d-4c0d-bc71-564696e3001a",
"question": "Phone Number",
"value": "0601020304",
"dataType": "TEXT",
"dataFormat": "PHONE_NUMBER",
"followUpQuestions": []
},
{
"id": "fb22cfef-dfd7-45ee-ae03-7411706b519b",
"question": "Date of birth",
"value": "2000-01-01",
"dataType": "DATE",
"followUpQuestions": []
}
],
"booking": [
{
"id": "c07bf8c2-6237-4c89-9ad1-5ad9f5ab2f90",
"question": "Arrival transfer mode",
"value": "AIR",
"dataType": "OPTIONS",
"questionChoices": {
"AIR": "Air",
"RAIL": "Rail",
"SEA": "Sea",
"OTHER": "Other"
},
"followUpQuestions": [
{
"id": "680802e1-4d8b-4e8b-82de-c1d6d5408fbe",
"parentId": "c07bf8c2-6237-4c89-9ad1-5ad9f5ab2f90",
"level": "1",
"requirementType": "CONDITIONAL",
"question": "Arrival airline",
"value": "Air France",
"dataType": "TEXT",
"conditions": [
{
"op": "equals",
"value": "AIR"
}
],
"followUpQuestions": []
},
{
"id": "de6fc268-0af2-4df7-b5d3-7337f9929f79",
"parentId": "c07bf8c2-6237-4c89-9ad1-5ad9f5ab2f90",
"level": "1",
"requirementType": "CONDITIONAL",
"question": "Arrival flight number",
"value": "AF1234",
"dataType": "TEXT",
"conditions": [
{
"op": "equals",
"value": "AIR"
}
],
"followUpQuestions": []
}
]
}
],
"participants": [
{
"id": "6f830e19-c76c-4b61-a05f-7fa72229082f",
"questions": [
{
"id": "0084f15c-c21c-4f2f-a4df-0b94d9f199c4",
"question": "Date of birth",
"value": "2000-01-01",
"dataType": "DATE",
"followUpQuestions": []
}
]
},
{
"id": "de974904-b701-4465-9ee3-53eacd5f3c95",
"questions": [
{
"id": "635a5588-2b4e-480e-ae12-ac06df15f9b6",
"question": "Date of birth",
"value": "2000-01-01",
"dataType": "DATE",
"followUpQuestions": []
}
]
},
{
"id": "f4de002e-f208-4a7c-98e2-b85d8e6ca46f",
"questions": [
{
"id": "05b35fc6-8ebf-4781-88ae-bc0de971dd3f",
"question": "Date of birth",
"value": "2000-01-01",
"dataType": "DATE",
"followUpQuestions": []
}
]
}
]
},
"cancellation": {
"isCancellable": false,
"cancellationPolicy": []
},
"isQuestionStepComplete": true,
"travelerDetails": {
"externalClientId": "ABCDEF"
}
}
Questions for the customer are mostly billing and contact related personal information (first name, last name, email, phone number etc).
Questions about the booking might include pickup location and other preferences not tied to any specific participant.
Questions about participants can include other information relevant to activity planning (e.g. first names and last names, height/weight for equipment availability, document numbers, culinary preferences).
All the questions are localized in the format in which the booking flow has been initiated.
The questions are defined by their dataType and dataFormat. All questions are required for the booking to proceed and must be validated based on their properties.
DataType |
Comments |
DataFormat |
Validation |
Examples |
|---|---|---|---|---|
TEXT |
Minimum length 1 |
John Smith |
||
TEXT |
PHONE_NUMBER |
Fully-qualified phone number (containing the area code and country code) Use google-libphonenumber package for phone number validation. We expect E.164 format. |
+12125551234 |
|
TEXT |
EMAIL_ADDRESS |
Fully qualified email addresses. |
||
TEXT |
ADDRESS |
Minimum length 1 |
||
LONG_TEXT |
scheduled for deprecation for TEXT |
Minimum length 1 |
||
INT |
Correctly casts to an integer value between JavaScript Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER |
0 |
||
DOUBLE |
Correctly casts to a float value between JavaScript Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER or null |
0.0001 |
||
BOOLEAN |
Correctly casts to a boolean value |
true/false |
||
DATE |
Matches ISO 8601 standard (YYYY-MM-DD) |
2023-01-20 |
||
TIME |
Matches HH:MM:SS[.s+]format or null |
09:52:31 |
||
DATE_AND_TIME |
Matches ISO 8601 standard |
2020-01-20T00:00:00Z |
||
CHECKBOX_TOGGLE |
scheduled for deprecation for BOOLEAN |
Correctly casts to a boolean value |
true/false |
|
ACCEPT |
scheduled for deprecation for BOOLEAN |
Correctly casts to a boolean value |
true/false |
|
OPTIONS |
Correctly matches the value of one of the availableOptions items |
Warning
The accepted phone number format follows the E.164 standard. Inputs outside of this standard will be rejected. We suggest the google-libphonenumber library for enforcing validation on client side.
When all required questions are answered, the setQuestions endpoint returns isQuestionStepComplete as true, and you can move to the next step.
Follow-up questions#
Some questions are conditional and include a nested followUpQuestions array.
A follow-up question is activated only when the parent answer matches its condition.
Follow-up questions can be nested across multiple levels.
In each call to setQuestions, include all previously answered question IDs and values, plus any newly requested follow-up answers.
Integrators should parse questions recursively and not assume a flat list.
Warning
Some bookings require more than one call to the putQuestions endpoint to reach isQuestionStepComplete = true. When additional information is needed after the first call, new conditional questions can appear in the response. Repeat the process until isQuestionStepComplete is true before calling confirmation.
Note
Some questions may include followUpQuestions. These are extra questions that appear only when a specific answer is given to a parent question. Your integration should be able to read these questions recursively and display them dynamically.
followUpQuestions are only returned for Viator products when using Markup Model (see Markup Pricing). If you are not using Markup Model, you can ignore this field.