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.

john.doe@example.com

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.