Attempting Questionnaires

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:

  1. Are you pregnant?
    1. Yes
    2. No
  2. Do you smoke?
    1. Yes
    2. No
  3. How often do you smoke?
    1. Daily
    2. Once a week
    3. 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:

  1. Retrieve the next question to be displayed, by calling the /questionnaire-status/profile/{profile_id}/questionnaire/{questionnaire_id}/ endpoint . Set previous_question_id query 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.
  2. Answer the question returned in next_question field from step 1 using the POST /answer/ endpoint. For details regarding answering different type of questions, please refer to Answering Questions.
  3. Repeat 1-2 until GET /questionnaire-status/ returns next_question as null and progress as 1.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_question returned from /questionnaire-status/ is not null, when the progress is returned as 1.0. The stopping condition for this flow is only progress = 1.0 if you only want to answer the minimum questions needed to complete the questionnaire. This is because the non-null next_question returned with progress = 1.0 would 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.

  1. Admins add a new question to the questionnaire
  2. 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:

  • progress
  • num_remaining_avaliable_questions
  • total_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.