ICD: EPC HRMS Employee Details Fetch

Direction: EPC --> HRMS (Outbound)

Version: 1.7

Date: 21 Oct 2026

Status: Implemented

Changes in 1.7: ACTIVE_STATUS Active is read before LEAVING_REASON (Status Mapping). An employee HRMS marks Active is never read as a retiree, even when the leaving reason mentions retirement, so retiree registration refuses them (HR_CURRENT_EMPLOYEE_USE_SSO, 10171) and they register through SSO. An Active record with a non-retirement leaving reason and a last day that has passed is still read as a former employee. Other statuses are read as in 1.6.

Changes in 1.6: Registration reads ACTIVE_STATUS again, with one rule for both registration flows (Status Mapping). The first SSO sign-in refuses a former employee who is not a retiree (HR_EMPLOYEE_LEFT_SERVICE, 10170). Retiree registration refuses an employee whose ACTIVE_STATUS is Active (HR_CURRENT_EMPLOYEE_USE_SSO, 10171) and sends a former employee who is not a retiree to associate registration.

Changes in 1.5: HR_EMPLOYEE_NOT_FOUND_IN_HRMS is now code 10169. It shared 10080 with SSO_USER_INACTIVE, an unrelated sign-in failure. The HTTP status and the message are unchanged.

Changes in 1.4: The unused POST /members/register was removed (EPC-1295), and it was the trigger this document named. The Trigger section now names the live callers: the first SSO sign-in, retiree registration after the OTP, the back office "Update HRMS data" and the daily leaver reconciliation. The status check and its error HR_EMPLOYEE_NOT_ACTIVE went with it, so Status Mapping now says which flows read ACTIVE_STATUS. Error Handling says which flow returns which error. The retiree lookup is described as the main lookup for retiree registration, and the empty-BG_ID fallback no longer names a form company.

Changes in 1.3: Added GENDER and MARITAL_STATUS to the active-employee requested fields (EPC-1290), so the back office "Update HRMS data" applies them; both endpoints now request the same list. DATE_OF_BIRTH is stored as the day only, like JOINING_DATE. A requested column HRMS has no value for is omitted from the response, and EPC never clears a stored value because of it.

Changes in 1.2: Added BG_ID to the active-employee requested fields (EPC-1260), so the member's company is resolved from the HRMS Business Group on both endpoints. Corrected the field lists to what EPC sends (FIRST_NAME and MIDDLE_NAME, not EMP_NAME) and documented the retiree field list.

Changes in 1.1: Added DOJ to the requested fields (returned as JOINING_DATE) and mapped it to joiningDate on the member record.

---

Overview

EPC fetches employee details from HRMS to pre-populate a member at registration, to refresh it on the back office "Update HRMS data", and to recognise leavers in the daily leaver reconciliation. Two endpoints are used:

Authentication

All requests are authenticated via PING OAuth2.0 Client Credentials flow.

Parameter Value
Token URL SSM: /platinum-api/{stage}/hrms-ping-token-url
Grant Type client_credentials
Auth Header Basic {base64} from SSM: /platinum-api/{stage}/hrms-ping-auth-basic
Token TTL 2 hours (refreshed 10 min before expiry)
Token Cache In-memory (per Lambda instance)

Token Request

POST {tokenUrl}
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {hrms-ping-auth-basic}
Cache-Control: no-cache

grant_type=client_credentials

Token Response

{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 7200
}

---

Endpoint 1: Active Employee Details

Request

GET {baseUrl}/platinum/erp/webservices/rest/EmployeeDetails/getEmployeeDetails/{employeeNumber}?fields={fields}
Authorization: Bearer {access_token}
Accept: application/json
Parameter Source Description
baseUrl SSM: /platinum-api/{stage}/hrms-api-base-url e.g. https://stgservices.emirates.dev
employeeNumber User input (staffId) URL-encoded employee number
fields Static See Fields Requested below

Fields Requested

DOJ,STAFFNR,EMAIL,MOBILE,FIRST_NAME,MIDDLE_NAME,LAST_NAME,GRADE,PERSON_TYPE,STATUS,WORK_LOCAITON,BG_NAME,BG_ID,CRA,TERM_DATE,DOB,PREV_EMP_NUM,CORE_GRADE,DEP_EXITS,LEAV_RES,GENDER,MARITAL_STATUS

Response (Success)

{
  "getEmployeeDetails_Output": {
    "OutputParameters": {
      "Output": {
        "employeeResponse": [
          {
            "EMPLOYEE_NUMBER": "EK123456",
            "EMAIL_ID": "john.doe@emirates.com",
            "MOBILE": "+971501234567",
            "FIRST_NAME": "John",
            "MIDDLE_NAME": "",
            "LAST_NAME": "Doe",
            "GRADE_CODE": "EK.07",
            "EMPLOYEE_TYPE": "EMP",
            "ACTIVE_STATUS": "Active Assignment",
            "WORKLOCATION": "Dubai Airport Free Zone",
            "BG_COUNTRY": "Emirates Group - UAE",
            "BG_ID": "61",
            "CURRENT_RES_ADDRESS": "Dubai, UAE",
            "ACTUAL_TERMINATION_DATE": "",
            "DATE_OF_BIRTH": "1990-01-15",
            "JOINING_DATE": "2008-09-23 00:00:00.0",
            "PREV_EMP__ID": "",
            "IS_DEP_EXISTS": "Y",
            "CORE_GRADE": "EK.07",
            "LEAVING_REASON": ""
          }
        ]
      }
    }
  }
}

---

Endpoint 2: Retiree Details (by Email)

Retiree registration calls it with the OTP-verified email. "Update HRMS data" calls it when the active employee endpoint returns no results.

Request

GET {baseUrl}/platinum/erp/webservices/rest/EmpDetailsByEmail/getEmpDetailsbyEmail/?emailID={email}&fields={fields}
Authorization: Bearer {access_token}
Accept: application/json

Fields Requested

DOJ,STAFFNR,EMAIL,MOBILE,FIRST_NAME,MIDDLE_NAME,LAST_NAME,GRADE,PERSON_TYPE,STATUS,WORK_LOCAITON,BG_NAME,BG_ID,CRA,TERM_DATE,DOB,PREV_EMP_NUM,CORE_GRADE,DEP_EXITS,LEAV_RES,GENDER,MARITAL_STATUS

Response (Success)

{
  "getEmpDetailsbyEmail_Output": {
    "OutputParameters": {
      "Output": {
        "employeeResponse": [
          {
            "EMPLOYEE_NUMBER": "EK123456",
            "ACTIVE_STATUS": "Terminate - Process",
            "LEAVING_REASON": "Retirement",
            "ACTUAL_TERMINATION_DATE": "2025-12-31",
            ...
          }
        ]
      }
    }
  }
}

---

Field Mapping

HRMS Field EPC Field Notes
EMPLOYEE_NUMBER employeeId / staffId Primary identifier
EMAIL_ID email
MOBILE phone
FIRST_NAME name
MIDDLE_NAME middleName
LAST_NAME surname
GRADE_CODE grade
EMPLOYEE_TYPE employmentType / memberType
ACTIVE_STATUS status See Status Mapping below
WORKLOCATION addressOptional
BG_COUNTRY country / address.country
BG_ID bgId → company Requested on both endpoints. Resolved to the Platinum company whose bgIds contains it. An unmapped value rejects the registration or the update; an empty value falls back to the SSO default company at registration and leaves the company unchanged on "Update HRMS data"
CURRENT_RES_ADDRESS address
ACTUAL_TERMINATION_DATE lastDayOfService Null if empty
DATE_OF_BIRTH birthdate Oracle timestamp; stored as the day only (1990-01-15). Empty or unparseable leaves the stored value untouched
GENDER gender Requested on both endpoints. M/Male and F/Female (any case); any other value is ignored
MARITAL_STATUS maritalStatus Requested on both endpoints. M/Married is stored as married; S/Single, Divorced, Widowed and Separated as single; any other value keeps the stored one and is recorded in the member's history
JOINING_DATE joiningDate Requested as DOJ. HRMS returns an Oracle timestamp (2008-09-23 00:00:00.0); normalized to the day only (2008-09-23) before storage. Empty or unparseable leaves the stored value untouched
PREV_EMP__ID oldStaffId / previousStaffIds Null if empty
IS_DEP_EXISTS dependantsExists "Y" or "N"
CORE_GRADE coreGrade
LEAVING_REASON leavingReason Null if empty

Status Mapping

Registration reads ACTIVE_STATUS together with LEAVING_REASON, ACTUAL_TERMINATION_DATE and JOINING_DATE (decision re1295). The same rule serves the first SSO sign-in and retiree registration. The rows are read in order: an Active status is read first.

HRMS record EPC reading First SSO sign-in Retiree registration
ACTIVE_STATUS Active, a leaving reason that does not mention retirement, a last day that has passed, and JOINING_DATE not after the last day Left Refused with HR_EMPLOYEE_LEFT_SERVICE (10170) Continues as an associate
ACTIVE_STATUS Active, any other case, a retirement reason included Employed Registers Refused with HR_CURRENT_EMPLOYEE_USE_SSO (10171)
Not Active, and LEAVING_REASON mentions retirement Retiree Registers Registers
ACTIVE_STATUS In-Active, Inactive or Terminated, not a retiree Left Refused with HR_EMPLOYEE_LEFT_SERVICE (10170) Continues as an associate
Empty or unrecognised ACTIVE_STATUS, a leaving reason and a last day that has passed, not a retiree, and JOINING_DATE not after the last day Left Refused with HR_EMPLOYEE_LEFT_SERVICE (10170) Continues as an associate
Empty or unrecognised ACTIVE_STATUS, and the rows above do not apply Current Registers Registers, as before (no positive evidence of a current employee)

A status value EPC does not recognise is judged on the leaving fields alone. The samples above show Active Assignment and Terminate - Process; the answers EPC received on its test stages in October 2026 carry Active and In-Active. Emirates to confirm the full list of ACTIVE_STATUS values, and whether the retiree endpoint also returns current employees.

ACTIVE_STATUS is also read by the back office "Update HRMS data" and by leaver reconciliation, to recognise a member who has left since registering. LEAVING_REASON and ACTUAL_TERMINATION_DATE are stored at registration, where a retirement leaving reason marks the member as a retiree.

---

Error Handling

Scenario HTTP Status Behavior
Employee not found at the first SSO sign-in N/A Return HR_EMPLOYEE_NOT_FOUND_IN_HRMS (10169)
Retiree not found by email N/A Not an error: the registrant continues as an associate
Former employee, not a retiree, at the first SSO sign-in N/A Return HR_EMPLOYEE_LEFT_SERVICE (10170)
Former employee, not a retiree, found by email N/A Not an error: the registrant continues as an associate
Active employee found by email at retiree registration 403 Return HR_CURRENT_EMPLOYEE_USE_SSO (10171); staff of a company with no self-registration get COMPANY_EMAIL_PASSWORD_ONLY (10142), and a BG_ID that matches no company gets HRMS_COMPANY_NOT_FOUND (11016, 404)
HRMS unavailable (503, timeout, HTML) at retiree registration 503 Return HR_HRMS_UNAVAILABLE (10079)
HRMS unavailable at the SSO sign-in or "Update HRMS data" N/A The request fails with a generic error
Employee not found by number or email on "Update HRMS data" N/A Return HR_HRMS_UNAVAILABLE (10079)
ISGServiceFault Varies Retry up to 3 times, then fail
401 Unauthorized 401 Clear token cache, retry once

ISGServiceFault Response

{
  "ISGServiceFault": {
    "Code": "500",
    "Message": "Internal Server Error"
  }
}

HTML 503 Response

HRMS may return HTML (Weblogic bridge failure) instead of JSON on 503. Detected via Content-Type: text/html.

---

Retry Strategy

Parameter Value
Max Retries 3
Retry Delay 5 seconds
Request Timeout 10 seconds
401 Handling Clear token cache, retry once
503 Handling Retry with backoff

---

Trigger

Called synchronously by four flows:

Flow Handler Lookup
First SSO sign-in, when no member holds the email or the staff ID login-sso-callback getEmployeeByNumber(staffId), staff ID from the SAML response
Retiree registration after the OTP verify-registration-otp getEmployeeByEmail(email), the OTP-verified email
Back office "Update HRMS data" resync-hrms-member getEmployeeByNumber(staffId), then getEmployeeByEmail(email) if not found
Leaver reconciliation (daily cron) reconcile-leavers getEmployeeByNumber(staffId)

Registration Flow

---

Source Files

File Purpose
src/lib/services/hrms-auth.service.ts PING OAuth2.0 token management
src/lib/services/hrms-employee.service.ts Employee fetch with retry logic
src/lib/mappers/hrms-employee.mapper.ts Raw response to domain model mapping
src/lib/entities/hr-integration.ts Type definitions (HrmsEmployeeRaw, HrmsEmployee)
src/modules/member/login-sso-callback/handler.ts Trigger: first SSO sign-in
src/modules/member/verify-registration-otp/handler.ts Trigger: retiree registration
src/modules/admin/resync-hrms-member/handler.ts Trigger: back office "Update HRMS data"
src/lib/utils/employment-state.ts registrationEmployment: the registration Status Mapping
src/lib/services/leaver-reconciliation.service.ts Trigger: leaver reconciliation (cron reconcile-leavers)

---

SSM Parameters

Parameter Type Description
/platinum-api/{stage}/hrms-ping-token-url String PING OAuth2.0 token endpoint
/platinum-api/{stage}/hrms-api-base-url String HRMS API base URL
/platinum-api/{stage}/hrms-ping-auth-basic SecureString Base64 client credentials for HRMS APIs