Summary
The Risk Selection API is a flexible question and answer engine which can facilitate generating a custom questionnaire, and handling the sequence of evaluating answers, asking additional questions, and ultimately, returning an outcome.
Authorization
All endpoints on this API are secured with OAuth 2.0, using the client_credentials grant type.
Environment | External URL |
---|---|
DEV |
|
UAT |
|
PROD |
Example HTTP Request
POST /oauth/token HTTP/1.1
Authorization: Basic {{base64 encoded clientId:clientSecret}}
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"api_product_list_json": [
"issuance-dev",
"rating-dev"
],
"token_type": "Bearer",
"access_token": "",
"expires_in": 3599,
}
Field | Type | Description |
---|---|---|
api_product_list_json |
array |
Array of strings indicating the authorities granted to the client. |
token_type |
string |
This value should be placed in the Authorization header for API requests.
|
access_token |
string |
This value should be placed in the Authorization header for API requests.
|
expires_in |
number |
The time in seconds when the access token will expire. |
Dynamic Documentation
/api/endpoints
Call this endpoint first to determine which endpoints are available to you, as a consumer. This API serves multiple business divisions, and a variety of complex insurance products. Therefore, not all endpoints apply to all consumers.
Example HTTP Request
GET /api/endpoints HTTP/1.1
Authorization: Bearer {{access_token}}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"endpoints": [
"/api/example1",
"/api/example2"
]
}
/api/docs
Call this endpoint to get specific request and response body details, which can vary based on factors such as the consumer, business division and product.
The /api/docs
endpoint provides dynamic documentation based on those factors.
Determine the request body required by an endpoint.
Example HTTP Request
POST /api/docs HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"type": "request",
"endpoint": "/api/example1",
"format": "json",
"scope": {
"state": "OH"
}
}
Determine the response body returned by an endpoint.
Example HTTP Request
POST /api/docs HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"type": "response",
"endpoint": "/api/example1",
"format": "json"
}
Field | Type | Required | Description |
---|---|---|---|
type |
string |
true |
Valid values: |
endpoint |
string |
true |
One of the available API endpoints. |
format |
string |
true |
Valid values: |
scope |
object |
false |
Additional scoping necessary for the request. |
Endpoints
/api/questionnaire
Retrieves a list of questions. Call /api/docs
to see the request/response structure.
HTTP Status Codes
Successful Responses
200 - OK
The request has succeeded.
Note: Please refer to /api/docs for documentation regarding successful response bodies.
Client Errors
400 Bad Request
The server could not understand the request due to invalid syntax.
Most 400 responses will contain the JSON structure in the example below.
The field errors
will contain an array of objects.
Each object will have the fields: category
, code
and message
.
Some 400 responses may also contain additional JSON structure.
Example HTTP Response
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"errors": [
{
"category": "Invalid Request",
"code": "INVALID",
"message": "The request was missing some piece of data."
}
]
}
Field | Description |
---|---|
category |
The category of the error. |
code |
This value is meant to be read by code, so that the consuming system can respond to a give error programmatically. |
message |
A human readable message describing the error. |
401 - Unauthorized
Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response.
Example HTTP Response
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"fault": {
"faultstring": "Invalid Access Token",
"detail": {
"errorcode": "keymanagement.service.invalid_access_token"
}
}
}
403 - Forbidden
The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401, the client’s identity is known to the server.
404 - Not Found
The server can not find the requested resource. This means that the endpoint is not available on this API.
Server Errors
500 - Internal Server Error
The server has encountered a situation it doesn’t know how to handle.
Example HTTP Response
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"timestamp": "2021-05-01T12:00:00.000-0400",
"status": 500,
"error": "Internal Server Error",
"message": "Something went wrong. Please contact CustomerCare@GAIG.COM",
"path": "/api/path"
}
501 - Not Implemented
The request method is not supported by the server and cannot be handled.
Note: This response may be returned if the endpoint is not relevant for the client. Please refer to /api/docs for the list of endpoints available for a client.
Example HTTP Response
HTTP/1.1 501 Not Implemented
Content-Type: application/json
{
"timestamp": "2021-05-01T12:00:00.000-0400",
"status": 501,
"error": "Not Implemented",
"message": "API not yet implemented.",
"path": "/api/path"
}
Answer Session Documentation
Key Concepts
As a consumer of the Risk Selection API, there are several concepts that will make it easier to understand the following documentation. The table below provides a description of important terminology that should make it easier to understand how the API operates and how you might build your integration with it.
Question Set
Simply put, a Question Set is an inventory of questions that have been authored pertaining to a particular objective. While all Question Sets are authored using a common model, each implementation may have additional fields to help facilitate and inform the consuming system.
Unique to each Question Set is the model for its Context Data.
Context Data
The Context Data model, which contains Context Entities, is uniquely defined per Question Set and is a part of what is used by Risk Selection to identify which Groups will be included on a Questionnaire.
The /api/docs/contextData
endpoint will provide details about the data model for a particular Question Set.
Context Entity
A Context Entity is a term describing any JSON object that exists within the Context Data which may affect the Answer Session.
At a minimum, a Context Entity has an id
field which must be unique across all context entities, no matter where they exist in the Context Data model. The id
is the instance identifier for that object. In addition to the id
field, a Context Entity may have additional fields which are used to determine which group(s) to add to the Questionnaire.
Important: Proper implementation of the Risk Selection API requires that if the values of a Context Entity object need to change, then the id
field must also change, as it now represents a different Context Entity instance.
Should a Context Entity cause questions to appear on a questionnaire, the group containing those questions (along with any answers) are tied to that object. This relationship is visible within the JSON of the Group via the contextIds
field. When a group has a contextIds
field, it is referred to as a Context-Based Group. A Context-Based group may be tied to one or more Context Entities.
Once a Group is added to a questionnaire based on a Context Entity, it is only removed if all Context Entities identified by its contextIds
field are removed in a request to /api/updateAnswerSession
.
Answer Session
A new Answer Session is created, saved, and returned when a consumer calls /api/createAnswerSession
. It is a container which encapsulates all data about a specific Questionnaire.
The answerSessionId
field on an Answer Session identifies that unique record within Risk Selection’s persisted storage and is what allows a consumer to interact with it via the other Answer Session endpoints. An Answer Session is what is returned by all four Answer Session APIs.
An optimum integration with Risk Selection is one where the consumer only has to persist the answerSessionId
and leverages Risk Selection APIs to retrieve the Answer Session and update it. Everything needed to display an instance of a Questionnaire and match up the Context Data to your model is included in the Answer Session.
Questionnaire
A Questionnaire is an individual instance of groups of questions, persisted within an Answer Session. In addition to the groups/questions, it also includes any answers that have been provided by the consumer, along with an Action for each answered question.
For convenience purposes, it includes two fields. questionsAsked
and questionsAnswered
, to indicate how many questions have been asked and how many have been answered, without having to traverse the JSON data.
Groups
A Group is merely a construct which can contain one or more questions. This allows the author of a Question Set to tie one or more questions together relating to a particular subject and to have them represented together on a Questionnaire’s JSON data. There are three types of Groups, however, as a consumer of Risk Selection, it is not really necessary to be able to distinguish the difference.
General Group: A Group which is added to a Questionnaire regardless of what Context Entities exist in the Context Data.
Context-Based Groups: A Group which is added to a Questionnaire based on what Context Entities exist in the Context Data object. The Context Entity (or Context Entities) which cause a Group to be added to a Questionnaire will be identified in the contextIds
array field of the Group. The contextIds
field is exclusive to this type of Group. If the consuming system, which provided the Context Data to Risk Selection, has additional information about the Context Entities identified in the contextIds
field, it may be beneficial to include that information when this Group is displayed, so that the user has the appropriate context to answer the question.
Action-Based Group: A Group which is added to a Questionnaire based on an answer that was provided to a question in another Group. This should not to be confused with a follow-up question, as follow-up questions appear within a single Group.
Documentation Endpoints
Some data used in requests and seen in responses may vary based on the consumer making the request or the Question Set. The following documentation endpoints allow you to interrogate Risk Selection to find out specifics for you or the Question Set you’re interacting with.
/api/docs/lines
Call the /api/docs/lines
endpoint to get the valid values for the line(s) of business configured for your credentials. These are the values used in the line
input field for APIs on this service.
Example HTTP Request
POST /api/docs/lines HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
TODO
}
}
/api/docs/contextData
This endpoint is used to show what the Context Data model looks like for a particular Question Set.
See the Key Concepts section for more information on Context Data and Context Entities*.
-
input
: Required.-
line
: Required. Abbreviated line of business. Call/api/docs/lines
to see the valid values. -
details
: Optional. Set totrue
to show additional details about the fields, including example values.
-
Example HTTP Request
POST /api/docs/contextData HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"input": {
"line": "EXAMPLE",
"details": true
}
}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"contextData": {
"topics": [
{
"id": {
"desc": "Specify a unique (across all context entities) identifier to represents this instance of the topic.",
"required": true
},
"value": {
"desc": "Specify the topic value.",
"required": true,
"validValues": [
"space",
"trivia",
"work"
]
}
}
]
}
}
}
/api/docs/questionSetCriteria
Call this endpoint to get details about the criteria
keys you can provide, and the potential values which can be used to select/filter the groups of questions returned by /api/questionSet
.
-
input
: Required.-
line
: Required. Abbreviated line of business. Call/api/docs/lines
to see the valid values.
-
Example HTTP Request
POST /api/docs/questionSetCriteria HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"input": {
"line": "EXAMPLE"
}
}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"criteriaInfo": {
"groupId": [
"riskSelectionFeedback",
"riskSelectionGeneral",
"favorites",
"followup",
"nonsenseQuestions",
"triviaSpace"
],
"contextType": [
"actionIds",
"general",
"topics"
],
"topics": [
"feedback",
"nonsense",
"riskSelection",
"space",
"trivia",
"work"
],
"actionIds": [
"riskSelectionHowDidYouHear_fromNOYB"
]
}
}
}
Answer Session Endpoints
/api/createAnswerSession
Use this endpoint to generate a new questionnaire
about the entities in contextData
and begin a new answerSession
. The answerSession
keeps track of the questions you have answered.
-
input
: Required.-
line
: Required. Abbreviated line of business. Call/api/docs/lines
to see the valid values. -
date
: Required. The date to determine which version of questions to use/expect. Note: Only the year, month, and day is considered. If timestamp information is included, it will be converted to Eastern Time and truncated. -
contextData
: Required. The data that identifies unique entities about which you are acquiring questions. Call/api/contextData
for more information, as contextData may be unique for eachQuestionSet
. Provide thecontextData
as it exists at the time you need to create ananswerSession
. If there are no entities to be included when you are creating ananswerSession
, simply provide an empty object. Once you have ananswerSessionId
, you can indicate changes tocontextData
(as entities are added or removed) when you call/api/updateAnswerSession
. -
questionnaire
: Optional. If you are consuming the data from/api/questionSet
and are implementing the specifications to create aquestionnaire
within your application, you can pass it along on with your request to create a newanswerSession
.
-
-
options
: Optional.-
questionnaireDetails
: Optional. Set tofalse
to have only the essential fields in thequestionnaire
returned to you. Fields such as group label, questionText, options, etc. will be left out. When creating ananswerSession
, this is not recommended unless you are calling/api/questionSet
to cache these details ahead of time. Default istrue
.
-
Example HTTP Request
POST /api/createAnswerSession HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"input": {
"line": "GL",
"date": "2020-01-01",
"contextData": {
"classCodes": [
{
"id": "A24",
"value": "12345"
}
]
}
}
}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"answerSession": {
"action": {
"status": "UNKNOWN",
"workflowControl": "CONTINUE"
},
"answerSessionId": "1594520811622000024",
"contextData": {
"classCodes": [
{
"id": "A24",
"value": "12345"
}
]
},
"date": "2020-01-01",
"line": "GL",
"questionnaire": {
"groups": [
{
"groupId": "Group1",
"label": "General Eligibility",
"questions": [
{
"questionId": "Question1a",
"questionText": "Does the insured have existing coverage with another carrier?",
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
},
{
"questionId": "Question1b",
"questionText": "Has coverage for this insured been canceled during the prior three years for any reason other than change in carrier appetite?",
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
}
],
"status": "UNKNOWN"
},
{
"groupId": "Group2",
"contextIds": ["A24"],
"label": "Class Code 12345",
"questions": [
{
"questionId": "Question23",
"questionText": "How many miles away is the nearest hospital?",
"answerType": "INPUT",
"options": [
{
"type": "INTEGER"
}
]
}
],
"status": "UNKNOWN"
}
],
"status": "UNKNOWN"
}
}
}
Please see the /api/updateAnswerSession instructions for additional information on how to interpret the response. The example shown above will be continued in the /api/updateAnswerSession instructions, where you’ll also see how to submit your questionnaire
with answers on it to have them validated and saved, and to get a status (ACCEPT
, REFERRAL
, DECLINE
, etc.) based on the answers.
/api/updateAnswerSession
Update your answerSession
by passing in your answerSessionId
and the updated questionnaire
. Call this as a user chooses/provides each answer, after they have completed a certain number of questions, or after they’ve answered all questions — The choice is yours.
Answering Questions
Using the questionnaire
that was returned to you as a base, you can provide answers to questions by adding an answer
field within each question object and setting its value. The answers provided on the questionnaire
will be checked and, if valid, saved.
How to format an answer
is based on the answerType
of the question
:
-
SELECT
: Provide a single value using the optionId of the option that was chosen. Ex:"answer": "Yes"
-
INPUT
: Provide a single value with the user’s input. Ex:"answer": 42
-
MULTI_SELECT
: Provide an array using alloptionId
s of theoption
s that were chosen. Ex:"answer": [ "Yellow", "Red", "Blue" ]
-
MULTI_INPUT
: Provide an array of objects, each containing anoptionId
andvalue
field, where theoptionId
corresponds to anoption
and thevalue
is what the user typed into that option. Ex:"answer": [ { "optionId": "Length", "value": 250}, { "optionId": "Width", "value": 50 } ]
Note: When you are providing answers to /api/updateAnswerSession
, you do not need to provide every field in the questionnaire
that was sent to you. If you prefer to just re-use the original JSON, that is fine, too. The extra fields will be ignored. The required fields are those which provide structure or which uniquely identify an object. For example, group objects need the groupId
and contextIds
fields to uniquely identify the group. For questions, just include the questionId
and add an answer
field with the answer to the question. Please maintain the original order that the groups were presented in.
-
input
: Required.-
answerSessionId
: Required. TheanswerSessionId
returned when you created your initialanswerSession
. -
date
: Specific Usage Only. The usage of thedate
field here is only intended if your consumption of the service includes complete implementation of the details provided by/api/questionSet
. When provided, if the date is different from the date that was provided last, the service will attempt to rebuild yourquestionnaire
based on the new date. When the service attempts to validate thequestionnaire
provided oninput
, if you have included any of the groups or questions that no longer exist, you will receive a400
response indicating which groups or questions were not valid based on the changed date. If yourquestionnaire
is valid, but any group from your stored answerSession does not exist based on the new date, those answers will be permanently discarded. If the group still exists, but a question within that group does not, the answer to that question will be permanently discarded. -
contextData
: Optional. If no entities have been added or removed fromcontextData
, please omit it from your request. If entities are added or removed, you must provide the completecontextData
object. If brand-new entities are added, new groups may appear with questions about those entities. If entities are removed, the service will perform a cleanup operation to discard any groups that no longer apply, along with their answers. If the same entity (identified with the same context id) is added on a subsequent request, the service will restore the answers previously given. If, on the same request, you have provided answers tied to that entity, they will overwrite the answers that were restored. -
questionnaire
: Required. Updatedquestionnaire
to be validated, saved, and returned to you with updated actions.
-
-
options
: Optional.-
questionnaireDetails
: Optional. Set tofalse
to have only the essential fields in thequestionnaire
returned to you. Fields such as group label, questionText, options, etc. will be left out. Default istrue
.
-
Example HTTP Request
POST /api/updateAnswerSession HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"input": {
"answerSessionId": "1594520811622000024",
"questionnaire": {
"groups": [
{
"groupId": "Group1",
"questions": [
{
"questionId": "question1a",
"answer": "No"
},
{
"questionId": "question1b",
"answer": "No"
}
]
},
{
"groupId": "Group2",
"contextIds": ["A24"],
"questions": [
{
"questionId": "Question23",
"answer": 250
}
]
}
]
}
}
}
Example HTTP Response
In the example response below, please note the answerSession.action
, the questionnaire.status
, each group.status
, as well as each question.action
. These are provided to help indicate which groups and questions may have contributed to the answerSession.action
. In this example, the answer of 250
to Question23
triggered the question.action.message
, which informs the user that their answer means Ambulance services coverage will be excluded.
HTTP/1.1 200 OK
Content-Type: application/json
{
"answerSession": {
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answerSessionId": "1594520811622000024",
"contextData": {},
"date": "2020-07-01",
"line": "GL",
"questionnaire": {
"status": "ACCEPT",
"groups": [
{
"groupId": "Group1",
"status": "ACCEPT",
"label": "General Eligibility",
"questions": [
{
"questionId": "question1a",
"questionText": "Does the insured have existing coverage with another carrier?",
"answer": "No",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
},
{
"questionId": "question1b",
"questionText": "Has coverage for this insured been canceled during the prior three years for any reason other than change in carrier appetite?",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answer": "No",
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
}
]
},
{
"groupId": "Group2",
"contextIds": ["A24"],
"status": "ACCEPT",
"label": "Class Code 12345",
"questions": [
{
"questionId": "Question23",
"questionText": "How many miles away is the nearest hospital?",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Coverage for Ambulance services will be excluded due to the distance to the nearest hospital."
},
"answer": 250,
"answerType": "INPUT",
"options": [
{
"type": "INTEGER"
}
]
}
]
}
]
}
}
}
Interpreting the Response
AnswerSession
An answerSession
has four fields:
-
The
line
anddate
fields are just references to the values passed in from the original request. -
The
contextData
field is the same as the value passed in, however, it may be modified to include additional information about its contents. -
The
action
field is an object which provides information about the answers provided in an update request:-
The
status
field is the overall status. It indicates the most significant status that all groups with answered questions have had on the answerSession. In some circumstances the status may also be affected by the provided contextData. It will be eitherACCEPT
,REFERRAL
,DECLINE
,INVALID
, orUNKNOWN
. TheINVALID
code appears when one or more answers provided were not valid. The specific answers which were invalid will include more information about why. TheUNKNOWN
code appears when no answers have been provided yet. -
The
workflowControl
field indicates how to proceed. It lets you know if you shouldCONTINUE
orSTOP
answering questions and/or making changes to yourcontextData
. A value ofSTOP
is only used to indicate that one or more of the answers provided resulted in a situation where the author of the question set does not need the user to continue answering questions. However, if a user accidentally provided the wrong answer to a question and corrects it, theSTOP
does not prevent you from letting them correct the answer and updating theanswerSession
. Lastly, theVALIDATE
status will appear in concert with ananswerSession.action
ofINVALID
when one or more answers was not accepted and should be corrected. -
The
message
field may be provided to give additional feedback that should be presented to the user.
-
Questionnaire
A Questionnaire has four fields:
-
The
status
field will indicate the most significantstatus
of all groups with questions answered. -
The
questionsAsked
field indicates the total number of questions across all groups in the Questionnaire. -
The
questionsAnswered
field indicates the number of questions which have valid answers. -
The
groups
field is the ordered list of groups of questions.
Groups
A Group is just a collection of questions related to a particular topic. Fields for a group are described below:
-
The
groupId
field is the unique identifier for the grouping of these questions. A group may exist in your questionnaire more than once if it is a Context-based group. See contextIds. -
The
contextIds
field is used to indicate which context entities from yourcontextData
this particular group of questions is about. This is what enables a group of questions to be asked multiple times — such as when there are multiple entities. General and Action-based groups will never have acontextIds
field. -
The
status
field will indicate the most significantstatus
of all the answered questions in that group. -
The
label
field is the friendly name for this group of questions. In most circumstances, you should display the label above the group of questions. Note: If a group hascontextIds
, it may be important to also indicate to the user what entity the questions in a particular group are about. For example, if the questions are about a particular location and you can provide them with the location name, number, or perhaps a pop-up or hover text that provides them more details, it will help make it easier for them to answer the questions appropriately. -
The
description
field is additional detail that you may want to display along with the label. This field may not always be defined. -
The
questions
field is the ordered list of questions in this group. Note: Some questions may have one or more follow-up questions, depending on the answer selected/provided. These follow-up questions will not appear in the group until you have submitted the answer back to/api/updateAnswerSession
.
Questions
A Question includes that data needed to present a question to a user and, once answered, will contain information about the selected/provided answer:
-
The
questionId
field is the unique identifier for the question. -
The
originatingId
field will appear if this question was added to the questionnaire as a follow-up to another question. The value will be the questionId of that question. -
The
questionText
field contains the actual question to be presented to the user. -
The
questionDetail
field may be present if there is additional information that should be presented to the user alongside thequestionText
. -
The
answerType
field specifies the type of question and informs the consuming system of how to provide the answer. See the Answering Questions section above for more information. -
The
options
field indicates information about how to collect the answer to the question. See the Answering Questions section above for more information. -
The
action
field is present only when the question has been answered. This field is similar to the one on the answerSession, but provides detail specific to the provided answer.-
The
status
indicates how the answer will affect the group.status. -
The
workflowControl
indicates if you should CONTINUE or STOP asking questions based on this answer specifically, or if the answer triggered one or more FOLLOWUP questions. If it triggered additional questions, they will be included in thequestionnaire
of the response and will indicate an originatingId to let you know which question triggered the follow-up. -
In some cases, there may also be a
message
field on the question.action with text that should be presented to the user based on their answer. If the status was marked INVALID, the message will inform the user about the invalid answer. Otherwise, it may provide them with useful information about what selecting/providing that particular answer means.
-
How to tell when there are no more questions
Once you have answered all of the questions on the questionnaire
and have submitted them back to /api/updateAnswerSession
, if no new questions show up in the response, you are done*. You don’t necessarily need to parse through the entire questionnaire
just to see if there are new questions — The questionsAsked
and questionsAnswered
fields can be used as a quicker indication. So, if you provided a valid answer to all questions, those two fields in the /api/updateAnswerSession
response will indicate if there are new unanswered questions. * Note: If you make changes to the entities in your contextData
, you will need to submit a request to /api/updateAnswerSession
again with the current/complete contextData, which may cause new questions to be returned in the response if new entities were added.
/api/getAnswerSession
Pass in just your answerSessionId
to retrieve the answerSession
.
-
input
: Required.-
answerSessionId
: Required. TheanswerSessionId
returned when you created your initialanswerSession
.
-
-
options
: Optional.-
questionnaireDetails
: Optional. Set tofalse
to have only the essential fields in thequestionnaire
returned to you. Fields such as group label, questionText, options, etc. will be left out. Default istrue
.
-
Example HTTP Request
POST /api/getAnswerSession HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"input": {
"answerSessionId": "1594520811622000024"
}
}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"answerSession": {
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answerSessionId": "1594520811622000024",
"contextData": {},
"date": "2020-07-01",
"line": "GL",
"questionnaire": {
"status": "ACCEPT",
"groups": [
{
"groupId": "Group1",
"status": "ACCEPT",
"label": "General Eligibility",
"questions": [
{
"questionId": "question1a",
"questionText": "Does the insured have existing coverage with another carrier?",
"answer": "No",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
},
{
"questionId": "question1b",
"questionText": "Has coverage for this insured been canceled during the prior three years for any reason other than change in carrier appetite?",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answer": "No",
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
}
]
},
{
"groupId": "Group2",
"contextIds": ["A24"],
"status": "ACCEPT",
"label": "Class Code 12345",
"questions": [
{
"questionId": "Question23",
"questionText": "How many miles away is the nearest hospital?",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Coverage for Ambulance services will be excluded due to the distance to the nearest hospital."
},
"answer": 250,
"answerType": "INPUT",
"options": [
{
"type": "INTEGER"
}
]
}
]
}
]
}
}
}
/api/setAnswerSession
Pass in your answerSessionId
, date
, contextData
, and questionnaire
to replace your entire answerSession
. This allows updating the answerSession
to be based on the new inputs without having to create one under a new answerSessionId
.
-
input
: Required.-
answerSessionId
: Required. TheanswerSessionId
returned when you created your initialanswerSession
. -
date
: Required. The date to determine which version of questions to use/expect. Note: Only the year, month, and day is considered. If timestamp information is included, it will be converted to Eastern Time and truncated. -
contextData
: Required. The data that identifies unique entities about which you are acquiring questions. -
questionnaire
: Required. Thequestionnaire
to be validated, saved, and returned to you with updated actions.
-
-
options
: Optional.-
questionnaireDetails
: Optional. Set tofalse
to have only the essential fields in thequestionnaire
returned to you. Fields such as group label, questionText, options, etc. will be left out. Default istrue
.
-
Example HTTP Request
POST /api/setAnswerSession HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
Content-Type: application/json
{
"input": {
"answerSessionId": "1594520811622000024",
"date": "2020-01-01",
"contextData": {
"classCodes": [
{
"id": "A24",
"value": "12345"
}
]
}
"questionnaire": {
"groups": [
{
"groupId": "Group1",
"questions": [
{
"questionId": "question1a",
"answer": "No"
},
{
"questionId": "question1b",
"answer": "No"
}
]
},
{
"groupId": "Group2",
"contextIds": ["A24"],
"questions": [
{
"questionId": "Question23",
"answer": 250
}
]
}
]
}
}
}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"answerSession": {
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answerSessionId": "1594520811622000024",
"contextData": {},
"date": "2020-07-01",
"line": "GL",
"questionnaire": {
"status": "ACCEPT",
"groups": [
{
"groupId": "Group1",
"status": "ACCEPT",
"label": "General Eligibility",
"questions": [
{
"questionId": "question1a",
"questionText": "Does the insured have existing coverage with another carrier?",
"answer": "No",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
},
{
"questionId": "question1b",
"questionText": "Has coverage for this insured been canceled during the prior three years for any reason other than change in carrier appetite?",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE"
},
"answer": "No",
"answerType": "SELECT",
"options": [
{
"optionId": "Yes",
"label": "Yes"
},
{
"optionId": "No",
"label": "No"
}
]
}
]
},
{
"groupId": "Group2",
"contextIds": ["A24"],
"status": "ACCEPT",
"label": "Class Code 12345",
"questions": [
{
"questionId": "Question23",
"questionText": "How many miles away is the nearest hospital?",
"action": {
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Coverage for Ambulance services will be excluded due to the distance to the nearest hospital."
},
"answer": 250,
"answerType": "INPUT",
"options": [
{
"type": "INTEGER"
}
]
}
]
}
]
}
}
}
QuestionSet Endpoints
/api/questionSet
This endpoint can be used to query a Question Set using various input criteria. If you are looking to create a questionnaire
, please see the /api/createAnswerSession
API.
-
input
: Required.-
line
: Required. Abbreviated line of business. Call/api/docs/lines
to see the valid values. -
date
: Optional. The date is used to bring back questions as of this date. If not provided, the current date will be used. Only the year, month, and day is considered. If timestamp information is included, it will be converted to Eastern Time and truncated. Note: For some consumers, the date may be forced to the current date. -
criteria
: Optional. A list of one or more sets of criteria to filter the returned question data. If no criteria is provided, the entire questionSet will be returned. See the examples below for how to construct basic query criteria. Call/api/docs/questionSetCriteria
to see the criteria keys and the possible values for each.
-
Criteria
The structure of the criteria
list provides a limited means to filter using AND and OR logical operations. Each field/value listed in a single criterion object will be treated with a logical AND. For example, the following criteria will only match question groups where the type is "foo" and the category is "bar".
"criteria": [ {"type": "foo", "category": "bar"} ]
Each criterion object listed inside of criteria
will be treated as a logical OR. For example, If you take the criteria
from above, but you also wanted to return question groups where the "category" is "baz", regardless of what the "type" is, include a second criterion object:
"criteria": [ {"type": "foo", "category": "bar"}, {"category": "baz"} ]
Example HTTP Request
POST /api/questionSet HTTP/1.1
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"input": {
"line": "EXAMPLE",
"criteria": [ {"groupId": "triviaSpace"} ]
}
}
Example HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"questionSet": {
"groups": [
{
"groupId": "triviaSpace",
"label": "Space Trivia",
"description": "Let's test your knowledge!",
"questionOrder": [
"triviaSpaceCommonGalaxy",
"triviaSpaceColdestPlace",
"triviaSpaceDarkMatterPercent",
"triviaSpaceNumberOfPlanets",
"triviaSpaceLargestPlanet",
"triviaSpaceSmallestPlanet",
"triviaSpaceClosestStar",
"triviaSpaceApolloLast",
"triviaSpaceIceCreamMoonLanding"
],
"order": 500,
"contextType": "topics",
"contextScope": "all",
"topics": [
"trivia",
"space"
]
}
],
"questions": [
{
"questionId": "triviaSpaceIceCreamMoonLanding",
"questionText": "What flavor ice cream did Baskin-Robbins release in 1969 to commemorate America’s landing on the moon?",
"answerType": "SELECT",
"options": [
{
"optionId": "cakeWalk",
"label": "Cake Walk"
},
{
"optionId": "lunarCheesecake",
"label": "Lunar Cheesecake"
},
{
"optionId": "iceCreamPieintheSky",
"label": "Ice Cream Pie in the Sky"
},
{
"optionId": "blastoffBerry",
"label": "Blastoff Berry"
}
],
"evals": [
{
"evalId": "triviaSpaceIceCreamMoonLanding_eval",
"bindType": "DISCRETE",
"requiredQuestionIds": [
"triviaSpaceIceCreamMoonLanding"
],
"actions": [
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Wrong.",
"binding": "cakeWalk"
},
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Created in 1969, Lunar Cheesecake landed in stores the day after the first man landed on the moon to celebrate the accomplishment.",
"binding": "lunarCheesecake"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!",
"binding": "iceCreamPieintheSky"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": "blastoffBerry"
}
]
}
]
},
{
"questionId": "triviaSpaceDarkMatterPercent",
"questionText": "What percent of the universe is dark matter?",
"answerType": "INPUT",
"options": [
{
"optionId": "darkMatterPercent",
"type": "INTEGER"
}
],
"evals": [
{
"evalId": "triviaSpaceDarkMatterPercent_eval",
"bindType": "RANGE",
"validationMessage": "Enter a value between 0 and 100.",
"requiredQuestionIds": [
"triviaSpaceDarkMatterPercent"
],
"actions": [
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": [
0,
25
]
},
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Correct! Your answer was within 2% of 27!\n\nThe rest of the universe is around 68% dark energy, and less than 5% of the universe is made up of what we would consider “normal” matter. This means that roughly 80% of the mass of the universe is made up of material we cannot see. 🤓",
"binding": [
25,
30
]
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": [
30,
101
]
}
]
}
]
},
{
"questionId": "triviaSpaceColdestPlace",
"questionText": "What is the coldest place in the universe?",
"answerType": "SELECT",
"options": [
{
"optionId": "coldest1",
"label": "Boomerang Nebula"
},
{
"optionId": "coldest2",
"label": "Horsehead Nebula"
},
{
"optionId": "coldest3",
"label": "Ring Nebula"
},
{
"optionId": "coldest4",
"label": "Helix Nebula"
},
{
"optionId": "coldest5",
"label": "Owl Nebula"
}
],
"evals": [
{
"evalId": "triviaSpaceColdestPlace_eval",
"bindType": "DISCRETE",
"requiredQuestionIds": [
"triviaSpaceColdestPlace"
],
"actions": [
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Correct!\n\nThe Boomerang Nebula is one degree Kelvin which is -458 degrees Fahrenheit or -272.15 degrees Celsius. It is located in the Centaurus constellation and is colder than the background temperature of deep space.",
"binding": "coldest1"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope! It is pretty though, right?",
"binding": "coldest2"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Sorry, that is incorrect.",
"binding": "coldest3"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Wrong.",
"binding": "coldest4"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": "coldest5"
}
]
}
]
},
{
"questionId": "triviaSpaceLargestPlanet",
"questionText": "What is the largest planet in our solar system?",
"answerType": "SELECT",
"options": [
{
"optionId": "mercury",
"label": "Mercury"
},
{
"optionId": "venus",
"label": "Venus"
},
{
"optionId": "earth",
"label": "Earth"
},
{
"optionId": "mars",
"label": "Mars"
},
{
"optionId": "jupiter",
"label": "Jupiter"
},
{
"optionId": "saturn",
"label": "Saturn"
},
{
"optionId": "uranus",
"label": "Uranus"
},
{
"optionId": "neptune",
"label": "Neptune"
}
],
"evals": [
{
"evalId": "triviaSpaceLargestPlanet_eval",
"bindType": "DISCRETE",
"requiredQuestionIds": [
"triviaSpaceLargestPlanet"
],
"actions": [
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Seriously?",
"binding": "mercury"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!",
"binding": "venus"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": "earth"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Wrong.",
"binding": "mars"
},
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Everyone knows this!",
"binding": "jupiter"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Try again.",
"binding": "saturn"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "No.",
"binding": "uranus"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Back to school for you!",
"binding": "neptune"
}
]
}
]
},
{
"questionId": "triviaSpaceNumberOfPlanets",
"questionText": "How many planets are in the Solar System?",
"answerType": "INPUT",
"options": [
{
"optionId": "numPlanets",
"description": "Hint: The answer to this question changed in August of 2006!",
"type": "INTEGER"
}
],
"evals": [
{
"evalId": "triviaSpaceNumberOfPlanets_eval",
"bindType": "DISCRETE",
"validationMessage": "Enter a value greater than 0.",
"requiredQuestionIds": [
"triviaSpaceNumberOfPlanets"
],
"actions": [
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!"
},
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Correct! In August 2006 the International Astronomical Union (IAU) downgraded the status of Pluto to that of “dwarf planet.” This means that from now on only the rocky worlds of the inner Solar System and the gas giants of the outer system will be designated as planets.",
"binding": 8
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope. Not anymore. 🥺",
"binding": 9
}
]
}
]
},
{
"questionId": "triviaSpaceClosestStar",
"questionText": "What is the closest star to the Sun?",
"answerType": "SELECT",
"options": [
{
"optionId": "closestStar1",
"label": "Proxima Centauri"
},
{
"optionId": "closestStar2",
"label": "Kobayashi Maru"
},
{
"optionId": "closestStar3",
"label": "Alpha Centaur"
},
{
"optionId": "closestStar4",
"label": "Barnard's Stari"
},
{
"optionId": "closestStar5",
"label": "Wolf 359"
}
],
"evals": [
{
"evalId": "triviaSpaceClosestStar_eval",
"bindType": "DISCRETE",
"requiredQuestionIds": [
"triviaSpaceClosestStar"
],
"actions": [
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "It's a mere 40,208,000,000,000 km away!",
"binding": "closestStar1"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Ha! The Kobayashi Maru is a training exercise in the fictional Star Trek universe designed to test the character of Starfleet Academy cadets in a no-win scenario. The Kobayashi Maru test was first depicted in the opening scene of the film Star Trek II: The Wrath of Khan and also appears in the 2009 film Star Trek.",
"binding": "closestStar2"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!",
"binding": "closestStar3"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": "closestStar4"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Wrong.",
"binding": "closestStar5"
}
]
}
]
},
{
"questionId": "triviaSpaceSmallestPlanet",
"questionText": "What is the smallest planet in our solar system?",
"answerType": "SELECT",
"options": [
{
"optionId": "mercury",
"label": "Mercury"
},
{
"optionId": "venus",
"label": "Venus"
},
{
"optionId": "earth",
"label": "Earth"
},
{
"optionId": "mars",
"label": "Mars"
},
{
"optionId": "jupiter",
"label": "Jupiter"
},
{
"optionId": "saturn",
"label": "Saturn"
},
{
"optionId": "uranus",
"label": "Uranus"
},
{
"optionId": "neptune",
"label": "Neptune"
}
],
"evals": [
{
"evalId": "triviaSpaceSmallestPlanet_eval",
"bindType": "DISCRETE",
"requiredQuestionIds": [
"triviaSpaceSmallestPlanet"
],
"actions": [
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Yes! Mercury is the smallest planet in our solar system—only slightly larger than Earth's Moon.",
"binding": "mercury"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Seriously?",
"binding": "venus"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!",
"binding": "earth"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": "mars"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Wrong.",
"binding": "jupiter"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Back to school for you!",
"binding": "saturn"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": "uranus"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!",
"binding": "neptune"
}
]
}
]
},
{
"questionId": "triviaSpaceCommonGalaxy",
"questionText": "What type of galaxy is the most common in the universe?",
"answerType": "SELECT",
"options": [
{
"optionId": "galaxyType1",
"label": "Elliptical"
},
{
"optionId": "galaxyType2",
"label": "Spiral"
},
{
"optionId": "galaxyType3",
"label": "Irregular"
}
],
"evals": [
{
"evalId": "triviaSpaceCommonGalaxy_eval",
"bindType": "DISCRETE",
"requiredQuestionIds": [
"triviaSpaceCommonGalaxy"
],
"actions": [
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Correct!\n\nGalaxies are categorized as elliptical, spiral, or irregular. There are at least two trillion galaxies in the universe. Each galaxy is bound by gravity and consists of stars, dust, interstellar gas, and dark matter. They range in size from a few billion stars to one hundred trillion stars. The oldest and most distant observed galaxy is actually 32 billion light years from Earth and is located in the constellation Ursa Major.",
"binding": "galaxyType1"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!",
"binding": "galaxyType2"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "That is incorrect!",
"binding": "galaxyType3"
}
]
}
]
},
{
"questionId": "triviaSpaceApolloLast",
"questionText": "Which NASA space flight was the last manned mission to the moon?",
"answerType": "SELECT",
"options": [
{
"optionId": "apollo13",
"label": "Apollo 13"
},
{
"optionId": "apollo14",
"label": "Apollo 14"
},
{
"optionId": "apollo15",
"label": "Apollo 15"
},
{
"optionId": "apollo16",
"label": "Apollo 16"
},
{
"optionId": "apollo17",
"label": "Apollo 17"
},
{
"optionId": "apollo18",
"label": "Apollo 18"
}
],
"evals": [
{
"evalId": "triviaSpaceApolloLast_eval",
"bindType": "DISCRETE",
"requiredQuestionIds": [
"triviaSpaceApolloLast"
],
"actions": [
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Nope!",
"binding": "apollo13"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Incorrect.",
"binding": "apollo14"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Wrong.",
"binding": "apollo15"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Sorry, that is incorrect.",
"binding": "apollo16"
},
{
"status": "ACCEPT",
"workflowControl": "CONTINUE",
"message": "Correct! A crew of three astronauts spent three days on the moon, taking lunar samples and walking on the surface. They landed back on earth on December 19, 1972. The flight occurred three years after the first human visit to the moon on Apollo 11 in 1969.",
"binding": "apollo17"
},
{
"status": "DECLINE",
"workflowControl": "CONTINUE",
"message": "Try again?",
"binding": "apollo18"
}
]
}
]
}
]
}
}
}
Response Description
The questionSet
object in the response two fields:
groups: A list containing one or more group objects. A group is a way to tie one or more questions together with a name and description. The contextType property of a group tells you whether the questions are always asked (contextType: general), if they are only asked if a particular answer has been given to another question (contextType: actionIds), or if it is targeted to a particular entity type in the contextData (contextType with any other value).
questions: A list containing all the question objects referenced by groups. A question contains the text of the question along with data to describe the possible answers, and the evaluations (evals) that should be performed once an answer is chosen/provided. Each question is tied to one or more evals. The eval is used to bind an action after an answer is chosen/provided by the user. While a question may have more than one eval, there can only be one action that can be bound to a given answer.