Interface Control Document (ICD): HRMS - EPC
---
| Version | Status | Update Comment | By | Date |
|---|---|---|---|---|
| 1.0 | Draft | Initial Draft | Retter | 05 Feb 2026 |
| 1.1 | Draft | Standardized payload: HRMS sends full record, overwrites dependant data | Retter | 10 Feb 2026 |
| 1.2 | Draft | Added status field for dependant activation/deactivation | Retter | 10 Feb 2026 |
| 1.3 | Draft | Changed to upsert mode — creates dependant if not found | Retter | 11 Feb 2026 |
| 1.4 | Draft | Made email field nullable; clarified type field uses dynamic back-office mapping (hrmsMapping) | Retter | 30 Mar 2026 |
| 1.5 | Draft | Status field changed to "Active"/"In-Active" (case-insensitive); unrecognized type no longer rejects — saves without mapping and returns warning | Retter | 30 Mar 2026 |
| 1.6 | Draft | Added optional, nullable phone field (dependant mobile number) |
Retter | 14 Jun 2026 |
---
| Abbreviation | Description |
|---|---|
| HRMS | Human Resource Management System |
| EPC | Emirates Platinum Card |
| API | Application Programming Interface |
| SSM | AWS Systems Manager (Parameter Store) |
---
When dependant data changes in the HRMS (name, email, relationship type, etc.), the HRMS system will push the updates to the Platinum Application. This endpoint operates in upsert mode: if the dependant exists it is updated; if not, a new dependant is created under the primary member.
> Standardized Payload: HRMS should always send the full dependant record in every request. The EPC system overwrites the dependant record with the incoming HRMS data, or creates a new dependant if the ID is not found.
---
| Risk | Mitigation |
|---|---|
| Network timeouts between HRMS and EPC | Configure appropriate timeout settings (recommended: 30s) |
| Duplicate dependant ID | EPC rejects creation if the ID already exists for a different member (403) |
| Dependant ownership mismatch | HRMS should verify dependant-employee relationship before sending updates |
---
| Sr No. | Non-Functional Requirement | Value |
|---|---|---|
| 1 | PHI or Credit Card data? | No credit card data & no patient health information |
| 2 | Authentication Pattern | API Key (X-API-Key header) |
| 3 | Secure Channel / Encryption in Transit | TLS 1.2+ (HTTPS only) |
| 4 | Input validation | Yes - all fields validated via JSON Schema |
| 5 | Internet exposed? IP whitelisting? | Yes, exposed via CloudFront. IP whitelisting can be implemented via WAF rules |
| 6 | Logging | All requests logged with sanitized payloads (sensitive fields redacted) |
| 7 | Data exposure | Only necessary fields returned. Sensitive member data not included in response |
---
| Component | Value |
|---|---|
| Source | HRMS (Human Resource Management System) |
| Source Protocol | HTTPS REST API |
| Source Data Format | JSON |
| Target | EPC (Emirates Platinum Card) |
| Target Protocol | HTTPS |
| Target Data Format | JSON |
┌─────────────┐ ┌─────────────┐
│ │ HTTPS / JSON │ │
│ HRMS │ ─────────────────────────▶ │ EPC API │
│ (Source) │ POST │ (Target) │
│ │ ◀───────────────────────── │ │
└─────────────┘ HTTPS / JSON └─────────────┘
Flow:
X-API-Key headerAPI Monitoring
Exception Handling
| HTTP Status | Scenario | HRMS Action |
|---|---|---|
| 200 | Dependant updated | Log success, continue |
| 201 | Dependant created (did not exist) | Log success, store returned dependantId |
| 400 | Validation error | Fix request data, retry |
| 401 | Invalid API key | Check API key, contact EPC team |
| 403 | Dependant ownership mismatch | Verify dependant belongs to employee |
| 404 | Primary member not found | Log for manual review |
| 500 | Server error | Retry with backoff |
| 503 | Service unavailable | Retry later |
Actors: HRMS System (automated)
Trigger: Dependant data change or new dependant in HRMS
Flow:
Actors: HRMS System (automated)
Trigger: Dependant's name changes in HRMS (e.g., after marriage)
Flow:
name and/or surnameActors: HRMS System (automated)
Trigger: Dependant's relationship type changes in HRMS
Flow:
type field---
> All fields except phone must be present in the payload. HRMS must always send the full dependant record in every request. The EPC system overwrites the dependant record with the incoming HRMS data. email and phone accept null when not available. Empty strings are rejected by validation (except email/phone, where empty/whitespace is normalized to null).
| Field | Type | Required | Description | Example | |
|---|---|---|---|---|---|
| id | String | Yes | Dependant's ID in the EPC system | "660e8400-e29b-41d4-a716-446655440001" | |
| employeeId | String | Yes | Primary member's staff ID (to verify ownership) | "EK123456" | |
| status | String (enum) | Yes | "Active" or "In-Active" (case-insensitive). "In-Active" sets member status to Inactive; "Active" reactivates if Inactive. | "Active" | |
| name | String | Yes | Dependant's first name | "Jane" | |
| surname | String | Yes | Dependant's last name | "Doe" | |
| String \ | null | Yes | Dependant's email address. Must be valid email format if provided; send null if not available. |
"jane.doe@example.com" or null | |
| phone | String \ | null | No | Dependant's mobile number. Optional — may be omitted. Send null (or omit) if not available; when null/omitted the stored phone is left unchanged. |
"+971501234567" or null |
| type | String | Yes | Relationship type. Member subtypes are defined dynamically in the back office by admins. A mapping field (hrmsMapping) is used to match HRMS values to EPC values. If the value is not recognized, the dependant is still saved but without type mapping, and a warning is returned in the warnings array. |
"Wife" | |
| birthdate | String (date) | Yes | Birth date (verification only, not stored) | "1995-05-15" or "1995-05-15 00:00:00.0" |
| Field | Type | Description |
|---|---|---|
| success | Boolean | True if operation succeeded |
| message | String | Human-readable message |
| body.dependantId | String (UUID) | Dependant's ID in EPC system |
| body.primaryMemberId | String (UUID) | Primary member's ID in EPC system |
| body.updatedFields | Array[String] | List of fields that were updated |
| body.warnings | Array[String] (optional) | Warnings about the request (e.g., unrecognized type). Only present when there are warnings. |
---
Authentication: API Key via X-API-Key header
X-API-Key: <your-api-key>
Content-Type: application/json
HRMS should always send the complete dependant record with every request. The EPC system overwrites the dependant record with the incoming HRMS data, or creates a new dependant if the ID is not found. The updatedFields array in the response tells HRMS which fields were modified. An empty updatedFields with a 201 status indicates a newly created dependant.
> Null convention: For fields that support null (e.g., email), send null — not an empty string (""). Empty strings are rejected by validation.
Request:
POST /members/hr/dependant HTTP/1.1
Host: uat.api.platinum.retter.io
X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"employeeId": "EK123456",
"status": "Active",
"type": "Wife",
"name": "Jane",
"surname": "Doe",
"email": "jane.doe@example.com",
"phone": "+971501234567",
"birthdate": "1995-05-15"
}
Response (200 OK) — dependant existed, only name and email differed:
{
"success": true,
"message": "Dependant updated successfully",
"body": {
"dependantId": "660e8400-e29b-41d4-a716-446655440001",
"primaryMemberId": "550e8400-e29b-41d4-a716-446655440000",
"updatedFields": ["name", "email"]
}
}
Response (200 OK) — dependant existed, nothing changed:
{
"success": true,
"message": "Dependant updated successfully",
"body": {
"dependantId": "660e8400-e29b-41d4-a716-446655440001",
"primaryMemberId": "550e8400-e29b-41d4-a716-446655440000",
"updatedFields": []
}
}
Response (201 Created) — dependant did not exist, created under primary member:
{
"success": true,
"message": "Dependant added successfully.",
"body": {
"dependantId": "660e8400-e29b-41d4-a716-446655440001",
"primaryMemberId": "550e8400-e29b-41d4-a716-446655440000",
"updatedFields": []
}
}
---
{
"success": false,
"error": {
"code": 10001,
"message": "Validation error"
},
"details": {
"errors": {
"id": ["Required"],
"employeeId": ["Required"]
}
}
}
{
"success": false,
"error": {
"code": 10072,
"message": "Invalid API key"
}
}
{
"success": false,
"error": {
"code": 10074,
"message": "Dependant does not belong to the specified employee"
}
}
{
"success": false,
"error": {
"code": 10075,
"message": "Primary member not found"
}
}
{
"success": false,
"error": {
"code": 10000,
"message": "Internal server error"
}
}
---
| Environment | URL |
|---|---|
| Staging | https://staging.api.platinum.retter.io/members/hr/dependant |
| UAT | https://uat.api.platinum.retter.io/members/hr/dependant |
---
All HR integration calls are logged with:
Successful operations create audit log entries with:
hr-update-dependant, event hr-dependant-updated, includes previous data, new data, and updated fieldshr-create-dependant, event hr-dependant-created, includes new data