ICD - HRMS - EPC - Employee Photo Update

Interface Control Document (ICD): HRMS - EPC

Definitions & List of Abbreviations

Abbreviation Description
HRMS Human Resource Management System
EPC Emirates Platinum Card
IDCD ID Card system (source of employee ID photos)
API Application Programming Interface
SSM AWS Systems Manager (Parameter Store)

1. Interface Description

When an employee's photo changes in the HR system, HR will push the new photo to the Platinum Application. The photo replaces the member's ID photo and is approved automatically, so the member does not have to upload and wait for review.

Business Value

Objective

Legacy compatibility: The request body and the instanceId format are identical to the legacy integration POST /{projectId}/CALL/Member/updateEmployeePhoto/{instanceId}. Migrating clients change only the base URL, the path prefix and the API key.

2. Assumptions & Risk

Assumptions

Risks

Risk Mitigation
Network timeouts between HR and EPC Configure appropriate timeout settings (recommended: 30s)
Employee not found in EPC HR should handle 404 responses gracefully and log for review
Photo larger than the request size limit Keep the decoded photo at or below 4.4 MB. Larger requests are rejected
Photo overwritten by another source EPC also refreshes the photo from IDCD at registration, SSO login and admin HRMS resync. The most recent write is the current photo

3. Non-Functional Requirements

3.1 Security Requirements

Sr No. Non-Functional Requirement Value
1 PHI or Credit Card data? No credit card data & no patient health information. The photo is personal data
2 Authentication Pattern API Key (X-API-Key header)
3 Secure Channel / Encryption in Transit TLS 1.2+ (HTTPS only)
4 Input validation Yes - body validated via JSON Schema; photo content checked against the declared file type
5 Internet exposed? IP whitelisting? Yes, exposed via CloudFront. IP whitelisting can be implemented via WAF rules
6 Logging Request metadata logged (photo content is never logged)
7 Data exposure Only the photo storage key and member status are returned
8 Data at rest Photo stored in a private S3 bucket, not publicly accessible

4. Solution View

4.1 Logical

Component Value
Source HRMS (Human Resource Management System)
Source Protocol HTTPS REST API
Source Data Format JSON (photo as base64)
Target EPC (Emirates Platinum Card)
Target Protocol HTTPS
Target Data Format JSON

4.2 Architecture

4.2.1 Interface Architecture

┌─────────────┐                              ┌─────────────┐
│             │         HTTPS / JSON         │             │
│    HRMS     │  ─────────────────────────▶  │   EPC API   │
│   (Source)  │            POST              │   (Target)  │
│             │  ◀─────────────────────────  │             │
└─────────────┘         HTTPS / JSON         └─────────────┘

Flow:

4.2.2 Security Mechanisms

4.2.3 Exception/Error Management Guidelines

API Monitoring

Exception Handling

HTTP Status Scenario HRMS Action
200 Success Log success, continue
400 Validation error, or invalid photo (not base64, empty, too large, or content does not match fileExtension) Fix request data, retry
401 Invalid API key Check API key, contact EPC team
404 Employee not found (no primary member matches instanceId) Log for manual review
500 Server error Retry with backoff
503 Service unavailable Retry later

4.3 Interface Touchpoints / Use Cases

4.3.1 Employee Photo Update by Staff ID

Actors: HRMS System (automated)

Trigger: Employee photo changes in HR

Flow:

4.3.2 Employee Photo Update by Member ID

Actors: HRMS System (automated)

Trigger: Employee photo changes in HR, and HR holds the EPC member ID

Flow:

4.3.3 Photo Replacement Rules

4.3.4 Company Managed by Hand in EPC

Actors: HRMS System (automated)

Trigger: The member belongs to a company whose EPC setting "Disable integrations and self-registrations" is on

Flow:

4.4 Fields Definition

Path Parameters

Field Type Required Description Example
instanceId String Yes Employee identifier. staffId!{staffId} looks up by staff ID (! may be sent URL-encoded as %21). Any other value is treated as the member ID (with or without the non-prod stage suffix). "staffId!EK123456"

Request Fields

Field Type Required Description Example
photo String (base64) Yes Base64 encoded image. A data:image/...;base64, prefix and line breaks are tolerated. Decoded size must not exceed 4.4 MB. "iVBORw0KGgoAAAANSUhEUg..."
fileExtension String Yes Image format of photo: "jpg", "jpeg", "png", "gif" or "webp". Must match the actual image content ("jpg" and "jpeg" are equivalent). "jpg"

Response Fields

Field Type Description
success Boolean True if operation succeeded
filePath String Storage key of the photo in EPC. Not returned when skipped is present
memberStatus String Member status after the update (unchanged by this call), e.g. "active"
skipped String (optional) company_hrms_sync_disabled when the photo was accepted but not applied because the member's company is managed by hand in EPC. Nothing was stored
message String Human-readable message

4.5 Request/Response Samples

Security / Credentials

Authentication: API Key via X-API-Key header

X-API-Key: <your-api-key>
Content-Type: application/json

4.5.1 Photo Update by Staff ID

Request:

POST /members/hr/photo/staffId!EK123456 HTTP/1.1
Host: uat.api.platinum.retter.io
X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

{
  "photo": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8U...",
  "fileExtension": "jpg"
}

Response (200 OK):

{
  "success": true,
  "filePath": "members/550e8400-e29b-41d4-a716-446655440000/hr-photo.jpg",
  "memberStatus": "active",
  "message": "Employee photo updated successfully."
}

4.5.2 Photo Update by Member ID

Request:

POST /members/hr/photo/2155581665 HTTP/1.1
Host: uat.api.platinum.retter.io
X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

{
  "photo": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
  "fileExtension": "png"
}

Response (200 OK):

{
  "success": true,
  "filePath": "members/550e8400-e29b-41d4-a716-446655440000/hr-photo.png",
  "memberStatus": "active",
  "message": "Employee photo updated successfully."
}

4.5.3 Scenario Detection Notes

Scenario Key Fields Response Indicator
Lookup by Staff ID instanceId starts with staffId! 200 with filePath
Lookup by Member ID instanceId without the staffId! prefix 200 with filePath
Company managed by hand in EPC Member's company has "Disable integrations and self-registrations" on 200 with skipped, no filePath
Declared type does not match content fileExtension differs from the actual image format 400, code 10152, details.reason explains the mismatch
Dependant targeted instanceId resolves to a dependant 404, code 10073

4.6 Error Responses

400 - Validation Error

{
  "success": false,
  "error": {
    "code": 10001,
    "message": "Validation error"
  },
  "details": {
    "errors": {
      "fileExtension": ["Invalid enum value. Expected 'jpg' | 'jpeg' | 'png' | 'gif' | 'webp'"]
    }
  }
}

400 - Invalid Photo

Returned when the photo is not valid base64, is empty, exceeds 4.4 MB decoded, or its content does not match fileExtension. details.reason states which check failed.

{
  "success": false,
  "error": {
    "code": 10152,
    "message": "The employee photo is invalid. It must be a base64 encoded JPG, PNG, GIF or WebP image matching the declared file extension."
  },
  "details": {
    "reason": "Photo content is image/jpeg, which does not match the declared fileExtension."
  }
}

401 - Unauthorized (Invalid API Key)

{
  "success": false,
  "error": {
    "code": 10072,
    "message": "Invalid or missing API key."
  }
}

404 - Employee Not Found

{
  "success": false,
  "error": {
    "code": 10073,
    "message": "Employee not found by employeeId or oldStaffId."
  }
}

500 - Internal Server Error

{
  "success": false,
  "error": {
    "code": 10000,
    "message": "Internal server error"
  }
}

5. API Endpoints

Environment URL
Staging https://staging.api.platinum.retter.io/members/hr/photo/{instanceId}
UAT https://uat.api.platinum.retter.io/members/hr/photo/{instanceId}

API Documentation

6. Appendix

6.1 Supported Image Formats

fileExtension Content Type Stored As
jpg image/jpeg hr-photo.jpg
jpeg image/jpeg hr-photo.jpg
png image/png hr-photo.png
gif image/gif hr-photo.gif
webp image/webp hr-photo.webp

6.2 Sync Log Tracking

Failed HR photo pushes (except 401 responses) are logged with: