GA - Gateway Public API Client - User Manual
Purpose
This document provides instructions for creating a public API client that can be used to connect to the Word & Brown General Agency Public API Gateway.
Prerequistes
Sample Application
As a reference, the Word & Brown General Agency has provided a sample application that can be used for testing purposes. To obtain a copy of the sample application, please contact your Word & Brown representative.
Credentials
Credentials must be obtained prior to connecting to the API Gateway. To request credentials, please contact your Word & Brown representative.
APIs (Carrier, Plan, Quote, Underwriting)
Base URL: https://api-gateway.wordandbrown.com
To ensure optimum usage of bandwidth and to provide a good response time, “Plan API” is split into 2 individual endpoints - Carrier and Plan. The following steps should be taken to initiate these endpoints:
- Call the Carrier API. This step will return a list of Carrier IDs that are available for the selected State and Effective Date.
- Programatically iterate the list of Carriers.
- Call the Plan API for ALL CARRIERS returned in Carrier API Call (one by one). This step will return all plans, rates, and benefits for the list of Carriers.
Carrier API
To obtain the list of carriers for a State and Effective Date:
Endpoint | GET : /api/carriers?state=statecode&effectiveDate=date |
---|---|
Description: | This API will return the list of Carrier IDs that are available for the selected State and Effective Date |
Query string Parameters: | state: Is 2 letter state code. Mandatory effectiveDate: Is a short date. Mandatory |
Request Headers | apiKey: apiKey received in email. Mandatory. secretCode: secretCode received in email. Mandatory |
In the sample application, go to Carriers, fill in the fields, and click Get Carriers:
‘C# Code - Carriers’
public async Task<ActionResult> Carriers(string state, DateTime? effectiveDate, string apiKey, string secretCode)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["PublicApiUrl"]);
client.DefaultRequestHeaders.Add("apiKey", apiKey.ToString());
client.DefaultRequestHeaders.Add("secretCode", secretCode.ToString());
var result = await client.GetAsync(string.Format("carriers?state={0}&effectiveDate={1}", state, effectiveDate));
if (result.IsSuccessStatusCode)
{
return Json(result.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
else
{
HttpContext.Response.StatusCode = (int)result.StatusCode;
var errorMessage = string.IsNullOrEmpty(result.Content.ReadAsStringAsync().Result) ? "Request failed due to an internal server error. Please try again." : result.Content.ReadAsStringAsync().Result;
return Json(result.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
}
}
catch (Exception ex)
{
HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
}
Response Format
{
"state": "string",
"effectiveDate": "string",
"carriers": [
{
"carrierId": "string",
"carrierName": "string",
"state": "string",
"startDate": "2016-07-25T13:45:44.665Z",
"endDate": "2016-07-25T13:45:44.665Z"
}
],
"error": "string"
}
Carriers Error Response
- Invalid Credentials
Status : 400
Details: {
"message": "Invalid Credentials. Please provide a valid combination of apiKey and secretCode."
}
- Date not provided
Status : 400
Details: {
"message": "Invalid EffectiveDate. EffectiveDate should not be null or empty and should be a valid date."
}
- State not provided
- Invalid Effective Date
Status : 400
Details: {
"message": "Bad Request. Invalid effective date. The effective date '7/22/2016' is not available in the allowed list of quotable dates. Allowed quotable dates are: 5/1/2016, 6/1/2016, 7/1/2016, 8/1/2016, 9/1/2016."
}
- apiKey not provided
- secretCode not provided
Plan Api
To obtain the Plans, Rates and Benefits for the given Carrier with respect to the selected State and Effective Date based on the value of include* parameter.
include* :
if include=plans, returns list of Plans along with the eligible Rating Areas’ Names. In this case, NQS PlanId and Area Name parameters will be ignored.
if include=benefitsandrates, returns Plan Info along with the list of Area Rates and Benefits for the given plan. In this case, NQS PlanId must be provided.
- if areaName is specified, returns Plan Info along with Area Rates and Benefits for the given area.
Endpoint | GET : /api/plans?include=plans/benefitsandrates&carrierId=cid&state=sid&effectiveDate=date&planId=nqsPid&areaName=ratingAreaName |
---|---|
Description: | This API will return a list of plans containing the following data: Plan Info, Area Rates, Benefits |
Query string Parameters: | include: Is either plans or benefitsandrates. carrierId: Is short string denoting carrier code. Mandatory. state: Is 2 letter state code. Mandatory effectiveDate: Is a short date. Mandatory planId: Is nqs plan id. Optional areaName: Is rating area name. Optional |
Request Headers | apiKey: apiKey received in email. Mandatory. secretCode: secretCode received in email. Mandatory |
In the sample application, go to Plans, fill in the fields, and click Get Plans:
‘C# Code - Plans’
public async Task<ActionResult> Plans(string state, DateTime? effectiveDate, string apiKey, string secretCode, int carrierId = 0, int planId = 0, string include = null, string areaName = null)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["PublicApiUrl"]);
client.DefaultRequestHeaders.Add("apiKey", apiKey.ToString());
client.DefaultRequestHeaders.Add("secretCode", secretCode.ToString());
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip");
var result = await client.GetAsync(GetPlanParameters(state, effectiveDate, carrierId, planId, include, areaName));
if (result.IsSuccessStatusCode)
{
return new JsonResult
{
Data = result.Content.ReadAsStringAsync().Result,
MaxJsonLength = Int32.MaxValue
};
}
else
{
HttpContext.Response.StatusCode = (int)result.StatusCode;
var errorMessage = string.IsNullOrEmpty(result.Content.ReadAsStringAsync().Result) ? INTERNAL_SERVER_ERROR_MSG : result.Content.ReadAsStringAsync().Result;
return Json(errorMessage, JsonRequestBehavior.AllowGet);
}
}
}
catch (Exception ex)
{
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
}
private string GetPlanParameters(string state, DateTime? effectiveDate, int carrierId, int planId, string include, string areaName)
{
return string.Format("plans?carrierId={0}&state={1}&effectiveDate={2}&planId={3}&include={4}&areaName={5}",
carrierId, state, effectiveDate, planId, include, areaName);
}
Plan Api Response Format
{
"carrierId": 0,
"state": "string",
"effectiveDate": "string",
"plans": [
{
"nqsPlanId": "string",
"planCode": "string",
"rollToPlanId": "string",
"planName": "string",
"coverageType": "string",
"networkName": "string",
"areas": [
{
"areaName": "string",
"rates": [
{
"ageRange": "string",
"ageFrom": "string",
"ageTo": "string",
"premium": 0
}
]
}
],
"benefits": {
"benefitSet1": [
{
"name": "string",
"value": "string",
"deductibleApply": "string",
"footnote": "string"
}
],
"benefitSet2": [
{
"name": "string",
"value": "string",
"deductibleApply": "string",
"footnote": "string"
}
],
"benefitSet3": [
{
"name": "string",
"value": "string",
"deductibleApply": "string",
"footnote": "string"
}
]
}
}
],
"error": "string"
}
Plan Api Response
- When no plans (benefits & rates) are found for the given criteria
Status : 200
{
"nqsPlanId": "string",
"rollToPlanId": "string",
"message": "The criteria you have entered have returned no rating areas. This likely means the plan is no longer available. Please contact Product Management to verify (ProductManagement@wordandbrown.com)"
}
Plan Api Error Response
- Invalid Credentials
Status : 400
Details: {
"message": "Invalid Credentials. Please provide a valid combination of apiKey and secretCode."
}
- Date not provided
Status : 400
Details: {
"message": "Invalid EffectiveDate. EffectiveDate should not be null or empty and should be a valid date."
}
- State not provided
- Invalid Effective Date
Status : 400
Details: {
"message": "Bad Request. Invalid effective date. The effective date '2/1/2019' exceeds last quotable date: 6/1/2017."
}
- CarrierId not provided
Status : 400
Details: {
"message": "Invalid CarrierId. CarrierId should not be null or empty and should be greater than 0."
}
- include provided other than plan/benefitsandrates
Status : 400
Details: {
"message": "Invalid Include parameter. The value of parameter should be either 'plans' or 'benefitsandrates'."
}
- include = benefitsandrates and NqsPlanId not provided
Status : 400
Details: {
"message": "Invalid PlanId. PlanId should not be null or empty and should be greater than 0."
}
- Invalid NqsPlanId provided
Status : 400
Details: {
"message": "Bad Request. Invalid plan id. Plan Id '78963' is not available for the given effective date '2/1/2016', state '54' and carrier id '1'."
}
- NqsPlanId not ready for quoting
Status : 400
Details: {
"message": "Bad Request. Plan Id '7896' is not available for quoting for the given effective date '2/1/2016', state '54' and carrier id '1'."
}
- apiKey not provided
- secretCode not provided
Quote API
To obtain quote information for a selected State, Effective Date, and Group Census:
Endpoint | POST : /api/quote?state=sid |
---|---|
Description: | This API will return quote data for a selected Effective Date (based on Group Census) |
Query string Parameters: | state: Is 2 letter state code. Mandatory |
Request Headers | apiKey: apiKey received in email. Mandatory. secretCode: secretCode received in email. Mandatory |
Quote - Request Data Format
{
"groupName": "string",
"effectiveDate": "2016-08-25T11:53:41.470Z",
"employeeList": [
{
"firstName": "string",
"lastName": "string",
"dateOfBirth": "2016-08-25T11:53:41.471Z",
"dependents": [
{}
],
"employeeType": 1,
"gender": 1,
"isCOBRA": true,
"isEmployerZipCode": true,
"isTobaccoUser": true,
"state": "string",
"zipCode": "string"
}
],
"employerCountyCode": "string",
"employerZipCode": "string",
"quoteClassificationType": 1,
"sicCode": "string",
"state": "string"
}
- All Census fields in the initial request are mandatory. There should be at least one employee included in the request.
In the sample application, go to Quote, fill in the fields, and click ‘Get Quote’. To view the JSON Request structure, click ‘Show Request JSON’.
C# Code - Quote
public async Task<ActionResult> Quote(QuotingContextDataViewModel quotingContext)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["PublicApiUrl"]);
client.DefaultRequestHeaders.Add("apiKey", Request.Headers["apiKey"].ToString());
client.DefaultRequestHeaders.Add("secretCode", Request.Headers["secretCode"].ToString());
var result = await client.PostAsJsonAsync((string.Format("Quoting?state={0}", quotingContext.State)), quotingContext);
if (result.IsSuccessStatusCode)
{
return new JsonResult
{
Data = result.Content.ReadAsStringAsync().Result,
MaxJsonLength = Int32.MaxValue
};
}
else
{
HttpContext.Response.StatusCode = (int)result.StatusCode;
var errorMessage = string.IsNullOrEmpty(result.Content.ReadAsStringAsync().Result) ? INTERNAL_SERVER_ERROR_MSG : result.Content.ReadAsStringAsync().Result;
return Json(errorMessage, JsonRequestBehavior.AllowGet);
}
}
}
catch (Exception ex)
{
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
}
Quote Response Format
{
"effectiveDate": "2016-10-14T13:39:32.150Z",
"rateArea": "string",
"carriers": [
{
"carrierId": 0,
"orionCarrierId": "string",
"carrierName": "string",
"plans": [
{
"nqsPlanId": 0,
"orionPlanId": "string",
"planName": "string",
"networkId": 0,
"networkName": "string",
"employees": [
{
"firstName": "string",
"lastName": "string",
"premium": "string",
"dependentPremium": "string",
"dependentRates": [
{
"firstName": "string",
"lastName": "string",
"premium": "string"
}
]
}
],
"totalPremium": "string",
"benefitSet1": [
{
"name": "string",
"value": "string",
"deductibleApply": "string",
"footnote": "string"
}
],
"benefitSet2": [
{
"name": "string",
"value": "string",
"deductibleApply": "string",
"footnote": "string"
}
],
"benefitSet3": [
{
"name": "string",
"value": "string",
"deductibleApply": "string",
"footnote": "string"
}
]
}
]
}
],
"message": "string"
}
Quote Error Response
- Invalid Credentials
Status : 400
Details: {
"message": "Invalid Credentials. Please provide a valid combination of apiKey and secretCode."
}
- apiKey not provided
- secretCode not provided
- Effective Date not provided or is invalid.
Status : 400
Details: {
"message": "Invalid EffectiveDate. EffectiveDate should not be null or empty and should be a valid date."
}
- Zip code not provided.
Status : 400
Details: {
"message": "Invalid ZipCode. Please enter a valid zipcode with a minimum 5 digits."
}
- Missing Information (ex: Group Name, SIC Code, State, or Employee Information)
Status : 500
Details: {
"message": "Request failed due to an internal server error. Please try again."
}
Underwriting API
Submit or Update underwriting information for a selected group.
Two interfaces are provided:
Submit or Update Enrollment: To enter the enrollment data directly in the user interface.
Upload Enrollment File: To upload a supplemental file containing the Enrollment data
Submit or Update Enrollment Interface
Endpoint | POST : /api/underwriting?content=content |
---|---|
Description: | This API will return the submission status for a Group |
Query string Parameters: | state: Is string containing state abbreviation. Mandatory |
content: Is string containing the Enrollment Data. Mandatory | |
Request Headers | apiKey: apiKey received in email. Mandatory. |
secretCode: secretCode received in email. Mandatory |
User Interface
In the sample application, go to Underwriting and select the Submit or Update Enrollment tab.
Enter the State, Api Key, Secret Code and Enrollment Data.
The Enrollment Data field can be filled in the following ways:
Press the Paste Empty Enrollment button to paste JSON containing all of the fields, then edit to add data.
Press the Paste Sample Enrollment button to paste JSON containing sample data.
Enter data from manually.
The enumerated values for properties are shown below:
After all the required data has been entered click the Submit or Update Enrollment button to submit or update the group information.
On the successful processing of the enrollment data the API Response is displayed as shown below.
Note the caseGuid returned is the same as the one provided for an update to an existing Group or is the new caseGuid created for a new Group submission.
Enrollment Data Field JSON showing all possible fields.
The brokerLicense and brokerZip must have a value. The caseGuid must either be blank to create a new case or filled with an existing caseGuid to update the case.
The Other fields may also be required based on business requirements. Always remove unneeded fields.
{
"caseGuid": "",
"brokerLicense": "string",
"brokerZip": "string",
"companies": [
{
"companyName": "string",
"taxid": "string",
"address1": "string",
"address2": "string",
"city": "string",
"state": "string",
"zip": "string",
"county": "string",
"sicCode": "string",
"corporationType": "string",
"contacts": [
{
"name": "string",
"phone": "1234567890",
"email": ""
}
],
"payrollgroups": [
{
"name": "string",
"payFrequency": "string",
}
],
"plans": [
{
"carrierName": "string",
"planName": "string"
}
],
"enrollments": [
{
"groupnumber": "string",
"policynumber": "string",
"isEmployeeCovered": true,
"isSpouseCovered": true,
"isDomesticPartnerCovered": true,
"areChildrenCovered": true
}
]
}
],
"members": [
{
"eid": "string",
"underwritingCaseId": 0,
"firstname": "string",
"middleName": "string",
"lastname": "string",
"gender": "Male",
"dob": "02/02/2017",
"age": "string",
"maritalStatus": "string",
"isTobaccoUser": "Yes",
"address1": "string",
"address2": "string",
"city": "string",
"zip": "string",
"county": "string",
"state": "string",
"telephone": "1234567890",
"workphone": "1234567890",
"email": "",
"language": "English",
"canWritePrimaryLanguage": "Yes",
"canSpeakPrimaryLanguage": "Yes",
"ssn": "string",
"employeeHasAdditionalCoverage": "No",
"isWaivingCoverage": "No",
"waiverReason": "string",
"isCobra": "No",
"isLifeOnly": "No",
"isMedicare": "No",
"employeeNumber": "string",
"jobTitle": "string",
"employeeType": "Fulltime",
"jobClass": "string",
"hireDate": "02/02/2017",
"startDate": "02/02/2017",
"benefitEligibleDate": "02/02/2017",
"hoursPerWeek": "string",
"annualSalary": "string",
"payrollId": "string",
"payFrequency": "string",
"payrollGroup": "string",
"terminationDate": "02/02/2017",
"terminationReason": "string",
"coverageType": "",
"planType": "",
"carrierName": "string",
"planName": "string",
"primaryCareProviderId": "string",
"primaryCareProviderCity": "string",
"primaryCareProviderZip": "string",
"isPrimaryCareProviderCurrentDoctor": "No",
"primaryDentalOfficeId": "string",
"primaryDentalOfficeCity": "string",
"primaryDentalOfficeZip": "string",
"isPrimaryDentalOfficeCurrentDentist": "No",
"enrollmentStatus": "InProgress",
"signatureDate": "02/02/2017",
"lastLoginDate": "02/02/2017",
"lastModifiedDate": "02/02/2017",
"coverageChangeFrom": "string",
"coverageChangeTo": "string",
"planChangeTo": "string",
"employeeCostChangeFrom": "string",
"employeeCostChangeTo": "string",
"employerCostChangeFrom": "string",
"employerCostChangeTo": "string",
"dependents": [
{
"dependentNumber": "string",
"dependentType": "",
"firstname": "string",
"middleName": "string",
"lastname": "string",
"gender": "",
"dob": "02/02/2017",
"age": "string",
"isDomesticPartner": "No",
"isTobaccoUser": "No",
"isStudent": true,
"isDisabled": false,
"address1": "string",
"address2": "string",
"city": "string",
"zip": "string",
"county": "string",
"state": "string",
"ssn": "string",
"coverageType": "",
"carrierName": "string",
"planName": "string",
"primaryCareProviderId": "string",
"primaryCareProviderCity": "string",
"primaryCareProviderZip": "string",
"isPrimaryCareProviderCurrentDoctor": "",
"primaryDentalOfficeId": "string",
"primaryDentalOfficeCity": "string",
"primaryDentalOfficeZip": "string",
"isPrimaryDentalOfficeCurrentDentist": ""
}
]
}
]
}
C# Code - Submit or Update Enrollment
public async Task<ActionResult> Underwriting(string content, string state, string apiKey, string secretCode)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["PublicApiUrl"]);
client.DefaultRequestHeaders.Add("apiKey", apiKey.ToString());
client.DefaultRequestHeaders.Add("secretCode", secretCode.ToString());
client.DefaultRequestHeaders.Add("Accept", "application/json");
dynamic obj = JsonConvert.DeserializeObject(content);
var v = obj.caseGuid;
string s = v;
if(s != null)
{
s = s.Trim();
}
if(s=="" || s==null)
{
var sResult = await client.PostAsJsonAsync((string.Format("underwritingcase/SubmitEnrollment?state={0}", state)), JsonConvert.DeserializeObject(content));
if (sResult.IsSuccessStatusCode)
{
return Json(sResult.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
else
{
HttpContext.Response.StatusCode = (int)sResult.StatusCode;
var errorMessage = string.IsNullOrEmpty(sResult.Content.ReadAsStringAsync().Result) ? INTERNAL_SERVER_ERROR_MSG : sResult.Content.ReadAsStringAsync().Result;
return Json(sResult.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
}
else
{
var uResult = await client.PutAsJsonAsync((string.Format("underwritingcase/UpdateEnrollment?state={0}", state)), JsonConvert.DeserializeObject(content));
if (uResult.IsSuccessStatusCode)
{
return Json(uResult.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
else
{
HttpContext.Response.StatusCode = (int)uResult.StatusCode;
var errorMessage = string.IsNullOrEmpty(uResult.Content.ReadAsStringAsync().Result) ? INTERNAL_SERVER_ERROR_MSG : uResult.Content.ReadAsStringAsync().Result;
return Json(uResult.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
}
}
}
catch (Exception ex)
{
HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
}
Submit or Update API Error Response
If issues occur during processing they will also be displayed in the Response field as shown in the following example.
Submit or Update Error Error Response Format
Submit or Update Error Responses
- Invalid Credentials
Status : 400
Details: {
"message": "Invalid Credentials. Please provide a valid combination of apiKey and secretCode."
}
- apiKey not provided
- secretCode not provided
- Content not provided.
````javascript Status : 400 Details: { “Enrollment Data cannot be empty.” }
- Content is invalid.
Details: The details will vary depending on the issue as shown in the following examples:
For example, when the enrollment data is blank you will see the following:
Status : 500
Details: {
"Cannot perform runtime binding on a null reference"
}
If the enrollment data has other issues you may see something like the following:
Status : 500
Details: {
"After parsing a value an unexpected character was encountered: ". Path 'companies[0].contacts', line 27, position 10."
}
In this case a comma is missing between the contact and payrollgroups sections.
Upload Enrollment File Interface
Endpoint | POST : /api/underwriting?content=content |
---|---|
Description: | This API will return the import status for a File |
Query string Parameters: | state: String containing state abbreviation. Mandatory |
file: The file selected for import. Mandatory | |
content: String containing the Enrollment File Association data. Mandatory | |
Request Headers | apiKey: apiKey received in email. Mandatory. |
secretCode: secretCode received in email. Mandatory |
User Interface
In the sample application, go to Underwriting and select the Upload Enrollment File tab.
Enter the State, Api Key, Secret Code, File and File Assocation Data.
The Enrollment File Assocation Data is formatted as shown below:
caseGuid is optional. If the case exists it is Mandatory. If not provided a new case will be created.
brokerLicense is Mandatory.
brokerZip is Mandatory.
After all the required data has been entered click the Upload Enrollment File button to load the file.
On the successful import of the file the API Response is displayed as shown below. Note the caseGuid returned is the same as the one provided for an update to an existing Group or is the new caseGuid created for a new Group submission.
C# Code - UnderwritingFile
public async Task<ActionResult> UnderwritingFile(HttpPostedFileBase file, string state, string content, string apiKey, string secretCode)
{
try
{
string result = new StreamReader(file.InputStream).ReadToEnd();
var streamContent = new StreamContent(file.InputStream);
var imageContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["PublicApiUrl"]);
client.DefaultRequestHeaders.Add("apikey", apikey);
client.DefaultRequestHeaders.Add("secretcode", secretcode);
using (var multipartFormDataContent = new MultipartFormDataContent())
{
#region Add Json content
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("symessage_metadata",content),
};
var contentType = file.ContentType;
foreach (KeyValuePair<string, string> keyValuePair in values)
{
StringContent jsonPart = new StringContent(keyValuePair.Value);
jsonPart.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
jsonPart.Headers.ContentType = new MediaTypeHeaderValue("application/json");
multipartFormDataContent.Add(new StringContent(keyValuePair.Value), String.Format("\"{0}\"", keyValuePair.Key));
}
#endregion
#region Add File Content
var fileName = Path.GetFileName(file.FileName);
ByteArrayContent byteArrayContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
byteArrayContent.Headers.Add("Content-Type", contentType);
multipartFormDataContent.Add(byteArrayContent, '"' + fileName + '"', '"' + fileName + '"');
#endregion
var fResult = await client.PostAsync((string.Format("underwritingcase/UploadEnrollmentFiles?state={0}", state)), multipartFormDataContent);
if (fResult.IsSuccessStatusCode)
{
return Json(fResult.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
else
{
HttpContext.Response.StatusCode = (int)fResult.StatusCode;
var errorMessage = string.IsNullOrEmpty(fResult.Content.ReadAsStringAsync().Result) ? INTERNAL_SERVER_ERROR_MSG : fResult.Content.ReadAsStringAsync().Result;
return Json(fResult.Content.ReadAsStringAsync().Result, JsonRequestBehavior.AllowGet);
}
}
}
}
catch (Exception ex)
{
HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
}
Upload Enrollment File API Error Response
If issues occur during processing they will also be displayed in the Response field as shown in the following example.
Upload Enrollment File Response Error Format
Upload Enrollment File Error Responses
- Invalid Credentials
Status : 400
Details: {
"message": "Invalid Credentials. Please provide a valid combination of apiKey and secretCode."
}
- state not provided
- state is not accessible
- apiKey not provided
- secretCode not provided
- Enrollment File Assocation data is not provided or is invalid.
- Enrollment File exceeds the maximum size permitted. In this case there is a 35MB maximum.
Status : 400
Details: {
"message": "The selected enrollment file exceeds the maximum file length of 35 MB for a JPG."
}
Enrollment
Endpoint | POST : /api/enrollment?state=sid |
---|---|
Description: | Service to send an Enrollment Application in JSON format as a Request and convert it into an EDI 834 format which further is processed and sent to selected carrier for in-force enrollments only. |
Query string Parameters: | state: Is 2 letter state code. Mandatory |
Request Headers | apiKey: apiKey received in email. Mandatory. secretCode: secretCode received in email. Mandatory |
User Interface
In the sample application, go to Enrollment and submit the enrollment JSON in the format below:
Enrollment - Request Data Format
{
"ClientId": integer, // See table Client ID
"EmailAddress": string, // Format: someone@vendor.com (when present, email notification is sent here)
"CarrierRoute": string, // See table Carrier Routes
"EventType": integer, // See table Event Types
"EventReason": string, // OPTIONAL* See table Event Reason Codes
"EventDate": string, // Format: MM/DD/YYYY - OPTIONAL*
"ChangeEffectiveDate": string, // format: MM/DD/YYYY - OPTIONAL only if EventType = 1 (New Enrollment)*
"Groups": [
{
"Name": string, // Group Name
"TaxId": string, // Format: nn-nnnnnnn,
"GroupCity": string,
"GroupState": string, // 2-letter state code, e.g. CA
"GroupZipCode": string, // 5-digit zip code string
"GroupOrPolicyNumber": string, // Group Carrier Policy Number
"RegionCode": string, // 2-letter code, *Applies to Kaiser only
"EffectiveDate": string, // Format: MM/DD/YYYY - Group Effective Date (aka Quote Effective Date)
"Subscribers": [
{
"DateOfHire": string, // Format: MM/DD/YYYY
"HomePhone": string, // Format: 7145551234
"EmailAddress": string, // Format: subscriber@mail.com
"AnnualSalary": string, // Format: 0 - OPTIONAL*
"HoursPerWeek": string, // Format: 0 - OPTIONAL*
"Language": {
"Speak": string, // See table Language Codes
"Write": string, // See table Language Codes
},
"EmploymentStatus": string, // "AC" = Active
"MaritalStatus": string, // OPTIONAL* See table Marital Statuses
"MaintenanceType": string, // 3-digit length, See table Maintenance Type
"MaintenanceReason": string, // See table Maintenance Reasons
"Dependents": [
{
"Relationship": string, // See table Relationshiop Codes
"SocialSecurityNumber": string, // Format: xxxnnyyyy (no dashes)
"FirstName": string,
"LastName": string,
"StreetAddress1": string,
"StreetAddress2": string,
"City": string,
"State": string, // 2-letter state code, e.g. CA
"ZipCode": string, // 5-digit zip code string
"County": string, // OPTIONAL*
"DateOfBirth": string, // Format: MM/DD/YYYY
"Gender": string, // Format: (M) Male, (F) Female, (U) Unknown
"IsCobra": string, // Format: (Y) Yes, (N) No
"Hcid": string, // REQUIRED* when Maintenance Reason = (41) Re-enrollment (HCID = Anthem Member ID / Kaiser Medical Record Number)
"Coverages": [
{
"CarrierId": integer,
"CoverageLevel": string, // See table Coverage Level Codes
"ProductCategory": string, // See table Product Categories
"PlanName": string,
"EffectiveDate": string, // Format: MM/DD/YYYY
"GroupOrPolicyNumber": string, // Member Group or Policy Number
"CancelCoverageEffectiveDate": string, // Format: MM/DD/YYYY
"CoverageType": string, // OPTIONAL*
"CoverageAmount": string, // OPTIONAL*
"Subgroup": string, // *Applies to Kaiser only
"Provider": {
"LoopNumber": string, // Default to 1
"ProviderId": string, // NPID - *Applies to Anthem only
"IdentificationCode": string, // REQUIRED* if enrolling Medical HMO or Dental HMO Product, See table Identification Codes
"RelationshipCode": string, // See table Provider Relationship Codes
"City": string
"State": string, // 2-letter state code, e.g. CA
"ZipCode": string, // 5-digit zip code string
"EffectiveDateOfProviderChange": string, // Format: MM/DD/YYYY
}
}
]
"SocialSecurityNumber": string, // Format: xxxnnyyyy (no dashes)
"FirstName": string,
"LastName": string,
"StreetAddress1": string,
"StreetAddress2": string,
"City": string,
"State": string, // 2-letter state code, e.g. CA
"ZipCode": string, // 5-digit zip code string
"DateOfBirth": string, // Format: MM/DD/YYYY
"Gender": string, // Format: (M) Male, (F) Female, (U) Unknown
"IsCobra": string, // Format: (Y) Yes, (N) No
"Hcid": string, // REQUIRED* when Maintenance Reason = (41) Re-enrollment (HCID = Anthem Member ID / Kaiser Medical Record Number)
"Coverages": [
{
"CarrierId": integer,
"CoverageLevel": string, // See table Coverage Level Codes
"ProductCategory": string, // See table Product Categories
"PlanName": string,
"EffectiveDate": string, // Format: MM/DD/YYYY
"GroupOrPolicyNumber": string, // Member Group or Policy Number
"CancelCoverageEffectiveDate": string, // Format: MM/DD/YYYY
"CoverageType": string, // OPTIONAL*
"CoverageAmount": string, // OPTIONAL*
"Subgroup": "", // *Applies to Kaiser only
"Provider": {
"LoopNumber": string, // Default to 1
"ProviderId": string, // NPID - *Applies to Anthem only
"IdentificationCode": string, // REQUIRED* if enrolling Medical HMO or Dental HMO Product, See table Identification Codes
"RelationshipCode": string, // See table Provider Relationship Codes
"City": string
"State": string, // 2-letter state code, e.g. CA
"ZipCode": string, // 5-digit zip code string
"EffectiveDateOfProviderChange": string, // Format: MM/DD/YYYY
}
}
]
}
]
}
]
}
Quote Error Response
- Invalid Credentials
Status : 400
Details: {
"message": "Invalid Credentials. Please provide a valid combination of apiKey and secretCode."
}
- apiKey not provided
- secretCode not provided
- Missing Information (ex: Group Name, SIC Code, State, or Employee Information)
Status : 500
Details: {
"message": "Request failed due to an internal server error. Please try again."
}
C# Code - Enrollment
public async Task<ActionResult> Enrollment(EnrollmentContextDataViewModel enrollmentContext)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["PublicApiUrl"]);
client.DefaultRequestHeaders.Add("apiKey", Request.Headers["apiKey"].ToString());
client.DefaultRequestHeaders.Add("secretCode", Request.Headers["secretCode"].ToString());
var result = await client.PostAsJsonAsync((string.Format("enrollment?state={0}", enrollmentContext.State)), enrollmentContext);
if (result.IsSuccessStatusCode)
{
return new JsonResult
{
Data = result.Content.ReadAsStringAsync().Result,
MaxJsonLength = Int32.MaxValue
};
}
else
{
HttpContext.Response.StatusCode = (int)result.StatusCode;
var errorMessage = string.IsNullOrEmpty(result.Content.ReadAsStringAsync().Result) ? INTERNAL_SERVER_ERROR_MSG : result.Content.ReadAsStringAsync().Result;
return Json(errorMessage, JsonRequestBehavior.AllowGet);
}
}
}
catch (Exception ex)
{
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
}
Reference Tables
Table: Client IDs
Client | Value |
---|---|
Orion | 1 |
Customer Care EPS | 2 |
GoCo | 3 |
Table: Carrier Routes
Carrier | Value |
---|---|
Anthem | 100 |
Kaiser Permanente | 102 |
Table: Event Types
Event | Value |
---|---|
New Enrollment | 1 |
Add Coverage | 2 |
Add Coverage Life | 3 |
Add Dependent | 4 |
Update Profile | 5 |
Cancel Coverage | 6 |
Cancel Coverage Life | 7 |
Update PCP | 8 |
Re-Enroll | 9 |
Re-Enroll Life | 10 |
ReInstate | 11 |
ReInstate Life | 12 |
Cancel Dependent | 13 |
Terminate Employee | 14 |
Table: Event Reason Codes
Reason | Value |
---|---|
Divorce | 01 |
Birth | 02 |
Death | 03 |
Retire | 04 |
Terminate | 07 |
COBRA | 09 |
Active | 20 |
Disable | 21 |
Plan Change | 22 |
Initial Enrollment | 28 |
Table: Language Codes
Language | Value |
---|---|
English | ENG |
Korean | KOR |
Russian | RUS |
Spanish | SPA |
Vietnamese | VIE |
Table: Marital Statuses
Status | Value |
---|---|
Divorced | D |
Married | M |
Separated | X |
Single | I |
Unknown | R |
Widowed | W |
Table: Maintenance Types
Description | Value |
---|---|
Change | 001 |
Addition | 021 |
Cancellation or Terminate | 024 |
Reinstatement | 025 |
Audit or Compare | 030 |
Table: Maintenance Reasons
Reason | Value |
---|---|
Divorce | 01 |
Birth | 02 |
Death | 03 |
Retirement | 04 |
Adoption | 05 |
Termination of Benefits | 07 |
Termination of Employment | 08 |
Voluntary Withdrawal | 14 |
Suspended | 18 |
Active | 20 |
Disability | 21 |
Plan Change | 22 |
Change in Identifying Data Elements | 25 |
Pre-Enrollment | 27 |
Initial Enrollment | 28 |
Benefit Selection | 29 |
Legal Separation | 31 |
Marriage | 32 |
Personnel Data | 33 |
Lay Off without Benefits | 40 |
Re-enrollment | 41 |
Change of Location or Address | 43 |
Non Payment | 59 |
No Reason Given | AI |
Member Benefit Selection | EC |
Table: Relationship Codes
Description | Value |
---|---|
Spouse | 01 |
Subscriber | 18 |
Child | 19 |
Domestic Partner | 53 |
Table: Coverage Level Codes
Description | Value |
---|---|
Children Only | CHD |
Dependent Only | DEP |
Employee Only | EMP |
Employee and Spouse/Dependent | ESP |
Family | FAM |
Spouse Only | SPO |
Spouse and Dependent | SPC |
Table: Product Categories
Description | Value |
---|---|
Dental | DEN |
EPO | EPO |
HMO | HMO |
POS | POS |
PPO | PPO |
Vision | VIS |
Table: Identification Codes
*Required if enrolling Medical HMO or Dental HMO Product
Description | Value |
---|---|
Primary Care Provider Code | PCP Code |
PIC – Carrier will assign | PIC |
Dental Office Number | PDO Number |
Table: Provider Relationship Codes
Description | Value |
---|---|
Established Patient | 25 |
Not Established Patient | 26 |
Unknown | 72 |