{"_id":"5a973d550614720012e4d279","project":"55843604fd8d910d007b9502","version":{"_id":"558444ceafccfd0d00fcb2bb","forked_from":"55843604fd8d910d007b9505","project":"55843604fd8d910d007b9502","__v":67,"createdAt":"2015-06-19T16:35:26.435Z","releaseDate":"2015-06-19T16:35:26.435Z","categories":["558444cfafccfd0d00fcb2bc","558444cfafccfd0d00fcb2bd","55ad4ce733616a0d00599d2e","55ad4cef6aadf20d0015b764","55ad4cf36aadf20d0015b765","55ad4cfb24cf160d0013584f","55ad4d0024cf160d00135850","55ad4d0a24cf160d00135851","55ad4d0d24cf160d00135852","55ad4d126aadf20d0015b766","55ad4d1624cf160d00135853","55ad4d1933616a0d00599d2f","55ad4d2233616a0d00599d30","55ad4d2e24cf160d00135854","55d35b6bf77e6d0d00b1b092","55d3649a0168850d0073f14a","55d366d40168850d0073f15a","55d37fcff77e6d0d00b1b13f","55d383e50168850d0073f1e1","55d3ac26c336ec0d007c2251","55d3c51cb2330119009c31db","55d3c59bfe37111900e536f3","55d3c5a7fe37111900e536f4","55d3c5b4fe37111900e536f5","55d3c5d4fe37111900e536f6","55d3c5d6b2330119009c31df","55d3c5d71f478b170077c164","55d3c687b2330119009c31e4","55d3c6a4fe37111900e536f9","55d3c6befe37111900e536fa","55d3c6e8d2c66f0d00497f93","55d49dcfd7c16b2d007de905","55d4ca8f5082980d0009c79b","55d4cab9c95a3d2f0069ad3d","55d4d279c95a3d2f0069ad60","55d4d9355082980d0009c7e1","55d4f6b5988e130d000b3eb1","55d64dc8e60a2f0d00b88ecb","5627ca43fcbbc621004ec07d","56c64a0d8f98b50d0012c37c","56f1b8b13eb62a34003ea041","56f1b9df4476fb2200795e8c","57f6907dca5e5d1700039ae9","591dd06ca266c423002ec4ca","59234825e465c11900922518","5936f82eaa591e0027638d57","59972f54fd7078001992c136","599c6da8f180820025f14909","59b054613c3e1b0019cf27d9","59b1ceca2d6231003ad73e5f","59b1cf1857911600382e0dc4","59b1cf2730f3d60010c30ef7","59b1cf385d4b89003035441a","59b1cf5857911600382e0dc6","59bc2c4e26ac9b0010a8b753","59bc2ce20b3eb30010657b70","59f0c793ba3bc90030f413ab","59f0cd62f5ecda00325294b9","59fb55a8e8d0f600101aedc3","59fcb05c067f8d0028613f86","5a2af4a1bc5fba00283909c1","5a83673b0e56010012138c12","5a972f2e77b85a0070e4ebe2","5aa300224ed4b40012c53e1d","5acd20095efd8d000359bb3c","5ad50889c05179000306021e","5af0927a8779670003daff34","5b55a46b282b25000319669e"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"3.0.0","version":"3"},"category":{"_id":"59234825e465c11900922518","__v":0,"version":"558444ceafccfd0d00fcb2bb","project":"55843604fd8d910d007b9502","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-05-22T20:20:53.281Z","from_sync":false,"order":1,"slug":"using-the-qualtrics-api","title":"Using the Qualtrics APIs"},"user":"57bb969a36eff81700666822","githubsync":"","__v":2,"parentDoc":null,"updates":["5a9f1ec7bff4bf001292819c","5b4e54b04c79160003af2204"],"next":{"pages":[],"description":""},"createdAt":"2018-02-28T23:37:57.947Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"settings":"","results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":12,"body":"This guide walks through the Conversational APIs that allow you to to take a survey programmatically. By using these APIs, you can create new user interfaces to surveys and use the Conversational APIs to record the survey responses.\n\nThere are two steps to responding to a survey programmatically:\n\n1. Create a new survey session with the  [Create Survey Session](doc:create-session) API. You will receive a survey session ID (**sessionId**) that you supply to the [Update Survey Session](doc:update-session) API.\n2. Use the [Update Survey Session](doc:update-session) API to respond to each question with **advance** set to **true**.\n\nYou can get the current state of a session with the [Get Survey Session](doc:get-session) API.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Surveys\",\n  \"body\": \"If you'd like to manage the survey itself, see [Managing Surveys](doc:managing-surveys) instead.\"\n}\n[/block]\nThis document contains the following sections:\n\n\n* [Starting a Survey Session](#starting-a-survey-session) \n* [Updating a Survey Session](#updating-a-survey-session) \n* [Getting the Current Survey Session](#getting-the-current-survey-session)\n* [Potential Errors](#potential-errors)\n[block:api-header]\n{\n  \"title\": \"Starting a Survey Session\"\n}\n[/block]\nThe first step in taking a survey is to start a new session with the [Create Session](doc:create-session) API call. Every time this API is called a new session will be created. The response object will include a session id that you will need to keep track of in order to answer questions and advance through the survey using the [Update Session](doc:update-session) API. \n\nThe following code example shows how to create a survey session:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"# Create Survey Session\\n\\nimport os\\nimport requests\\n\\n# Setting user Parameters\\napiToken = os.environ[\\\"Q_API_TOKEN\\\"]\\ndataCenter = os.environ[\\\"Q_DATA_CENTER\\\"]\\n\\nsurveyId = \\\"SV_eyRJDHHhxbvI6aN\\\"\\n\\nbaseUrl = \\\"https://{0}.qualtrics.com/API/v3/surveys/{1}/sessions\\\".format(dataCenter, surveyId)\\nheaders = {\\n    \\\"x-api-token\\\": apiToken,\\n    \\\"Content-Type\\\": \\\"application/json\\\"\\n    }\\n\\ndata = { \\n  \\\"language\\\": \\\"EN\\\",\\n  \\\"embeddedData\\\": {\\n\\t   \\\"storeId\\\": \\\"48123\\\"\\n\\t }\\n}\\nresponse = requests.post(baseUrl, json=data, headers=headers)\\nprint(response.text)\",\n      \"language\": \"python\"\n    }\n  ]\n}\n[/block]\n## Survey Session Request Object\n\nAs shown in the previous code example, you can provide an optional request object to configure the survey session. An example of a complete request object is shown below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"language\\\": \\\"EN\\\",\\n  \\\"embeddedData\\\": {\\n    \\\"storeNumber\\\": \\\"123\\\"\\n  },\\n  \\\"recipientId\\\": \\\"MLRP_1234567890\\\",\\n  \\\"distributionId\\\": \\\"EMD_1234567890\\\"\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nThe following table describes the members of the request object:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Name\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description\",\n    \"0-0\": \"**language**\",\n    \"0-1\": \"String\",\n    \"0-2\": \"The **language** field specifies the language of the survey questions. It must be an uppercase version of a supported language. For a list of the language codes supported by Qualtrics, see [Language Codes](doc:language-codes). If a question is not translated in the given language it will use the survey's default language. The language cannot be changed mid-survey.\",\n    \"1-0\": \"**embeddedData**\",\n    \"1-1\": \"Object\",\n    \"1-2\": \"The **embeddedData** object can be set when starting the survey. You can also specify additional embedded data during the survey by using the [Updating a Survey Session](doc:managing-survey-sessions#updating-a-survey-session) API.\",\n    \"2-0\": \"**receipientId** and **distributionId**\",\n    \"2-1\": \"String\",\n    \"2-2\": \"The **recipientId** and **distributionId** fields can be specified to associate a survey session to a Qualtrics panel member and distribution. See [Generate Distribution Links](doc:generate-distribution-invite) for more information on creating a distribution. Both fields are optional, but if a **distributionId** is specified there must also be a **recipientId**. The **recipientId** field can be used by itself to pull in any recipient embedded data.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n## Survey Session Response Object\n\nThe response to all Survey Session API calls will have the same structure. The response body will contain the current session id, the questions that the respondent should be asked, any embedded data that has been defined in the survey flow, any preexisting response data (default choices), and an end of survey message if there are no more questions.\n\nAll response bodies will be returned as JSON (including errors). The following shows an example of a response object:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"result\\\": {\\n    \\\"sessionId\\\": \\\"FS_3jVhuKYaCoptXkW\\\",\\n    \\\"questions\\\": [\\n      {\\n        \\\"questionId\\\": \\\"QID3\\\",\\n        \\\"type\\\": \\\"db\\\",\\n        \\\"display\\\": \\\"Thanks for taking this survey. Please answer the following questions.\\\",\\n        \\\"options\\\": {}\\n      },\\n      {\\n        \\\"questionId\\\": \\\"QID1\\\",\\n        \\\"type\\\": \\\"mc\\\",\\n        \\\"display\\\": \\\"What is your favorite color?\\\",\\n        \\\"options\\\": {\\n          \\\"multiSelect\\\": false\\n        },\\n        \\\"choices\\\": [\\n          {\\n            \\\"choiceId\\\": \\\"1\\\",\\n            \\\"display\\\": \\\"red\\\",\\n            \\\"textual\\\": false\\n          },\\n          {\\n            \\\"choiceId\\\": \\\"2\\\",\\n            \\\"display\\\": \\\"green\\\",\\n            \\\"textual\\\": false\\n          },\\n          {\\n            \\\"choiceId\\\": \\\"3\\\",\\n            \\\"display\\\": \\\"other\\\",\\n            \\\"textual\\\": true\\n          }\\n        ]\\n      },\\n      {\\n        \\\"questionId\\\": \\\"QID2\\\",\\n        \\\"type\\\": \\\"te\\\",\\n        \\\"display\\\": \\\"Tell me why it's your favorite color\\\",\\n        \\\"options\\\": {}\\n      }\\n    ],\\n    \\\"embeddedData\\\": {\\n      \\\"customerId\\\": \\\"123\\\"\\n    },\\n    \\\"responses\\\": {\\n      \\\"QID1\\\": {\\n        \\\"1\\\": {\\n          \\\"selected\\\": true\\n        }\\n      }\\n    },\\n    \\\"done\\\": false\\n  }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nThe response object contains the following members:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Name\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description\",\n    \"0-0\": \"**sessionId**\",\n    \"0-1\": \"String\",\n    \"0-2\": \"The **sessionId** field contains the current session ID. Keep track of this ID to submit responses to questions.\",\n    \"1-0\": \"**embeddedData**\",\n    \"1-1\": \"Object\",\n    \"1-2\": \"The **embeddedData** object contains the embedded data that is defined in the survey flow. Only embedded data values defined in the survey flow will be returned. You can set arbitrary embedded data values when you start or update a session, but those values will not be returned here unless they are defined in the survey flow.\",\n    \"2-0\": \"**questions**\",\n    \"2-1\": \"Array of Objects\",\n    \"2-2\": \"The **questions** array contains question definitions. The order of the questions in the array is the order in which they should be asked. The order will reflect any question randomization defined in the survey. Only a subset of questions are supported by the survey session APIs. Each question will have a **type** to distinguish between them. More details are in [The Question Object](#section-the-question-object) below.\",\n    \"3-0\": \"**responses**\",\n    \"3-1\": \"Array of Objects\",\n    \"4-0\": \"**done**\",\n    \"4-1\": \"String\",\n    \"3-2\": \"The **responses** array contains the recorded responses for each question on the current page. These can come from default choices or using the Updating a Survey Session API without advancing. See [Updating a Survey Session](doc:managing-survey-sessions#updating-a-survey-session) for more details on the format.\",\n    \"4-2\": \"The **done** boolean indicates that the survey session is complete. It will be **false** unless the session is complete in which case it will be a string containing the end of survey message.\"\n  },\n  \"cols\": 3,\n  \"rows\": 5\n}\n[/block]\n### The Question Object\n\nThe **question** object contains information about each question on the survey. There are some common fields among all types of question objects. The following table shows those common fields, and the following sections contain information about members specific to each question type.\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Name\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description\",\n    \"0-0\": \"**questionId**\",\n    \"0-1\": \"String\",\n    \"0-2\": \"This is the question's id. It is needed to record responses.\",\n    \"1-0\": \"**type**\",\n    \"1-1\": \"String\",\n    \"1-2\": \"The **type** string defines what kind of question this is. Supported question types are **mc** (multiple choice), **te** (text entry), and **db** (descriptive block, but also know as descriptive text).\",\n    \"2-0\": \"**display**\",\n    \"2-1\": \"String\",\n    \"2-2\": \"The **display** string is the question text.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n\n### Question Types\n\nThere are three possible question types: multiple choice (**mc**), text entry (**te**), and descriptive block (**db**). For more information on these types of questions, see the following pages:\n\n- [Multiple Choice](https://www.qualtrics.com/support/edit-survey/editing-questions/question-types-guide/standard-content/multiple-choice/)\n- [Text Entry](https://www.qualtrics.com/support/edit-survey/editing-questions/question-types-guide/standard-content/text-entry/)\n- [Descriptive Text](https://www.qualtrics.com/support/edit-survey/editing-questions/question-types-guide/static-content/descriptive-text-and-graphic/)\n\n#### Multiple Choice (mc)\n\nThe following JSON shows an example of an **mc** or multiple choice question object:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"questionId\\\": \\\"QID1\\\",\\n  \\\"type\\\": \\\"mc\\\",\\n  \\\"display\\\": \\\"What is your favorite color?\\\",\\n  \\\"options\\\": {\\n    \\\"multiSelect\\\": false\\n  },\\n  \\\"choices\\\": [\\n    {\\n      \\\"choiceId\\\": \\\"1\\\",\\n      \\\"display\\\": \\\"red\\\",\\n      \\\"textual\\\": false\\n    },\\n    {\\n      \\\"choiceId\\\": \\\"2\\\",\\n      \\\"display\\\": \\\"green\\\",\\n      \\\"textual\\\": false\\n    },\\n    {\\n      \\\"choiceId\\\": \\\"3\\\",\\n      \\\"display\\\": \\\"other\\\",\\n      \\\"textual\\\": true\\n    }\\n  ]\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nThe following table contains information on each of the members of the multiple choice question:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Name\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description\",\n    \"0-0\": \"**options**\",\n    \"0-1\": \"Object\",\n    \"0-2\": \"The **options** object defines whether multiple choices can be selected via **multiSelect**. For single answer (radio buttons) **mc** questions, it will be false, and for multiple answer (checkbox), it will be true.\",\n    \"1-0\": \"**choices**\",\n    \"1-1\": \"Array of Objects\",\n    \"1-2\": \"The **choices** array contains **choice** objects. (Choice randomization defined in the survey may affect the order of this array.) A choice has an **id** that will be used to specify it as selected (see [Updating a Survey Session](doc:managing-survey-sessions#updating-a-survey-session)), **display** is the choice text, and **textual** is defined if this choice allows a textual response.\"\n  },\n  \"cols\": 3,\n  \"rows\": 2\n}\n[/block]\n\n#### Text Entry (te)\n\nThe following JSON shows an example text entry question:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"questionId\\\": \\\"QID3\\\",\\n  \\\"type\\\": \\\"te\\\",\\n  \\\"display\\\": \\\"Tell me why it's your favorite color\\\",\\n  \\\"options\\\": {}\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nText entry questions don't have choices or any options. They accept any textual response.\n\n#### Descriptive Block (db)\n\nThe following shows an example of a descriptive block question:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"questionId\\\": \\\"QID7\\\",\\n  \\\"type\\\": \\\"db\\\",\\n  \\\"display\\\": \\\"Thank you for taking this survey. Please answer truthfully.\\\",\\n  \\\"options\\\": {}\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nA **db** question is simply used to display text information, an image, or some other file to a respondent. You cannot answer a **db** question.\n[block:api-header]\n{\n  \"title\": \"Updating a Survey Session\"\n}\n[/block]\nTo record the respondent's answers, use the [Update Session](doc:update-session) API.\n\nThe following code example shows how to use this API:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"# Update Survey Session\\n\\nimport os\\nimport requests\\n\\n# Setting user Parameters\\napiToken = os.environ[\\\"Q_API_TOKEN\\\"]\\ndataCenter = os.environ[\\\"Q_DATA_CENTER\\\"]\\n\\nsurveyId = \\\"SV_eyRJDHHhxbvI6aN\\\"\\nsessionId = \\\"FS_xfJgWwTtRXSLFD3\\\"\\n \\nbaseUrl = \\\"https://{0}.qualtrics.com/API/v3/surveys/{1}/sessions/{2}\\\".format(dataCenter, surveyId, sessionId)\\nheaders = {\\n    \\\"x-api-token\\\": apiToken,\\n    \\\"Content-Type\\\": \\\"application/json\\\"\\n    }\\n\\ndata = { \\n  \\\"advance\\\": False,\\n  \\\"embeddedData\\\": {\\n    \\\"username\\\": \\\"johns\\\"\\n  },\\n  \\\"responses\\\": {\\n    \\\"QID1\\\": {\\n      \\\"3\\\": {\\n        \\\"selected\\\": True\\n      }\\n    }\\n  }\\n}\\nresponse = requests.post(baseUrl, json=data, headers=headers)\\nprint(response.text)\\n\",\n      \"language\": \"python\"\n    }\n  ]\n}\n[/block]\nThe previous example chooses answer three to the first multiple choice question and does not advance to the next question.\n\nAn example POST request body is shown below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"advance\\\": true,\\n  \\\"embeddedData\\\": {\\n    \\\"additionalEmbeddedData\\\": \\\"something new\\\"\\n  },\\n  \\\"responses\\\": {\\n    \\\"QID1\\\": {\\n      \\\"1\\\": {\\n        \\\"selected\\\": true\\n      }\\n    },\\n    \\\"QID2\\\": \\\"It's a nice color.\\\"\\n  }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nThe following table provides information on the members in the request:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Name\",\n    \"h-1\": \"Type\",\n    \"h-2\": \"Description\",\n    \"0-0\": \"**advance**\",\n    \"0-1\": \"Boolean\",\n    \"0-2\": \"The **advance** field is used indicate whether to move to the next set of questions or save a respondent's current progress without moving on. Specify **true** to move to the next page or **false** to save current responses and come back later. When **advance** is **true**, it will run through any validation specified in the survey. If validation fails the same set of questions will be returned in the response body with a message about why validation failed.\",\n    \"1-0\": \"**embeddedData**\",\n    \"1-1\": \"Object\",\n    \"1-2\": \"Any additional **embeddedData** can be set here.\",\n    \"2-0\": \"**responses**\",\n    \"2-1\": \"Object\",\n    \"2-2\": \"The **responses** object contains the respondent's answers to questions. The **responses** object is a mapping from question id to question response. The response format is different for each question type and is detailed in the next section. Descriptive block (db) questions do not accept responses so they should not be included in the responses object.\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\n\n## Response Types\n\nThere are two types of responses, multiple choice (mc) responses and text entry (te) responses. Descriptive block (db) questions do not have a response.\n\n### Multiple Choice Response Types (mc)\n\nThere are two formats of multiple choice response types:\n\n1. An explicit response format\n2. A \"fuzzy\" response format.\n\n#### Multiple Choice Explicit Response\n\nThe explicit response format tells the API exactly which choices are selected and any textual response associated with that choice. It is an object with choice id keys that map to an object with a **selected** and **text** key. The following example shows an explicit answer to a multiple choice question:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"\\\"QID1\\\": {\\n  \\\"3\\\": {\\n    \\\"selected\\\": true,\\n    \\\"text\\\": \\\"blue\\\"\\n  }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nIn this example, answer 3 is selected for **QID1** and the **textual** response was **blue**. If **multiSelect** (in the **options** object of each **choice** in the **choices** array) is true for the **mc** question, include multiple choice IDs in the **QID** object. Any choices not included in the response are considered unselected. The following JSON shows an example of multiple choices:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"\\\"QID1\\\": {\\n  \\\"1\\\": {\\n    \\\"selected\\\": true\\n  },\\n  \\\"2\\\": {\\n    \\\"selected\\\": true\\n  },\\n  \\\"3\\\": {\\n    \\\"selected\\\": true,\\n    \\\"text\\\": \\\"blue\\\"\\n  }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n#### Multiple Choice Fuzzy Response\n\nUsing the fuzzy response format is useful for loosely matching against the choice texts. It lets Qualtrics figure out which choice should be selected based on the text of the response. For example, you ask \"What if your favorite color?\" with choices \"Crimson Red\", \"Forest Green\", and \"Sky Blue\". If the respondent responds with \"red,\" the API will determine that \"Crimson Red\" is the appropriate match and mark that choice as selected. The following example shows how to supply a fuzzy match to a question:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"\\\"QID1\\\": {\\n  \\\"fuzzySearch\\\": \\\"red\\\",\\n  \\\"maxMatches\\\": 1\\n}\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\nThe **maxMatches** field can be set to select multiple choices if desired. It uses some very basic string matching to determine which choice should be selected. Because of the simple nature of the algorithm, it might match too many choices or no choices at all, in which case an error will be returned. See the example error response formats of the [Update Session](doc:update-session) API for details.\n\n### Text Entry Response\n\nA text entry (te) response is simply a string. The following example shows such a response:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"\\\"QID2\\\": \\\"It's a nice color.\\\"\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Getting the Current Survey Session\"\n}\n[/block]\nTo get the respondent's current session use the [Get Session](doc:get-session) API. The following example shows how to use the Get Survey Session API:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"# Get Survey Session\\n\\nimport os\\nimport requests\\n\\n# Setting user Parameters\\napiToken = os.environ[\\\"Q_API_TOKEN\\\"]\\ndataCenter = os.environ[\\\"Q_DATA_CENTER\\\"]\\n\\nsurveyId = \\\"SV_eyRJDHHhxbvI6aN\\\"\\nsessionId = \\\"FS_xfJgWwTtRXSLFD3\\\"\\n\\nbaseUrl = \\\"https://{0}.qualtrics.com/API/v3/surveys/{1}/sessions/{2}\\\".format(dataCenter, surveyId, sessionId)\\nheaders = {\\n    \\\"x-api-token\\\": apiToken,\\n    \\\"Content-Type\\\": \\\"application/json\\\"\\n    }\\n\\nresponse = requests.get(baseUrl, headers=headers)\\nprint(response.text)\",\n      \"language\": \"python\"\n    }\n  ]\n}\n[/block]\nIt will return the current set of questions that should be asked to the respondent as well as any saved answers. It has the same format described [above](#section-survey-session-response-object). From here you can use the [Updating a Survey Session](#updating-a-survey-session) API to provide answers.\n[block:api-header]\n{\n  \"title\": \"Potential Errors\"\n}\n[/block]\nIf the original [Create Session](doc:create-session) API request is successful, status code 201 is returned along with the session body. However, keep in mind that to start a session, the **surveyId** must correspond to a survey that is compatible with this API and the proper authorization headers must be included with the initial request. (See [Authentication](doc:authentication) for more information.) \n\n## Create Session Errors\n\nYou may encounter errors with the following formats upon attempting to start a session.\n\nIn the case of a **bad survey** error, you will need to ensure your survey contains no incompatible questions and that it is currently started, active, and unexpired.\n\nIn the case of an **authentication** error, you will need to ensure that the correct [X-API-TOKEN](doc:authentication) header was included with your request. \n\nIn the case of a **survey not found** error, you will need to ensure that the **surveyId** you are using corresponds to an existing survey.\n\nThe following shows examples of each of these errors:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"error\\\": \\\"BadSurvey\\\",\\n  \\\"desc\\\": \\\"survey is incompatible.\\\",\\n  \\\"incompatibilities\\\": {\\n    \\\"questions\\\": {\\n      \\\"QID1\\\": [\\n        \\\"Unsupported question type Matrix-Likert-SingleAnswer\\\"\\n      ],\\n      \\\"QID2\\\": [\\n        \\\"Unsupported question type TE-FORM\\\"\\n      ]\\n    }\\n  }\\n}\",\n      \"language\": \"json\",\n      \"name\": \"400 Bad Survey\"\n    },\n    {\n      \"code\": \"{\\n  \\\"error\\\": \\\"BadSurvey\\\",\\n  \\\"desc\\\": \\\"survey is inactive.\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"400 Bad Survey\"\n    },\n    {\n      \"code\": \"{\\n  \\\"error\\\": \\\"NotFound\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"404 Survey Not Found\"\n    }\n  ]\n}\n[/block]\nNote that errors with the same formats can occur for the same reasons when attempting to use the [Get Session](doc:get-session) or [Update Session](doc:update-session) APIs. \n\n## Updating Session Errors\n\nThere are some additional errors you should be aware of when updating sessions.\n\nIn the case of a **validation** error, the session cannot proceed because of validation logic within the survey. The respondent will have to pick different answers. The **problems** field will contain an array of objects, each with an ID of a question that did not pass validation and its associated message.\n\nAn **outdated session** error means that the session has expired and can no longer be updated.\n\nLastly, if you use the fuzzy matching feature to select responses, a **fuzzy** error may occur if there are no matches or if the number of matches is greater than **maxMatches**.\n\nThe following gives examples of these errors:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"error\\\": \\\"ValidationErrors\\\",\\n  \\\"problems\\\": [\\n    {\\n      \\\"questionId\\\": \\\"QID1\\\",\\n      \\\"message\\\": \\\"Please select Choice 2\\\"\\n    }\\n  ]\\n}\",\n      \"language\": \"json\",\n      \"name\": \"400 Validation Error\"\n    },\n    {\n      \"code\": \"{\\n  \\\"error\\\": \\\"OutdatedSession\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"400 Outdated Session\"\n    },\n    {\n      \"code\": \"{\\n  \\\"error\\\": \\\"FuzzyNoMatch\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"400 Fuzzy Error\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Documentation Change (9/17/18)\",\n  \"body\": \"The \\\"maxSelectable\\\" option that was previously documented was never implemented. Instead, the \\\"multiSelect\\\" option, which accepts a true/false value, is used for questions that accept multiple answers. The documentation has been updated accordingly. This correction reflects the actual result of the API, which has not changed in functionality.\"\n}\n[/block]","excerpt":"APIs for taking a survey programmatically","slug":"managing-survey-sessions","type":"basic","title":"Using the Conversational APIs"}

Using the Conversational APIs

APIs for taking a survey programmatically

This guide walks through the Conversational APIs that allow you to to take a survey programmatically. By using these APIs, you can create new user interfaces to surveys and use the Conversational APIs to record the survey responses. There are two steps to responding to a survey programmatically: 1. Create a new survey session with the [Create Survey Session](doc:create-session) API. You will receive a survey session ID (**sessionId**) that you supply to the [Update Survey Session](doc:update-session) API. 2. Use the [Update Survey Session](doc:update-session) API to respond to each question with **advance** set to **true**. You can get the current state of a session with the [Get Survey Session](doc:get-session) API. [block:callout] { "type": "info", "title": "Surveys", "body": "If you'd like to manage the survey itself, see [Managing Surveys](doc:managing-surveys) instead." } [/block] This document contains the following sections: * [Starting a Survey Session](#starting-a-survey-session) * [Updating a Survey Session](#updating-a-survey-session) * [Getting the Current Survey Session](#getting-the-current-survey-session) * [Potential Errors](#potential-errors) [block:api-header] { "title": "Starting a Survey Session" } [/block] The first step in taking a survey is to start a new session with the [Create Session](doc:create-session) API call. Every time this API is called a new session will be created. The response object will include a session id that you will need to keep track of in order to answer questions and advance through the survey using the [Update Session](doc:update-session) API. The following code example shows how to create a survey session: [block:code] { "codes": [ { "code": "# Create Survey Session\n\nimport os\nimport requests\n\n# Setting user Parameters\napiToken = os.environ[\"Q_API_TOKEN\"]\ndataCenter = os.environ[\"Q_DATA_CENTER\"]\n\nsurveyId = \"SV_eyRJDHHhxbvI6aN\"\n\nbaseUrl = \"https://{0}.qualtrics.com/API/v3/surveys/{1}/sessions\".format(dataCenter, surveyId)\nheaders = {\n \"x-api-token\": apiToken,\n \"Content-Type\": \"application/json\"\n }\n\ndata = { \n \"language\": \"EN\",\n \"embeddedData\": {\n\t \"storeId\": \"48123\"\n\t }\n}\nresponse = requests.post(baseUrl, json=data, headers=headers)\nprint(response.text)", "language": "python" } ] } [/block] ## Survey Session Request Object As shown in the previous code example, you can provide an optional request object to configure the survey session. An example of a complete request object is shown below: [block:code] { "codes": [ { "code": "{\n \"language\": \"EN\",\n \"embeddedData\": {\n \"storeNumber\": \"123\"\n },\n \"recipientId\": \"MLRP_1234567890\",\n \"distributionId\": \"EMD_1234567890\"\n}", "language": "json" } ] } [/block] The following table describes the members of the request object: [block:parameters] { "data": { "h-0": "Name", "h-1": "Type", "h-2": "Description", "0-0": "**language**", "0-1": "String", "0-2": "The **language** field specifies the language of the survey questions. It must be an uppercase version of a supported language. For a list of the language codes supported by Qualtrics, see [Language Codes](doc:language-codes). If a question is not translated in the given language it will use the survey's default language. The language cannot be changed mid-survey.", "1-0": "**embeddedData**", "1-1": "Object", "1-2": "The **embeddedData** object can be set when starting the survey. You can also specify additional embedded data during the survey by using the [Updating a Survey Session](doc:managing-survey-sessions#updating-a-survey-session) API.", "2-0": "**receipientId** and **distributionId**", "2-1": "String", "2-2": "The **recipientId** and **distributionId** fields can be specified to associate a survey session to a Qualtrics panel member and distribution. See [Generate Distribution Links](doc:generate-distribution-invite) for more information on creating a distribution. Both fields are optional, but if a **distributionId** is specified there must also be a **recipientId**. The **recipientId** field can be used by itself to pull in any recipient embedded data." }, "cols": 3, "rows": 3 } [/block] ## Survey Session Response Object The response to all Survey Session API calls will have the same structure. The response body will contain the current session id, the questions that the respondent should be asked, any embedded data that has been defined in the survey flow, any preexisting response data (default choices), and an end of survey message if there are no more questions. All response bodies will be returned as JSON (including errors). The following shows an example of a response object: [block:code] { "codes": [ { "code": "{\n \"result\": {\n \"sessionId\": \"FS_3jVhuKYaCoptXkW\",\n \"questions\": [\n {\n \"questionId\": \"QID3\",\n \"type\": \"db\",\n \"display\": \"Thanks for taking this survey. Please answer the following questions.\",\n \"options\": {}\n },\n {\n \"questionId\": \"QID1\",\n \"type\": \"mc\",\n \"display\": \"What is your favorite color?\",\n \"options\": {\n \"multiSelect\": false\n },\n \"choices\": [\n {\n \"choiceId\": \"1\",\n \"display\": \"red\",\n \"textual\": false\n },\n {\n \"choiceId\": \"2\",\n \"display\": \"green\",\n \"textual\": false\n },\n {\n \"choiceId\": \"3\",\n \"display\": \"other\",\n \"textual\": true\n }\n ]\n },\n {\n \"questionId\": \"QID2\",\n \"type\": \"te\",\n \"display\": \"Tell me why it's your favorite color\",\n \"options\": {}\n }\n ],\n \"embeddedData\": {\n \"customerId\": \"123\"\n },\n \"responses\": {\n \"QID1\": {\n \"1\": {\n \"selected\": true\n }\n }\n },\n \"done\": false\n }\n}", "language": "json" } ] } [/block] The response object contains the following members: [block:parameters] { "data": { "h-0": "Name", "h-1": "Type", "h-2": "Description", "0-0": "**sessionId**", "0-1": "String", "0-2": "The **sessionId** field contains the current session ID. Keep track of this ID to submit responses to questions.", "1-0": "**embeddedData**", "1-1": "Object", "1-2": "The **embeddedData** object contains the embedded data that is defined in the survey flow. Only embedded data values defined in the survey flow will be returned. You can set arbitrary embedded data values when you start or update a session, but those values will not be returned here unless they are defined in the survey flow.", "2-0": "**questions**", "2-1": "Array of Objects", "2-2": "The **questions** array contains question definitions. The order of the questions in the array is the order in which they should be asked. The order will reflect any question randomization defined in the survey. Only a subset of questions are supported by the survey session APIs. Each question will have a **type** to distinguish between them. More details are in [The Question Object](#section-the-question-object) below.", "3-0": "**responses**", "3-1": "Array of Objects", "4-0": "**done**", "4-1": "String", "3-2": "The **responses** array contains the recorded responses for each question on the current page. These can come from default choices or using the Updating a Survey Session API without advancing. See [Updating a Survey Session](doc:managing-survey-sessions#updating-a-survey-session) for more details on the format.", "4-2": "The **done** boolean indicates that the survey session is complete. It will be **false** unless the session is complete in which case it will be a string containing the end of survey message." }, "cols": 3, "rows": 5 } [/block] ### The Question Object The **question** object contains information about each question on the survey. There are some common fields among all types of question objects. The following table shows those common fields, and the following sections contain information about members specific to each question type. [block:parameters] { "data": { "h-0": "Name", "h-1": "Type", "h-2": "Description", "0-0": "**questionId**", "0-1": "String", "0-2": "This is the question's id. It is needed to record responses.", "1-0": "**type**", "1-1": "String", "1-2": "The **type** string defines what kind of question this is. Supported question types are **mc** (multiple choice), **te** (text entry), and **db** (descriptive block, but also know as descriptive text).", "2-0": "**display**", "2-1": "String", "2-2": "The **display** string is the question text." }, "cols": 3, "rows": 3 } [/block] ### Question Types There are three possible question types: multiple choice (**mc**), text entry (**te**), and descriptive block (**db**). For more information on these types of questions, see the following pages: - [Multiple Choice](https://www.qualtrics.com/support/edit-survey/editing-questions/question-types-guide/standard-content/multiple-choice/) - [Text Entry](https://www.qualtrics.com/support/edit-survey/editing-questions/question-types-guide/standard-content/text-entry/) - [Descriptive Text](https://www.qualtrics.com/support/edit-survey/editing-questions/question-types-guide/static-content/descriptive-text-and-graphic/) #### Multiple Choice (mc) The following JSON shows an example of an **mc** or multiple choice question object: [block:code] { "codes": [ { "code": "{\n \"questionId\": \"QID1\",\n \"type\": \"mc\",\n \"display\": \"What is your favorite color?\",\n \"options\": {\n \"multiSelect\": false\n },\n \"choices\": [\n {\n \"choiceId\": \"1\",\n \"display\": \"red\",\n \"textual\": false\n },\n {\n \"choiceId\": \"2\",\n \"display\": \"green\",\n \"textual\": false\n },\n {\n \"choiceId\": \"3\",\n \"display\": \"other\",\n \"textual\": true\n }\n ]\n}", "language": "json" } ] } [/block] The following table contains information on each of the members of the multiple choice question: [block:parameters] { "data": { "h-0": "Name", "h-1": "Type", "h-2": "Description", "0-0": "**options**", "0-1": "Object", "0-2": "The **options** object defines whether multiple choices can be selected via **multiSelect**. For single answer (radio buttons) **mc** questions, it will be false, and for multiple answer (checkbox), it will be true.", "1-0": "**choices**", "1-1": "Array of Objects", "1-2": "The **choices** array contains **choice** objects. (Choice randomization defined in the survey may affect the order of this array.) A choice has an **id** that will be used to specify it as selected (see [Updating a Survey Session](doc:managing-survey-sessions#updating-a-survey-session)), **display** is the choice text, and **textual** is defined if this choice allows a textual response." }, "cols": 3, "rows": 2 } [/block] #### Text Entry (te) The following JSON shows an example text entry question: [block:code] { "codes": [ { "code": "{\n \"questionId\": \"QID3\",\n \"type\": \"te\",\n \"display\": \"Tell me why it's your favorite color\",\n \"options\": {}\n}", "language": "json" } ] } [/block] Text entry questions don't have choices or any options. They accept any textual response. #### Descriptive Block (db) The following shows an example of a descriptive block question: [block:code] { "codes": [ { "code": "{\n \"questionId\": \"QID7\",\n \"type\": \"db\",\n \"display\": \"Thank you for taking this survey. Please answer truthfully.\",\n \"options\": {}\n}", "language": "json" } ] } [/block] A **db** question is simply used to display text information, an image, or some other file to a respondent. You cannot answer a **db** question. [block:api-header] { "title": "Updating a Survey Session" } [/block] To record the respondent's answers, use the [Update Session](doc:update-session) API. The following code example shows how to use this API: [block:code] { "codes": [ { "code": "# Update Survey Session\n\nimport os\nimport requests\n\n# Setting user Parameters\napiToken = os.environ[\"Q_API_TOKEN\"]\ndataCenter = os.environ[\"Q_DATA_CENTER\"]\n\nsurveyId = \"SV_eyRJDHHhxbvI6aN\"\nsessionId = \"FS_xfJgWwTtRXSLFD3\"\n \nbaseUrl = \"https://{0}.qualtrics.com/API/v3/surveys/{1}/sessions/{2}\".format(dataCenter, surveyId, sessionId)\nheaders = {\n \"x-api-token\": apiToken,\n \"Content-Type\": \"application/json\"\n }\n\ndata = { \n \"advance\": False,\n \"embeddedData\": {\n \"username\": \"johns\"\n },\n \"responses\": {\n \"QID1\": {\n \"3\": {\n \"selected\": True\n }\n }\n }\n}\nresponse = requests.post(baseUrl, json=data, headers=headers)\nprint(response.text)\n", "language": "python" } ] } [/block] The previous example chooses answer three to the first multiple choice question and does not advance to the next question. An example POST request body is shown below: [block:code] { "codes": [ { "code": "{\n \"advance\": true,\n \"embeddedData\": {\n \"additionalEmbeddedData\": \"something new\"\n },\n \"responses\": {\n \"QID1\": {\n \"1\": {\n \"selected\": true\n }\n },\n \"QID2\": \"It's a nice color.\"\n }\n}", "language": "json" } ] } [/block] The following table provides information on the members in the request: [block:parameters] { "data": { "h-0": "Name", "h-1": "Type", "h-2": "Description", "0-0": "**advance**", "0-1": "Boolean", "0-2": "The **advance** field is used indicate whether to move to the next set of questions or save a respondent's current progress without moving on. Specify **true** to move to the next page or **false** to save current responses and come back later. When **advance** is **true**, it will run through any validation specified in the survey. If validation fails the same set of questions will be returned in the response body with a message about why validation failed.", "1-0": "**embeddedData**", "1-1": "Object", "1-2": "Any additional **embeddedData** can be set here.", "2-0": "**responses**", "2-1": "Object", "2-2": "The **responses** object contains the respondent's answers to questions. The **responses** object is a mapping from question id to question response. The response format is different for each question type and is detailed in the next section. Descriptive block (db) questions do not accept responses so they should not be included in the responses object." }, "cols": 3, "rows": 3 } [/block] ## Response Types There are two types of responses, multiple choice (mc) responses and text entry (te) responses. Descriptive block (db) questions do not have a response. ### Multiple Choice Response Types (mc) There are two formats of multiple choice response types: 1. An explicit response format 2. A "fuzzy" response format. #### Multiple Choice Explicit Response The explicit response format tells the API exactly which choices are selected and any textual response associated with that choice. It is an object with choice id keys that map to an object with a **selected** and **text** key. The following example shows an explicit answer to a multiple choice question: [block:code] { "codes": [ { "code": "\"QID1\": {\n \"3\": {\n \"selected\": true,\n \"text\": \"blue\"\n }\n}", "language": "json" } ] } [/block] In this example, answer 3 is selected for **QID1** and the **textual** response was **blue**. If **multiSelect** (in the **options** object of each **choice** in the **choices** array) is true for the **mc** question, include multiple choice IDs in the **QID** object. Any choices not included in the response are considered unselected. The following JSON shows an example of multiple choices: [block:code] { "codes": [ { "code": "\"QID1\": {\n \"1\": {\n \"selected\": true\n },\n \"2\": {\n \"selected\": true\n },\n \"3\": {\n \"selected\": true,\n \"text\": \"blue\"\n }\n}", "language": "json" } ] } [/block] #### Multiple Choice Fuzzy Response Using the fuzzy response format is useful for loosely matching against the choice texts. It lets Qualtrics figure out which choice should be selected based on the text of the response. For example, you ask "What if your favorite color?" with choices "Crimson Red", "Forest Green", and "Sky Blue". If the respondent responds with "red," the API will determine that "Crimson Red" is the appropriate match and mark that choice as selected. The following example shows how to supply a fuzzy match to a question: [block:code] { "codes": [ { "code": "\"QID1\": {\n \"fuzzySearch\": \"red\",\n \"maxMatches\": 1\n}", "language": "text" } ] } [/block] The **maxMatches** field can be set to select multiple choices if desired. It uses some very basic string matching to determine which choice should be selected. Because of the simple nature of the algorithm, it might match too many choices or no choices at all, in which case an error will be returned. See the example error response formats of the [Update Session](doc:update-session) API for details. ### Text Entry Response A text entry (te) response is simply a string. The following example shows such a response: [block:code] { "codes": [ { "code": "\"QID2\": \"It's a nice color.\"", "language": "json" } ] } [/block] [block:api-header] { "title": "Getting the Current Survey Session" } [/block] To get the respondent's current session use the [Get Session](doc:get-session) API. The following example shows how to use the Get Survey Session API: [block:code] { "codes": [ { "code": "# Get Survey Session\n\nimport os\nimport requests\n\n# Setting user Parameters\napiToken = os.environ[\"Q_API_TOKEN\"]\ndataCenter = os.environ[\"Q_DATA_CENTER\"]\n\nsurveyId = \"SV_eyRJDHHhxbvI6aN\"\nsessionId = \"FS_xfJgWwTtRXSLFD3\"\n\nbaseUrl = \"https://{0}.qualtrics.com/API/v3/surveys/{1}/sessions/{2}\".format(dataCenter, surveyId, sessionId)\nheaders = {\n \"x-api-token\": apiToken,\n \"Content-Type\": \"application/json\"\n }\n\nresponse = requests.get(baseUrl, headers=headers)\nprint(response.text)", "language": "python" } ] } [/block] It will return the current set of questions that should be asked to the respondent as well as any saved answers. It has the same format described [above](#section-survey-session-response-object). From here you can use the [Updating a Survey Session](#updating-a-survey-session) API to provide answers. [block:api-header] { "title": "Potential Errors" } [/block] If the original [Create Session](doc:create-session) API request is successful, status code 201 is returned along with the session body. However, keep in mind that to start a session, the **surveyId** must correspond to a survey that is compatible with this API and the proper authorization headers must be included with the initial request. (See [Authentication](doc:authentication) for more information.) ## Create Session Errors You may encounter errors with the following formats upon attempting to start a session. In the case of a **bad survey** error, you will need to ensure your survey contains no incompatible questions and that it is currently started, active, and unexpired. In the case of an **authentication** error, you will need to ensure that the correct [X-API-TOKEN](doc:authentication) header was included with your request. In the case of a **survey not found** error, you will need to ensure that the **surveyId** you are using corresponds to an existing survey. The following shows examples of each of these errors: [block:code] { "codes": [ { "code": "{\n \"error\": \"BadSurvey\",\n \"desc\": \"survey is incompatible.\",\n \"incompatibilities\": {\n \"questions\": {\n \"QID1\": [\n \"Unsupported question type Matrix-Likert-SingleAnswer\"\n ],\n \"QID2\": [\n \"Unsupported question type TE-FORM\"\n ]\n }\n }\n}", "language": "json", "name": "400 Bad Survey" }, { "code": "{\n \"error\": \"BadSurvey\",\n \"desc\": \"survey is inactive.\"\n}", "language": "json", "name": "400 Bad Survey" }, { "code": "{\n \"error\": \"NotFound\"\n}", "language": "json", "name": "404 Survey Not Found" } ] } [/block] Note that errors with the same formats can occur for the same reasons when attempting to use the [Get Session](doc:get-session) or [Update Session](doc:update-session) APIs. ## Updating Session Errors There are some additional errors you should be aware of when updating sessions. In the case of a **validation** error, the session cannot proceed because of validation logic within the survey. The respondent will have to pick different answers. The **problems** field will contain an array of objects, each with an ID of a question that did not pass validation and its associated message. An **outdated session** error means that the session has expired and can no longer be updated. Lastly, if you use the fuzzy matching feature to select responses, a **fuzzy** error may occur if there are no matches or if the number of matches is greater than **maxMatches**. The following gives examples of these errors: [block:code] { "codes": [ { "code": "{\n \"error\": \"ValidationErrors\",\n \"problems\": [\n {\n \"questionId\": \"QID1\",\n \"message\": \"Please select Choice 2\"\n }\n ]\n}", "language": "json", "name": "400 Validation Error" }, { "code": "{\n \"error\": \"OutdatedSession\"\n}", "language": "json", "name": "400 Outdated Session" }, { "code": "{\n \"error\": \"FuzzyNoMatch\"\n}", "language": "json", "name": "400 Fuzzy Error" } ] } [/block] [block:callout] { "type": "info", "title": "Documentation Change (9/17/18)", "body": "The \"maxSelectable\" option that was previously documented was never implemented. Instead, the \"multiSelect\" option, which accepts a true/false value, is used for questions that accept multiple answers. The documentation has been updated accordingly. This correction reflects the actual result of the API, which has not changed in functionality." } [/block]