Questionnaire
Given that you have a questionnaire_id, you can attempt the questionnaire for a particular profile, and have the answers stored for that questionnaire against the profile, to be retrieved or updated anytime later. A questionnaire comprises of a list of questions to be answered where each question has one or more answer options.
Questions may be shared among multiple questionnaires, and if you answer a question as part of one questionnaire, it would be answered for all questionnaires.
Displaying & Answering Questions
The questions presented in each questionnaire are personalized to the profile answering them. For example some questions are only supposed to be shown to female or male profiles exclusively, while other questions are displayed depending upon previous answers.
Let's say there are three single choice questions in a questionnaire:
- Are you pregnant?
- Yes
- No
- Do you smoke?
- Yes
- No
- How often do you smoke?
- Daily
- Once a week
- Occasionally
The 1st question is supposed to be displayed to only female profiles. The 2nd question is relevant for all profiles. Whether the 3rd question is supposed to be displayed to the user attempting the questionnaire depends on their answer to the 2nd question, i.e. it should be displayed only if they answer "Yes" to the 2nd question.
Therefore, we advise you display questions one by one, since a question may only become relevant based on the previous answer.
Attempting All Questions - Default Flow
Attempting the questionnaire essentially involves two steps:
- Retrieve the next question to be displayed, by calling the
/questionnaire-status/profile/{profile_id}/questionnaire/{questionnaire_id}/endpoint . Setprevious_question_idquery param as "none" to retrieve the first available question, and set it to the last retrieved question ID for subsequent requests. Refer to the endpoint for details regarding the fields returned in the response. - Answer the question returned in
next_questionfield from step 1 using thePOST /answer/endpoint. For details regarding answering different type of questions, please refer to Answering Questions. - Repeat 1-2 until
GET /questionnaire-status/returnsnext_questionasnullandprogressas1.0, indicating that the questionnaire has been completed.
The flow described above to display questions is relevant both while you're attempting a questionnaire for the first time or retaking it. You can always revisit a questionnaire, and simply re-attempt it, exactly the way you attempted it the first time, and your answers will be updated in the database.
Attempting Only Unanswered Questions - Express Flow (Optional)
Questions may be shared among multiple questionnaires, and if you answer a question as part of one questionnaire, it would be answered for all questionnaires. That makes it entirely possible that you have a questionnaire with, let's say, 10 questions and a progress of 0.5 despite the fact that you've never attempted it before, because 5 of those 10 questions were answered because you answered them for the same profile as part of other questionnaires.
If you want to complete the questionnaire and only display the unanswered questions, call the GET /questionnaire-status/ endpoint with ?unanswered_first=true, which would bypass the default order of questions, and first return the unanswered question. You can then answer the returned question, and recursively call the GET /questionnaire/ endpoint with ?unanswered_first=true until the progress is returned as 1.0. The flow diagram for this approach is given below:
In this flow, it's expected that the
next_questionreturned from/questionnaire-status/is notnull, when the progress is returned as1.0. The stopping condition for this flow is onlyprogress = 1.0if you only want to answer the minimum questions needed to complete the questionnaire. This is because the non-nullnext_questionreturned withprogress = 1.0would be an already answered question.
This flow provides extra flexibility but is entirely optional. You can always choose to attempt / re-attempt the whole questionnaire from scratch using the default flow.
It's possible that you've completed a questionnaire for a profile (i.e. progress = 1), but later upon calling
GET /questionnaire-status/you get a progress less than 1. It can happen for a number of reasons e.g.
- Admins add a new question to the questionnaire
- You re-answered a question as part of a different questionnaire and unlocked a constraint question
In such scenarios, you can answer the questionnaire again, using either of the flows mentioned in this document.
Skip Previously Answered Questions
Before attempting a questionnaire, you can list any existing answers as described here.
You can just either re-answer the question with the same answer as before, which would be the same as skipping it from a frontend user perspective, or you can entirely skip it by not calling the POST /answer/ endpoint for the skipped question, and instead calling the GET /questionnaire-status/ endpoint, with previous_question_id query param set to the ID of the skipped question.
Displaying Progress
Apart from next_question, the GET /questionnaire-status/ endpoint returns the following status fields:
progressnum_remaining_avaliable_questionstotal_num_avaliable_questions
While progress is a metric that determines whether a questionnaire is complete or not, using it to display a progress bar or percentage to a frontend user is not always ideal. If you've implemented the express flow, where users only answer unanswered questions in a questionnaire until progress = 1, the progress can be used. However, for the default flow, where you want to attempt all questions regardless of the current progress, more relevant metrics to display progress would be num_remaining_avaliable_questions / total_num_avaliable_questions or just countdown of num_remaining_avaliable_questions. This would work even if you're retaking a questionnaire when progress would be 1, but the rest of the two metrics would still indicate the correct position within the questionnaire, depending on the previous_question_id that you pass as the query param.
The num_remaining_avaliable_questions would be equal to the total_num_avaliable_questions at the start, i.e. when you call GET /questionnaire-status/ without any query param (or with previous_question_id="none") and it would decrease as you move towards the end of the questionnaire, i.e. with every subsequent GET /questionnaire-status/ call updating the previous_question_id. Once you reach the last question, GET /questionnaire-status/ would return next_question as null, and num_remaining_avaliable_questions as 0.
Updating a Specific Question's Answer
If you have access to the list of questions as shown in the Example Questionnaire or you have access to the list of answers as described here, you can always do a simple POST /answer/ for a particular question, updating your answer for that question. However, please note that updating a question's answer could potentially unlock another question in that questionnaire resulting in progress being less than 1. If you want to ensure that the questionnaire remains completed then you must get updated progress from GET /questionnaire-status/ and if progress is less than 1, further follow the steps outlined above, using either of the flows, to complete the questionnaire.
Listing Answers of a Profile for a Questionnaire
Use the GET /answer/ endpoint to list all answers of a profile against a particular questionnaire. Before re-attempting a questionnaire, you can use this endpoint to display the existing answers of the profile for the questions. You can also list answers for a questionnaire that's been partially attempted, allowing user to skip already answered questions.
