When deploying authentication based Cirrus Account Linking, many times organizations want to use some form of a knowledge based verification (KBV) solution. Cirrus Identity currently supports both the organization hosting their own KBV solution, or Cirrus Identity can host as ID Verify form that leverages an API provided by the organization. This article outlines the capabilities the API provided by the organization should have to enable integration with the Cirrus ID Verify form without organization specific customization.
The Cirrus ID Verify form currently supports a REST based API authenticated using HTTP Basic authentication for access control. The API responds with JSON formatted data when calls are made to the following endpoints.
The APIs have the following constraints:
The /questions endpoint of the API controls the types of questions and the allowable values that can be provided by the end user.
For the /questions endpoint, the "date" question type can be presented in any date format supported by JavaScript (see https://www.w3schools.com/js/js_date_formats.asp). The request to the /answers endpoint will always format the date value in an RFC-3339 / ISO-8601 format (for example "yyyy-mm-dd").
For the /questions endpoint, the verifiedEmail question type will perform a verification check to ensure the end user had control of the associated mailbox. The check will send a message to the mailbox that contains a six-digit number. The correct number must be entered before the post to the /answers endpoint will be submitted.
The /questions response can have a header and/or footer property formatted using basic markdown (https://www.markdownguide.org/basic-syntax). Styling can be further adjusted by contacting Cirrus Identity Support (see https://www.cirrusidentity.com/resources/service-desk).
The following is an example of the JSON response on an HTTP-GET to the /questions endpoint, and outlines the supported question types currently supported by the Cirrus ID Verify form.
{
"questions": [
{
"property": "FirstName",
"required": true,
"type": "string",
"label": "First Name",
"constraints": {
"minSize": 1,
"maxSize": 35
}
},
{
"property": "LastName",
"required": true,
"type": "string",
"label": "Last Name",
"constraints": {
"minSize": 1,
"maxSize": 35
}
},
{
"property": "DOB",
"required": true,
"type": "date",
"label": "Date of Birth (mm/dd/yyyy)",
"constraints": { "format": "dd/mm/YYYY" }
},
{
"property": "email",
"required": true,
"type": "verifiedEmail",
"label": "Email Address"
},
{
"property": "UndergradYear",
"required": true,
"type": "select",
"label": "Undergraduate Degree Year",
"constraints": {
"range": "1917..2016"
}
},
{
"property": "Program",
"required": true,
"type": "select",
"label": "Program",
"constraints": {
"options": {
"U-AH": "Undergraduate Art and Humanities",
"U-Bus": "Undergraduate Business",
"U-EMS": "Undergraduate Engineering, Math, and Science",
"M": "Masters Program",
"Law": "Law School",
"Med": "Medical School",
"Ed": "School of Education",
"MBA": "MBA Program",
"P": "PhD Program"
}
}
},
{
"property": "IdVerification",
"required": true,
"type": "pick-one",
"label": "To verify ID, select one of the following",
"constraints": {
"questions": [
{
"property": "CampusId",
"label": "8 Digit Campus ID",
"type": "string",
"constraints": {
"minSize": 8,
"maxSize": 8
}
},
{
"property": "NationalId",
"label": "Last 4 Digits of National ID",
"type": "string",
"constraints": {
"minSize": 4,
"maxSize": 4
}
}
]
}
}
],
"header": {
"markdown": "# HEADER\n\nThis is a line with a [link](https://example.edu/help)\n\n*Final* header _line_",
"align": "CENTER"
},
"footer": {
"markdown": "## FOOTER\n\n*Final* footer _line_",
"align": "LEFT"
}
}
{
"questions": [
{
"property": "IdVerification",
"required": true,
"type": "either-or",
"label": "Group questions",
"constraints": {
"groups": [
{
"property": "Group1",
"label": "First Group",
"questions": [
{
"property": "LastName",
"required": true,
"type": "string",
"label": "Last Name",
"constraints": {
"minSize": 1,
"maxSize": 35
}
},
{
"property": "ClaimCode",
"label": "16 Digit Claim Code",
"type": "string",
"constraints": {
"minSize": 16,
"maxSize": 16
}
}
]
},
{
"property": "Group2",
"label": "Second Group",
"questions": [
{
"property": "LastName",
"required": true,
"type": "string",
"label": "Last Name",
"constraints": {
"minSize": 1,
"maxSize": 35
}
},
{
"property": "DOB",
"required": true,
"type": "date",
"label": "Date of Birth (mm/dd/yyyy)",
"constraints": {
"format": "dd/mm/YYYY"
}
},
{
"property": "email",
"required": true,
"type": "verifiedEmail",
"label": "Email Address"
}
]
}
]
}
}
]
}
The /answers endpoint of the API verifies the identity by processing a JSON formatted request provided by the ID Verify form and returns a JSON formatted response that either:
The ID Verify form will only do basic question type validation and constraint checking. It is left up to the API to implement any desired business logic. For example:
The following are examples of a request, and both an example successful and failed response when a HTTP-POST is issued to the /answers endpoint.
{
"clientIp": "127.0.0.1",
"answers": [
{
"property": "FirstName",
"value": "Connie"
},
{
"property": "LastName",
"value": "Contrail"
},
{
"property": "DOB",
"value": "1980-02-29"
},
{
"property": "UndergradYear",
"value": "2004"
},
{
"property": "Program",
"value": "U-EMS"
},
{
"property": "IdVerification.CampusId",
"value": "12345678"
}
]
}
{
"clientIp": "127.0.0.1",
"answers": [
{
"property": "IdVerification",
"value": {
"group": "Group1",
"groupAnswers": [
{
"property": "LastName",
"value": "Contrail"
},
{
"property": "ClaimCode",
"value": "1234567890123456"
}
]
}
}
]
}
{
"status": "ok",
"uid": "aa11bbb222"
}
{
"status": "ok",
"uid": "aa11bbb222",
"attributes": {
"singleAttrib": "exampleValue",
"multiAttrib": ["exampleOne", "exampleTwo"]
}
}
The "status" property in an error response can be any value with the exception of "ok". The value has no impact on ID Verify logic.
An error can be returned as either HTTP-200, or HTTP-404 status. In either case, the ID Verify form will process the status and message.
The error message can be leveraged to provide end user feedback. The message can be dynamic and based on any business logic executed by the API. The message can also be formatted using basic markdown (https://www.markdownguide.org/basic-syntax).
{
"message": "A user could not be found. **You have 2 more attempt(s) before your account is locked**. click [here](https://example.edu/help) for help.",
"status": "invalid"
}