Employees API
17 endpoints, generated from packages/core/openapi/v1.snapshot.json (OpenAPI 3.1.0, contract version 1.0). Conventions for lists, errors, money and authentication are on the API conventions page.
GET/api/v1/employees
Employee directory
Directory fields are visible to every member. Work pass state only to readers of all work passes.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
page | query | integer | no |
pageSize | query | integer | no |
sort | query | enum | no |
q | query | string | no |
departmentId | query | string (uuid) | no |
teamId | query | string (uuid) | no |
locationId | query | string (uuid) | no |
costCentreId | query | string (uuid) | no |
managerId | query | string (uuid) | no |
status | query | string | no |
scope | query | enum | no |
Responses
200 Success. object
itemsarray of objectrequiredidstringrequiredemployeeNumberstringrequirednamestringrequiredlegalNamestringrequiredpreferredNamestring | nullrequiredjobTitlestring | nullrequireddepartmentobject or nullrequiredidstringrequirednamestringrequired
teamobject or nullrequiredidstringrequirednamestringrequired
locationobject or nullrequiredidstringrequirednamestringrequired
managerobject or nullrequiredidstringrequirednamestringrequired
workEmailstring | nullrequiredstatusobjectrequiredcodeenumrequiredone of "not_started", "active", "leaving", "former", "no_tenure"
labelstringrequiredsincestringlastWorkingDaystring
workPassStateenum or nullrequiredone of "valid", "expiring", "expired", "cancelled"
hireDatestring | nullrequired
pageintegerrequiredmin -9007199254740991
pageSizeintegerrequiredmin -9007199254740991
totalintegerrequiredmin -9007199254740991
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
forbidden,mfa_enrolment_required
POST/api/v1/employees
Hire an employee
Creates the employee, tenure, employment record, optional compensation (payroll roles only), onboarding checklist and sign-in invitation.
Request body
application/json, object, required
personobjectrequiredemployeeNumberstring or nullmax length 20
legalNamestringrequiredmin length 1 · max length 200
preferredNamestring or nullmax length 100
idTypeenumrequiredone of "nric", "fin", "other"
idNumberstringrequiredmin length 1
dobstringrequiredgenderenum or nullone of "female", "male", "other", "undisclosed"
nationalitystring or nullmax length 60
residencyStatusenumrequiredone of "citizen", "pr", "foreigner"
prStartDatestring | nullsprCpfOptionenum or nullone of "gg", "fg", "ff"
sprCpfOptionApprovedOnstring | nullracestring or nullmax length 60
raceSecondarystring or nullmax length 60
religionenum or nullone of "buddhism", "christianity", "islam", "hinduism", "taoism", "sikhism", "other", "none", "undisclosed"
shgOptOutOnstring | nullworkEmailstring (email) or nullpersonalEmailstring (email) or nullmobilestring or nullmax length 30
addressobject or nullblockstring or nullmax length 20
streetstring or nullmax length 200
unitstring or nullmax length 20
buildingstring or nullmax length 200
postalCodestring or nullmax length 10
countrystring or nullmin length 2 · max length 2
jobobjectrequiredjobTitlestringrequiredmin length 1 · max length 120
departmentIdstring (uuid)requiredteamIdstring (uuid) or nulllocationIdstring (uuid) or nullcostCentreIdstring (uuid) or nullmanagerEmployeeIdstring (uuid) or nullemploymentTypeenumrequiredone of "full_time", "part_time", "contract", "intern"
workScheduleIdstring (uuid) or nullprobationEndstring | nulleaCoveredbooleanisWorkmanbooleanisManagerOrExecutivebooleanhireDatestringrequired
compensationobject or nullpayBasisenumrequiredone of "monthly", "hourly"
amountCentsintegerrequiredmin 0
reasonstring or nullmax length 200
allowancesarray of objectallowanceTypeIdstring (uuid)requiredamountCentsintegerrequiredmin 0
workPassobject or nullpassTypeenumrequiredone of "EP", "S_PASS", "WP", "DP_LOC", "LTVP_LOC", "PEP", "ONE", "TEP", "OTHER"
passNumberstring or nullmax length 30
issuedOnstring | nullexpiresOnstringrequirednotesstring or nullmax length 500
emergencyContactsarray of objectnamestringrequiredmin length 1 · max length 120
relationshipstringrequiredmin length 1 · max length 60
phonestringrequiredmin length 1
inviteboolean
Responses
201 Success. object
employeeIdstringrequiredinviteobject or nullrequiredstatusenumrequiredone of "emailed", "link", "linked", "skipped"
inviteUrlstring | nullrequiredmessagestringrequired
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required - 409
conflict,duplicate_id_number,reporting_cycle
GET/api/v1/employees/{id}
Get an employee
Sections the caller may not read are omitted and listed in redactedFields.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Responses
200 Success. object
idstringrequiredemployeeNumberstringrequirednamestringrequiredlegalNamestringrequiredpreferredNamestring | nullrequiredworkEmailstring | nullrequiredstatusobjectrequiredcodeenumrequiredone of "not_started", "active", "leaving", "former", "no_tenure"
labelstringrequiredsincestringlastWorkingDaystring
jobobject or nullrequiredeffectiveFromstringrequiredYYYY-MM-DD
jobTitlestringrequireddepartmentobject or nullrequiredidstringrequirednamestringrequired
teamobject or nullrequiredidstringrequirednamestringrequired
locationobject or nullrequiredidstringrequirednamestringrequired
managerobject or nullrequiredidstringrequirednamestringrequired
employmentobjectcostCentreobject or nullrequiredidstringrequirednamestringrequired
employmentTypestringrequiredworkScheduleobject or nullrequiredidstringrequirednamestringrequired
probationEndstring | nullrequiredeaCoveredbooleanrequiredisWorkmanbooleanrequiredisManagerOrExecutivebooleanrequiredtenuresarray of objectrequiredidstringrequiredhireDatestringrequiredYYYY-MM-DD
lastWorkingDaystring | nullrequiredcessationReasonstring | nullrequirednoticeDaysnumber | nullrequired
historyarray of objectrequiredidstringrequiredeffectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequiredjobTitlestringrequireddepartmentstring | nullrequiredteamstring | nullrequiredlocationstring | nullrequiredmanagerstring | nullrequiredemploymentTypestringrequiredeventIdstringrequired
eventsarray of objectrequiredidstringrequiredtypestringrequiredeffectiveDatestringrequiredYYYY-MM-DD
statusenumrequiredone of "scheduled", "effective", "cancelled"
payloadobjectrequiredcreatedAtstringrequired
directReportsarray of objectrequiredidstringrequirednamestringrequired
personalobjectidTypestringrequiredidNumberMaskedstringrequiredsensitive: nricdobstringrequiredYYYY-MM-DD
ageintegerrequiredmin -9007199254740991
genderstring | nullrequirednationalitystring | nullrequiredresidencyStatusstringrequiredprStartDatestring | nullrequiredsprCpfOptionstring | nullrequiredsprCpfOptionApprovedOnstring | nullrequiredracestring | nullrequiredraceSecondarystring | nullrequiredreligionstring | nullrequiredshgOptOutOnstring | nullrequiredpersonalEmailstring | nullrequiredmobilestring | nullrequiredaddressobject or nullrequiredblockstring | nullstreetstring | nullunitstring | nullbuildingstring | nullpostalCodestring | nullcountrystring | null
emergencyContactsarray of objectidstringrequirednamestringrequiredrelationshipstringrequiredphonestringrequired
workPassesarray of objectidstringrequiredpassTypestringrequiredpassTypeLabelstringrequiredpassNumberMaskedstring | nullrequiredsensitive: nricissuedOnstring | nullrequiredexpiresOnstringrequiredYYYY-MM-DD
cancelledOnstring | nullrequirednotesstring | nullrequiredstateenumrequiredone of "valid", "expiring", "expired", "cancelled"
compensationobjectcurrentobject or nullrequiredidstringrequiredeffectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequiredpayBasisenumrequiredone of "monthly", "hourly"
amountCentsintegerrequiredsensitive: salarymin -9007199254740991
reasonstring | nullrequiredretroactivebooleanrequiredeventIdstringrequired
historyarray of objectrequiredidstringrequiredeffectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequiredpayBasisenumrequiredone of "monthly", "hourly"
amountCentsintegerrequiredsensitive: salarymin -9007199254740991
reasonstring | nullrequiredretroactivebooleanrequiredeventIdstringrequired
allowancesarray of objectrequiredidstringrequiredallowanceTypeIdstringrequirednamestringrequiredamountCentsintegerrequiredsensitive: salarymin -9007199254740991
effectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequired
bankobjectcurrentobject or nullrequiredidstringrequiredbankCodestringrequiredbankNamestringrequiredaccountLast4stringrequiredsensitive: bankholderNamestringrequiredsensitive: bankeffectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequired
historyarray of objectrequiredidstringrequiredbankCodestringrequiredbankNamestringrequiredaccountLast4stringrequiredsensitive: bankholderNamestringrequiredsensitive: bankeffectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequired
redactedFieldsarray of stringrequired
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
forbidden,mfa_enrolment_required - 404
not_found
PATCH/api/v1/employees/{id}
Update personal and identity details (HR)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Request body
application/json, object, required
legalNamestringmin length 1 · max length 200
preferredNamestring or nullmax length 100
idTypeenumone of "nric", "fin", "other"
idNumberstringmin length 1
dobstringgenderenum or nullone of "female", "male", "other", "undisclosed"
nationalitystring or nullmax length 60
residencyStatusenumone of "citizen", "pr", "foreigner"
prStartDatestring | nullsprCpfOptionenum or nullone of "gg", "fg", "ff"
sprCpfOptionApprovedOnstring | nullracestring or nullmax length 60
raceSecondarystring or nullmax length 60
religionenum or nullone of "buddhism", "christianity", "islam", "hinduism", "taoism", "sikhism", "other", "none", "undisclosed"
shgOptOutOnstring | nullworkEmailstring (email) or nullpersonalEmailstring (email) or nullmobilestring or nullmax length 30
addressobject or nullblockstring or nullmax length 20
streetstring or nullmax length 200
unitstring or nullmax length 20
buildingstring or nullmax length 200
postalCodestring or nullmax length 10
countrystring or nullmin length 2 · max length 2
Responses
204 No content.
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required - 404
not_found - 409
conflict,duplicate_id_number
POST/api/v1/employees/{id}/bank-accounts
Set the bank account from a date (previous one kept as history)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Request body
application/json, object, required
bankCodeenumrequiredone of "DBSSSGSG", "POSBSGSG", "OCBCSGSG", "UOVBSGSG", "SCBLSGSG", "HSBCSGS2", "CITISGSL", "MBBESGS2", "BKCHSGSG", "ICBKSGSG", "RHBBSGSG", "CIBBSGSG", "HLBBSGSG", "SIVBSGSG", "TRWISGSG", "GXSPSGSG"
accountNumberstringrequiredmin length 1
holderNamestringrequiredmin length 1 · max length 140
effectiveFromstringrequired
Responses
201 Success. object
idstringrequiredaccountMaskedstringrequired
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required,reauth_required,self_change_requires_approval - 404
not_found
POST/api/v1/employees/{id}/bank/reveal
Reveal the full current bank account number once (re-authentication, 30 per hour, audited)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Responses
200 Success. object
valuestringrequiredsensitive: bank
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required,reauth_required - 404
not_found - 429
rate_limited
GET/api/v1/employees/{id}/checklists
Onboarding and offboarding checklists
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Responses
200 Success. object
itemsarray of objectrequiredidstringrequiredkindenumrequiredone of "onboarding", "offboarding"
statusenumrequiredone of "open", "cancelled"
anchorDatestringrequiredYYYY-MM-DD
itemsarray of objectrequiredidstringrequiredtitlestringrequiredassigneeRoleenumrequiredone of "hr_admin", "payroll_admin", "manager", "employee"
dueOnstringrequiredYYYY-MM-DD
statusenumrequiredone of "open", "done", "skipped", "cancelled"
skipReasonstring | nullrequireddoneAtstring | nullrequired
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
forbidden,mfa_enrolment_required - 404
not_found
GET/api/v1/employees/{id}/compensation
Compensation history
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Responses
200 Success. object
currentobject or nullrequiredidstringrequiredeffectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequiredpayBasisenumrequiredone of "monthly", "hourly"
amountCentsintegerrequiredsensitive: salarymin -9007199254740991
reasonstring | nullrequiredretroactivebooleanrequiredeventIdstringrequired
historyarray of objectrequiredidstringrequiredeffectiveFromstringrequiredYYYY-MM-DD
effectiveTostring | nullrequiredpayBasisenumrequiredone of "monthly", "hourly"
amountCentsintegerrequiredsensitive: salarymin -9007199254740991
reasonstring | nullrequiredretroactivebooleanrequiredeventIdstringrequired
allowancesarray of objectrequiredidstringrequiredallowanceTypeIdstringrequirednamestringrequiredamountCentsintegerrequiredmin -9007199254740991
effectiveFromstringrequiredeffectiveTostring | nullrequired
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
forbidden,mfa_enrolment_required - 404
not_found
PUT/api/v1/employees/{id}/emergency-contacts
Replace emergency contacts (at most 3)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Request body
application/json, object, required
contactsarray of objectrequirednamestringrequiredmin length 1 · max length 120
relationshipstringrequiredmin length 1 · max length 60
phonestringrequiredmin length 1
Responses
204 No content.
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required - 404
not_found
POST/api/v1/employees/{id}/events
Record a lifecycle event
transfer, promotion, salary_change, probation_confirmed, resignation, termination or rehire. Future-dated events are scheduled.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Request body
application/json, object | object | object | object | object | object, required
Responses
201 Success. object
eventIdstringrequiredstatusenumrequiredone of "scheduled", "effective", "cancelled"
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required,self_change_requires_approval - 404
not_found - 409
conflict,reporting_cycle
POST/api/v1/employees/{id}/events/{eventId}/cancel
Cancel a scheduled lifecycle event
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
eventId | path | string (uuid) | yes |
Responses
204 No content.
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required - 404
not_found - 409
conflict
POST/api/v1/employees/{id}/nric/reveal
Reveal the full NRIC/FIN once (re-authentication, 30 per hour, audited)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Responses
200 Success. object
valuestringrequiredsensitive: nric
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required,reauth_required - 404
not_found - 429
rate_limited
POST/api/v1/employees/{id}/work-passes
Add a work pass
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
Request body
application/json, object, required
passTypeenumrequiredone of "EP", "S_PASS", "WP", "DP_LOC", "LTVP_LOC", "PEP", "ONE", "TEP", "OTHER"
passNumberstring or nullmax length 30
issuedOnstring | nullexpiresOnstringrequirednotesstring or nullmax length 500
Responses
201 Success. object
idstringrequiredpassTypestringrequiredpassTypeLabelstringrequiredpassNumberMaskedstring | nullrequiredsensitive: nricissuedOnstring | nullrequiredexpiresOnstringrequiredYYYY-MM-DD
cancelledOnstring | nullrequirednotesstring | nullrequiredstateenumrequiredone of "valid", "expiring", "expired", "cancelled"
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required - 404
not_found
PATCH/api/v1/employees/{id}/work-passes/{passId}
Update or cancel a work pass
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string (uuid) | yes |
passId | path | string (uuid) | yes |
Request body
application/json, object, required
passTypeenumone of "EP", "S_PASS", "WP", "DP_LOC", "LTVP_LOC", "PEP", "ONE", "TEP", "OTHER"
passNumberstring or nullmax length 30
issuedOnstring | nullexpiresOnstringnotesstring or nullmax length 500
cancelledOnstring | null
Responses
200 Success. object
idstringrequiredpassTypestringrequiredpassTypeLabelstringrequiredpassNumberMaskedstring | nullrequiredsensitive: nricissuedOnstring | nullrequiredexpiresOnstringrequiredYYYY-MM-DD
cancelledOnstring | nullrequirednotesstring | nullrequiredstateenumrequiredone of "valid", "expiring", "expired", "cancelled"
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,forbidden,mfa_enrolment_required - 404
not_found
GET/api/v1/employees/export
Export the employee list (CSV or XLSX, masked identifiers)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
format | query | enum | no |
columns | query | string | no |
q | query | string | no |
departmentId | query | string (uuid) | no |
teamId | query | string (uuid) | no |
locationId | query | string (uuid) | no |
costCentreId | query | string (uuid) | no |
managerId | query | string (uuid) | no |
status | query | string | no |
scope | query | enum | no |
Responses
200 CSV or XLSX file text/csv
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
forbidden,mfa_enrolment_required
GET/api/v1/employees/export/columns
Columns the caller may export
Responses
200 Success. object
itemsarray of objectrequiredkeystringrequiredlabelstringrequiredunmaskedbooleanrequired
- 401
session_expired,session_revoked,unauthenticated - 403
forbidden,mfa_enrolment_required
GET/api/v1/employees/export/unmasked
Export with unmasked NRIC/FIN or bank numbers (requires recent sign-in)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
format | query | enum | no |
columns | query | string | no |
q | query | string | no |
departmentId | query | string (uuid) | no |
teamId | query | string (uuid) | no |
locationId | query | string (uuid) | no |
costCentreId | query | string (uuid) | no |
managerId | query | string (uuid) | no |
status | query | string | no |
scope | query | enum | no |
Responses
200 CSV or XLSX file text/csv
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
forbidden,mfa_enrolment_required,reauth_required