Using the UI Claimant API
AJL's UI Claimant API (Application Programming Interface) is a real-time RESTful web service that uses JSON for data interchange. It processes claimant information sent from a state’s UI system, automatically creating a JobLink account, UI enrollment, and Self-Service enrollment if one does not exist; or updating the claimant record in JobLink if one does exist. This begins a process of notifications between JobLink and UI of claimant activity, as well as job match notifications to the job seeker.
UI agencies must develop, purchase, or use an open-source RESTful client to use the API. Using the Claimant API requires basic knowledge of software development and web services. The UI Claimant API is secured using an API token. The UI agency's IT staff who are implementing the API must be given the token by the state's AJL administrator. The API token is the same whether the Staging (Test) or Production endpoint are being used.
Viewing an API Token
The following instructions are for the state’s AJL administrator.
-
Log into AJL as an administrator.
-
Click Admin Tasks in the navigation bar.
-
On the Admin tab of Admin Tasks, scroll down to the bottom of the page and click the API tile. The UI Claimant API is displayed next to /api/ui_claimants.
-
Provide the token in a secure manner (such as encrypted email) to the IT staff responsible for implementing the UI Claimant API.
How the UI Claimant API Works
To use the UI Claimant API, you need a RESTful client, which is a program that lets you build
HTTP requests. To make a request, you need to include the URL, Header, Method, and Body.
Request URL
An endpoint is a unique URL that makes up part of an API. For the UI Claimant API, each state using AJL has two unique endpoints: one for the Staging (Test) environment and one for the Production environment. The state AJL administrator should provide the UI IT staff with these endpoints. Any testing using the Production endpoint should be coordinated with the state AJL administrator.
Method
There is only one method for the UI Claimant API: POST.
Header
Headers provide meta information about the request. Add the following headers to your RESTful client:
| Header Name | Header Value |
|---|---|
| Content-Type | application/json |
| Accept | application/json |
| Authorization Token | token=”provided api key” |
Body
The request body contains the UI claimant data the client is sending to the AJL server. UI sends a RESTful request when a person files a new claim or an additional claim. A successful request creates an UI enrollment and job seeker account in AJL if they don't already exist. Otherwise, it updates appropriate claim and account information.
{
"claimant": {
"ssn": "string",
"ui_system_id": "string",
"date_of_birth": "2020-08-03",
"first_name": "string",
"last_name": "string",
"middle_name": "string",
"address": "string",
"address2": "string",
"city": "string",
"state": "string",
"zip": "string",
"country": "string",
"county": "string",
"email": "string",
"home_phone": "string"
},
"claim": {
"byb": "2020-08-03",
"bye": "2020-08-03",
"job_title": "string",
"job_category": 17,
"originally_hire_on": "2020-08-03",
"work_ended_on": "2020-08-03",
"job_match_exempt": true,
"status": 0,
"interstate_worker": 0
"weekly_benefit_amount": true
},
"employer": {
"name": "string",
"address": "string",
"address2": "string",
"city": "string",
"state": "string",
"zip": "string",
"country": "string"
},
"eligibility": {
"race": [
0
],
"gender": 0,
"dislocated_worker": true,
"highest_grade_completed": 0,
"migrant_worker": true,
"citizen": true,
"alien_permit_number": "string",
"veteran": {
"is_veteran": true,
"is_veteran_spouse": true,
"branch": [
0
],
"start_date": "2020-08-03",
"end_date": "2020-08-03",
"vietnam_vet": true,
"character_of_discharge": 0,
"upcoming_separation": 0,
"upcoming_retirement": 0,
"tap": 0,
"campaign": 0,
"homeless": 0,
"vrap": 0,
"vrap_id": 0,
"compensation_entitlement": 0,
"disability_discharged": 0,
"disability_over_30": 0,
"disability_under_30": 0,
"disability_rating": 0,
"reserve": 0,
"reserve_homeland": 0,
"reserve_medical_discharge": 0,
"aggravated_discharge": 0,
"sole_survivor_discharge": 0,
"spouse_died": 0,
"spouse_mia": 0,
"spouse_captured": 0,
"spouse_detained": 0,
"spouse_disability": 0,
"spouse_diagnosed_death": 0,
"spouse_tap": 0,
"not_disability_compensation_entitled": 0
}
},
"other": {
"reset_password": true
}
}
About UI Claimant API Data
The following table provides the keys and values accepted in the body of UI Claimant API requests. There are four types of data: string (group of characters and digits), integer (group of digits), boolean (true or false), and semi-boolean (no, yes, not reported). Accepted values are provided, as well as any constraints, such as character limits.
| Key | Data Type | Value | Required |
|---|---|---|---|
| ssn | string | Claimant's SSN (9 digits (0-9), do not include dashes) | Yes |
| ui_system_id | string | Claimant's unique ID in the UI system | No |
| date_of_birth | string | Claimant's date of birth (YYYY-MM-DD) | Yes |
| first_name | string | Claimant's first name | Yes |
| last_name | string | Claimant's last name | Yes |
| middle_name | string | Claimant's middle name | No |
| address | string | Claimant’s street address | Yes |
| address2 | string |
Claimant’s apartment, floor,room, suite, PO box, or building number |
No |
| city | string | Claimant’s city of residence | Yes |
| state | string | Claimant’s state of residence | Yes |
| zip | string | Claimant’s ZIP code | Conditional (only required when claimant’s country = US) |
| country | string | Claimant’s country of residence | No |
| county | string | Claimant’s county of residence | Yes |
| string | Claimant’s email address | No (if not provided, claimant will not receive job match emails from AJL) | |
| home_phone | string | Claimant’s home phone number | No |
| byb | string | Claim benefit year begin date; cannot be a future date but can be before the claimant's eligibility date (YYYY-MM-DD) | No (values outside the accepted range will result in a 422 error) |
| bye | string | Claim benefit year end date ( YYYY-MM-DD) | Yes |
| job_title | string |
Job title of claimant’s last employment |
No (if not provided, job match information will not be returned in the response, and the claimant will not receive job match emails from AJL) |
| job_category | integer |
Job category of claimant’s last employment:
|
No |
|
|||
| originally_hire_on | string |
Hire date of claimant’s last employment (YYYY-MM-DD) |
No |
| work_ended_on | string | Claimant’s last day worked (YYYY-MM-DD) | No |
| job_match_exempt | boolean |
Is claimant exempt from job search requirements? (true/false) |
Yes |
| status | integer |
Claimant’s unemployment insurance status:
|
Yes |
| interstate_worker | integer |
Which of the following best describes where the claimant lives in relation to where they are looking for work?
|
Yes |
| weekly_benefit_amount | boolean | Is the claimant receiving the maximum weekly benefit amount? (true/false, values entered other than "Y" or "N" will result in a 422 error) | No |
| name | string | Last employer’s name | No |
| address | string | Last employer’s street address | No |
| address2 | string |
Last employer’s apartment, floor, room, suite, PO box, or building number |
No |
| city | string | Last employer’s city | No |
| state | string | Last employer’s state | No |
| zip | string | Last employer’s ZIP code | No |
| country | string | Last employer’s country | No |
| race | integer array |
Claimant’s race:
|
Yes |
| gender | integer |
Claimant’s gender:
|
Yes |
| dislocated_worker | boolean | Is the claimant a dislocated worker? (true/false) | Yes |
| highest_grade_completed | integer |
Highest grade completed by the claimant:
|
Yes |
| migrant_worker | boolean |
Is the claimant a migrant seasonal farm worker? (true/false) |
Yes |
| citizen | boolean | What is the claimant’s work eligibility status? (true/false) | Yes |
| alien_permit_number | string |
If the claimant is a non-citizen eligible to work in the United States or a non-citizen not eligible to work in the United States, what is their Alien Certification Number? |
No |
| is_veteran | boolean |
Has the claimant served on active duty with the armed forces of the United States? (true/false) |
Yes |
| is_veteran_spouse | boolean |
Is the claimant the spouse of an active duty service member of veteran (living or deceased)? (true/false) |
Yes |
| branch | integer array |
What was the claimant’s military branch of service?
|
Yes |
| start_date | string |
What is the claimant’s active duty service start date? (YYYY-MM-DD) |
No |
| end_date | string |
What is the claimant’s active duty end date? (YYYY-MM-DD) |
No (unless "is_veteran" is true) |
| vietnam_vet | boolean |
Is the claimant a Vietnam veteran? (true/false) |
No |
| character_of_discharge | integer |
What was the claimant’s character of discharge?
|
Yes (unless "is_veteran" is true AND "end_date" is a future date) |
| upcoming_separation | semi-boolean |
Will the claimant separate from active duty within 12 months?
|
No |
| upcoming_retirement |
semi-boolean |
Will the claimant retire from the military within 24 months?
|
No |
| tap | integer |
Is or has the claimant been a participant in the Transition Assistance Program (TAP)?
|
Yes |
| campaign |
semi-boolean |
Did the claimant serve on active duty during a war, campaign, or expedition for which a campaign or expeditionary medal has been identified and listed by the Office of Personnel Management (OPM)?
|
No |
| homeless |
semi-boolean |
Is the claimant a homeless veteran?
|
No |
| vrap |
semi-boolean |
Is the claimant enrolled in the Homeless Veterans Reintegration Program (HVRP)?
|
No |
| vrap_id | integer |
If the claimant is enrolled in HVRAP, what is their HVRP grant number? |
No |
|
compensation_entitlement |
semi-boolean |
Is the claimant entitled to payment from Veterans Affairs for a disability incurred on active duty?
|
No |
| disability_discharged |
semi-boolean |
Was the claimant discharged or released because of a disability incurred while on active duty that is not entitled to payment from Veterans Affairs?
|
No |
| disability_over_30 |
semi-boolean |
Is the claimant entitled to payment from Veterans Affairs for a disability incurred on active duty that has been rated at 30% or more?
|
No |
|
disability_under_30 |
semi-boolean |
Has Veterans Affairs classified the claimant as a “Special Disabled Veteran” because their disability has been rated less than 30%, but is a major barrier to employment?
|
No |
| disability_rating | integer |
What is the claimant’s veterans’ disability rating?
|
No |
| reserve |
semi-boolean |
Was the claimant a military reserve or guard unit member who served on active duty during a war, campaign, or expedition for which a campaign or expeditionary medal was authorized?
|
No |
| reserve_homeland |
semi-boolean |
Was the claimant a military reserve or guard unit member who served on active duty for Homeland Security?
|
No |
|
reserve_medical_discharge |
semi-boolean |
Did the claimant receive a medical discharge or release from active duty due to a service-connected disability?
|
No |
| aggravated_discharge |
semi-boolean |
Did the claimant receive a medical discharge for a pre-existing condition that worsened in the line of duty?
|
No |
| sole_survivor_discharge |
semi-boolean |
Did the claimant receive a sole survivorship discharge?
|
No |
| spouse_died |
semi-boolean |
At the time of this registration, is the claimant the spouse of a veteran who died of a service-connected disability?
|
No |
| spouse_mia |
semi-boolean |
At the time of this registration, is the claimant the spouse of an active duty service member who has been missing in action for more than 90 days?
|
No |
| spouse_captured |
semi-boolean |
At the time of this registration, is the claimant the spouse of an active duty service member who has been captured in the line of duty for more than 90 days?
|
No |
| spouse_detained |
semi-boolean |
At the time of this registration, is the claimant the spouse of an active duty service member who has been detained by a foreign government or power for more than 90 days?
|
No |
| spouse_disability |
semi-boolean |
Is the claimant the spouse of a veteran who has a total, service-connected disability?
|
No |
|
spouse_diagnosed_death |
semi-boolean |
Is the claimant the spouse of a veteran who died while diagnosed with total, service-connected disability?
|
No |
| spouse_tap | semi-boolean |
Is the claimant the spouse of an active duty service member who is receiving Transition Assistance Program (TAP) services prior to retirement or discharge?
|
No |
|
not_disability_compensation_entitled |
semi-boolean |
Has the claimant received a rating for a disability incurred on active duty that is not entitled to payment from Veterans Affairs (VA)?
|
No |
| reset_password | boolean |
When set to “true” and there is already an existing claimant record in AJL, the claimant’s AJL password will be reset to their SSN. ( true/false) This is generally not recommended, as it may cause user confusion if they did not request a password reset. |
Yes |
| access_token | string | API access token | Yes |
General Data Formatting Guidelines
-
When data is to be inserted as null, send a null value.
-
When a data element is not provided at all, no value is set (i.e., omitted data elements are not assumed to be null).
-
The integer value 99 is only equivalent to null for fields of type "semi-boolean". Semiboolean values of 99 or null are recorded as 99 in their associated database field. This value is used for when the user opts-out of providing information, not to indicate that a question was never asked.
-
Date (Time) fields are ISO 8601 may be formatted as follows (examples):
-
"2014-12-31" (if time is included "2014-12-31T04:05:06+07:00").
-
"2014/12/31" (if time is included "2014/12/31T04:05:06+07:00").
-
"20141231" (if time is included "20141231T040506+0700").
-
"31st Dec 2014" (if time is included "31st Dec 2014 04:05:06 PM").
-
Notes
-
All of the following must be true in the request in order for the TSM (Transitioning Service Member) tag to appear on a job seeker's Case Details page:
-
"is_veteran" = true
-
"end_date" = a future date
-
upcoming_separation" = 1 OR "upcoming_retirement" = 1
-
"tap" = 1
-
-
All of the following must be true in the request in order for the TSM (Transitioning Service Member) tag to appear on the Job Seeker Search page for a job seeker:
-
"is_veteran" = true
-
"end_date" = a future date
-
upcoming_separation" = 1 AND/OR "tap" = 1
-
-
If a claimant's contact information is updated via the API and the "country" field is empty in the request, the updated contact information will not override the existing country_id. If the existing claimant's country_id is null, it is defaulted to United States.
-
(Idaho only) If an API request includes a claimant that is already in the system and the claimant is identified as a veteran in the request but not in JobLink (or vice versa), the claimant's veteran status is not updated in JobLink and no error will occur.
Submitting a Successful API Request
Using your RESTful client, send a request to the UI Claimant API endpoint. To be successful, all requests must include a valid API token and accepted values for all of the required fields as shown in the table above. They must also not trigger any data validation errors.
The API processes successful requests immediately. Matching against existing AJL job seeker records is based solely on the SSN provided in the request. If no matching SSN is found, a new AJL job seeker “stub account” is created for the claimant, as well as a username and a temporary password. AJLA–TS returns this log in information to the UI agency in the API response (See API Responses below for more information). The UI agency is responsible for communicating the AJL log in information to the claimant either by displaying it to them on a screen in the UI system, or by including the information in a letter or email to the claimant. AJLA–TS creates claimant usernames in the following format: 1st 3 characters of first name, 1st 3 characters of last name, then a special character and a sequential number: e.g. BroPat!73. The claimant’s temporary AJL password is their SSN. Never display the claimant’s actual SSN on a screen in the UI system or in a letter or email. Instead, use language such as “Your AJL password is your SSN.” The claimant will be required to reset their password upon first logging into AJL.
When an update to an existing record comes through the UI interface, the user’s username and password will remain their current AJL username and password, unless reset_password is set to “true” in the request (not recommended). Their account will be set to active if it was previously disabled for inactivity.
The full business logic executed in AJL for successful requests is shown below.
-
Updates the client's unended UI {Enrollment} and associated {UiBenefitInfo#is_job_match_exempt} status
-
Inactivates the {Enrollment}'s {ProgramParticipation} if {claim_job_match_exempt} is true
-
Adds a new 'Self Service' {Enrollment} if the client is not actively enrolled or inactivates the existing 'Self Service' {Enrollment}'s {ProgramParticipation} if {claim_job_match_exempt} is true.
-
-
If an active UI {Enrollment} exists:
-
{Enrollment#updated_at} is updated to the current date
-
If there already exists a {UiBenefitInfo} record for the associated UI {Enrollment}, and {UiBenefitInfo#is_job_match_exempt} is not equal to {claim_job_match_exempt}, then the {ProgramParticipation#inactivated_at} associated with the UI {Enrollment} is updated to either the current date/time or null depending on whether the value of {claim_job_match_exempt} is true or false, respectively
-
If {claim_byb} and {claim_bye} are not blank and they're not equal to {UiBenefitInfo#benefit_year_begins_on} and {UiBenefitInfo#benefit_year_begins_on} on the existing UI {Enrollment}, then:
-
{Enrollment#ends_on} and {ProgramParticipation#ends_on} are updated to the day preceding {claim_byb} if {UiBenefitInfo#benefit_year_ends_on} is greater than {claim_byb} and {claim_byb} is greater than {UiBenefitInfo#benefit_year_begins_on} and {claim_bye} is greater than {UiBenefitInfo#benefit_year_ends_on}
-
Otherwise, {Enrollment#ends_on} and {ProgramParticipation#ends_on} are updated to the value of {UiBenefitInfo#benefit_year_ends_on} if {claim_byb} is greater than {UiBenefitInfo#benefit_year_ends_on} and {claim_byb} is greater than {UiBenefitInfo#benefit_year_begins_on} and {claim_bye} is greater than {UiBenefitInfo#benefit_year_ends_on}
-
Otherwise, {UiBenefitInfo#benefit_year_begins_on} and {UiBenefitInfo#benefit_year_ends_on} are updated to {claim_byb} and {claim_bye}, respectively
-
-
If an active UI {Enrollment} doesn't exist or was closed out by the preceding logic, then:
-
The Process_CreateOnePgmEnroll stored procedure is run to create a new UI {Enrollment} for the client
-
A {UiBenefitInfo} record is created for the {Enrollment} above with the values of {claim_byb} and {claim_bye} for {UiBenefitInfo#benefit_year_begins_on} and {UiBenefitInfo#benefit_year_ends_on}, respectively
-
-
API Responses
After submitting a request, AJLA–TS will send a response back to UI including a status code indicating the success of the request.
-
200: “successful” The request was successful, resulting in the execution of the business logic described above.
-
401: “unauthorized” The request contained an unauthorized/invalid token in the HTTP header, and access is denied.
-
404: “not found” Request may not have reached the UI claimants endpoint. Likely a transient network issue on the UI agency’s side.
-
422: “unprocessable entity” The request was invalid and validation messages are provided.
-
500: “internal server error” An error indicating a general problem on our server during specific steps in processing.
-
502: “bad gateway” Likely a network issue on the UI agency’s side.
-
503: “service unavailable” Request may not have reached the UI claimant’s endpoint. Likely a transient network issue on the UI agency’s side.
When a request is successful and no existing AJL job seeker account is found for the claimant, the response will also include the claimant’s AJL username and temporary password as discussed above in Submitting a Successful API Request, as well as a unique Participant ID. If the request includes a valid job title and a matching O*NET occupation code is found, the response will include the O*NET code and a job search link with the job title pre-filled in the search keyword field.
Example:
{
"username": "JohDoe!1"
"password": false [for first time user]/ true [for updated user],
"participant_id": 123456,
"onet_code": "35-9021.00",
"job_matches": {
"url": "https://[State URL]/search/jobs?keywords=Dishwasher"
}
}
Logging and Troubleshooting
It is critical that the UI agency implement logging according to state and agency procedures to record requests made and responses received through the UI Claimant API. Without logging, issues cannot be effectively researched and resolved. SSN is generally not needed for troubleshooting, so these can be omitted from logs for the protection of PII. The UI agency should monitor logs for any error status codes so that these can be promptly addressed without causing a delay in claimant benefits or other services.
Validation Errors
The most common errors are 422 (data validation) errors. The UI agency should work to resolve data validation issues for requests that receive a 422-error response, which may require reaching out to the claimant and/or AJL subscribing agency. The error response includes the information necessary to research and resolve the error; for example:
7/23/19: ClaimID: 1234567<BR/><BR/><BR/>Exception: The remote server returned an error: (422) Unprocessable Entity.<BR/><BR/>Response Text:
{"eligibility":{"veteran":{"is_veteran":["cannot be false since this client is already registered as a veteran"]}}}<BR/><BR/>
This error indicates the claimant already has an account in AJL with an is_veteran status of true, and the POST request includes an is_veteran status of false. The conflicting data must be resolved and then the POST request should be resent.
Network-Related Errors
404, 502, and 503 errors are all likely network issues on the UI agency side. UI should work with their IT resources to research these errors and attempt to resend the failed records at least once before reaching out to the AJL state administrator who would then contact AJLA–TS.
500 errors indicate a server/network issue on the AJLA–TS side. Before contacting the AJL state administrator, the UI agency should resend requests that receive a 500-error response once to see if it is an intermittent issue, such as a temporary DB timeout. If the request receives a 500 error a second time, report this to the AJL state administrator who will enter a ticket in the AJLA–TS issue tracking system. The ticket should include the approximate timestamp and first and last name of the claimant.
API requests will not be successful during AJL system downtime, such as scheduled releases, and will receive a 500-error response. Scheduled downtime should be communicated to the UI agency by the AJL state administrator. If possible, the UI system should be programmed to not send records during these timeframes. Alternatively, failed records should be sent as soon as possible after releases.