Skip to main content

HR Tool - API Specification Document v3.1.7

Table of Contents

1. OVERVIEW

This document outlines the REST API specifications for the HR Tool system. The Phase 2 implementation introduces OAuth 2.0 authentication, providing enterprise-grade security and enabling Single Sign-On (SSO) capabilities.

1.1 Purpose

This API enables companies to integrate with the HR Tool for employee data synchronization, leave management, and user authentication. This also includes OAuth 2.0 implementation which allows HR Tool users to authenticate directly into their local platform using their HR Tool credentials.

1.2 Base URLs

EnvironmentBase URL
Testinghttp://xz-ai.info:8197
Productionhttps://hr.shiftcare.com/api

1.3 What's New in Phase 2

OAuth 2.0 Client Credentials Grant - Secure machine-to-machine authentication

JWT Access Tokens - RS256 signed tokens with 15-minute expiry

Enhanced Security - OWASP Top 10 compliance, rate limiting, audit logging

Improved Performance - Caching layer for faster API responses

2. AUTHENTICATION (OAuth 2.0)

IMPORTANT: All API endpoints require OAuth 2.0 authentication using Bearer tokens. Legacy authentication methods to be deprecated.

2.1 OAuth 2.0 Flow Overview

HR Tool implements the OAuth 2.0 Client Credentials Grant flow, suitable for server-to-server authentication where Shiftcare acts as the client.

Authentication Flow: Where Company is your entity.

1. Company → POST /oauth2/token with client credentials
2. HR Tool validates credentials and issues tokens
3. Company receives access_token (15 min)
4. Company uses access_token in Authorization header for API calls

2.2 Obtaining Access Tokens

Endpoint: POST /oauth2/token

Description: Obtain access token using client credentials

Request Headers:

HeaderValue
Content-Typeapplication/x-www-form-urlencoded

Request Body (form-urlencoded):

ParameterRequiredDescription
grant_typeYesMust be client_credentials
client_idYesYour application's client ID (provided by HR Tool)
client_secretYesYour application's client secret (provided by HR Tool)
scopeOptionalSpace-delimited scopes (default: read write)

Example Request (cURL):

curl -X POST https://hr.shiftcare.com/api/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"

Success Response (200 OK):

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "read write"
}

Response Fields:

access_tokenJWT access token (valid for 15 minutes)
token_typeAlways "Bearer" - use in Authorization header
expires_inToken lifetime in seconds (900 = 15 minutes)
scopeGranted permissions (space-delimited)

2.3 Using Access Tokens

Include the access token in the Authorization header of all API requests:

Authorization: Bearer YOUR_ACCESS_TOKEN

Example API Request:

curl -X GET https://hr.shiftcare.com/api/hr/v1/employees \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

2.4 JWT Token Structure

Access tokens are JSON Web Tokens (JWT) signed with RS256 algorithm. The token contains:

Standard Claims:

iss - Issuer (HR Tool)
sub - Subject (client_id)
aud - Audience (HR Tool API)
exp - Expiration time (Unix timestamp)
iat - Issued at (Unix timestamp)
jti - JWT ID (unique token identifier)

Token Verification:

Public keys for JWT verification are available at:

GET https://hr.shiftcare.com/api/oauth2/jwks

2.5 Mandatory Header for Client Credentials Grant

All business APIs accessed with a token obtained via client_credentials grant MUST include this header:
X-Enterprise-Id: {your-enterprise-id}

Location: Request Header

Required: YES

Description: Enterprise unique ID in the HR system (multi-tenant isolation)

Error: Missing or invalid value will return 400/403 Forbidden

Note: COMPANY PROVISION API No need to transfer X-Enterprise Id

3. EMPLOYEE MANAGEMENT APIs

Authentication Required: All endpoints require valid OAuth 2.0 access token in Authorization header

3.1 Get Employee List

Endpoint: GET /hr/v1/employees

Description: Retrieve paginated list of employees with filtering options

scope: employee:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)
statusinteger0=All, 1=Active, 2=Resigned, 3=Offboarding

Example Request:

GET /hr/v1/employees?page=1&size=20&status=1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"employeeId": 1997903282458996738,
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@example.com",
"phoneCode": "AU",
"phone": "+61 412345678",
"status": "1",
"employmentType": "1",
"createdDate": "2024-12-08T13:37:16",
"updatedDate": "2024-12-15T09:20:30"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

3.2 Create Employee

Endpoint: POST /hr/v1/employees

Description: Create a new employee record. Your company can call this endpoint to sync employee data from your platform to the HR Tool.

scope: employee:write

Request Body (JSON):

{
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phoneCode": "AU",
"phone": "+61 423456789",
"position": "Support Worker",
"employmentType": "1",
"hiredOn": "2024-01-15",
"username": "janedoe",
"roleId": "134",
"workPhoneCode": "AU",
"workPhone": "+24 325432345",
"employmentType": "1",
"country": "United States",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"province": "NY",
"postalCode": "Postal code",
"gender": "male",
"dateOfBirth": "1999-9-9",
"externalId": "12423123"
}

Required Fields:

firstName, lastName, email, phone, phoneCode, username, role

Note:

Employment type (1=Full-time, 2=Part-time, 3=Internship, 4=Contractor, 5=Casual, 6=Others)

roleId: using roleid from the role API

externalId: External system identifier

gender: must be male, female, non-binary, or prefer-not-to-say

Success Response (201 Created):

{
"success": true,
"statusCode": 201,
"data": {
"employeeId": 2046765589981163521,
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phoneCode": "AU",
"phone": "‌+61‌ 387654321",
"position": "Support Worker",
"status": "1",
"hiredOn": "2026-03-26",
"externalId": "shiftcare-312322",
"workPhoneCode": "AU",
"workPhone": "+24 325432345",
"employmentType": "1",
"country": "United States",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"province": "NY",
"postalCode": "Postal code",
"gender": "male",
"dateOfBirth": "1999-9-9",
"createdDate": "2026-04-22T01:38:37",
"updatedDate": "2026-04-22T01:38:37"
}
}

3.3 Get Employee Details

Endpoint: GET /hr/v1/employees/{employeeId}

Description: Retrieve detailed information for a specific employee.

scope: employee:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"employeeId": 2046765589981163521,
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phoneCode": "AU",
"phone": "‌+61‌ 387654321",
"position": "Support Worker",
"status": "1",
"hiredOn": "2026-03-26",
"externalId": "shiftcare-312322",
"workPhoneCode": "AU",
"workPhone": "+24 325432345",
"employmentType": "1",
"country": "United States",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"province": "NY",
"postalCode": "Postal code",
"createdDate": "2026-04-22T01:38:37",
"updatedDate": "2026-04-22T01:38:37"
}
}

3.4 Update Employee

Endpoint: PUT /hr/v1/employees/{employeeId}

Description: Update existing employee information

scope: employee:write

Path Parameters:

employeeId - Employee ID from HR Tool

Request Body: Same as Create Employee, only include fields to update

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"employeeId": 2046765589981163521,
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phoneCode": "AU",
"phone": "‌+61‌ 387654321",
"position": "Support Worker",
"status": "1",
"hiredOn": "2026-03-26",
"externalId": "shiftcare-312322",
"workPhoneCode": "AU",
"workPhone": "+24 325432345",
"employmentType": "1",
"country": "United States",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"province": "NY",
"postalCode": "Postal code",
"gender": "male",
"dateOfBirth": "1999-9-9",
"createdDate": "2026-04-22T01:38:37",
"updatedDate": "2026-04-22T01:38:37"
}
}

3.5 Delete Employee

Endpoint: DELETE /hr/v1/employees/{employeeId}

Description: Soft delete an employee (marks as inactive)

scope: employee:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

3.6 Offboard Employee

Endpoint: PUT /hr/v1/employees/{employeeId}/offboard

Description: Mark employee as resigned. Employee record is retained but status changed to RESIGNED.

scope: employee:admin

Query Parameters:

ParameterTypeDescription
resignationDateStringResignation date (yyyy-MM-dd)
reasonStringResignation reason (maxlength: 500)

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"employeeId": 2046765589981163521,
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phoneCode": "AU",
"phone": "‌+61‌ 387654321",
"position": "Support Worker",
"status": "2",
"hiredOn": "2026-03-26",
"externalId": "shiftcare-312322",
"workPhoneCode": "AU",
"workPhone": "+24 325432345",
"employmentType": "1",
"country": "United States",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"province": "NY",
"postalCode": "Postal code",
"createdDate": "2026-04-22T01:38:37",
"updatedDate": "2026-04-22T01:38:37"
}
}

3.7 Restore Employee

Endpoint: PUT /hr/v1/employees/{employeeId}/restore

Description: Reactivate a previously resigned employee. Changes status back to ACTIVE.

scope: employee:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"employeeId": 2046765589981163521,
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"phoneCode": "AU",
"phone": "‌+61‌ 387654321",
"position": "Support Worker",
"status": "1",
"hiredOn": "2026-03-26",
"externalId": "shiftcare-312322",
"workPhoneCode": "AU",
"workPhone": "+24 325432345",
"employmentType": "1",
"country": "United States",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"province": "NY",
"postalCode": "Postal code",
"createdDate": "2026-04-22T01:38:37",
"updatedDate": "2026-04-22T01:38:37"
}
}

4. LEAVE TYPE MANAGEMENT APIs

Authentication Required: All endpoints require valid OAuth 2.0 access token in Authorization header

4.1 Get Leave Type List

Endpoint: GET /hr/v1/leave-types

Description: Retrieve paginated list of leave types

scope: leaveType:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)

Example Request:

GET /hr/v1/leave-types?page=1&size=20 Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"leaveTypeId": 1001,
"leaveName": "Annual Leave",
"leaveType": "1",
"entitlement": 152.00,
"accrualFrequency": "4",
"resetDate": "1",
"carryOverPolicy": 40,
"carryOverStatus": "1",
"paidLeaveStatus": "1",
"maxDaysAllowed": 10,
"createDate": "2026-04-01T10:30:00",
"updatedDate": "2026-04-01T10:30:00"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

4.2 Create Leave Type

Endpoint: POST /hr/v1/leave-types

Description: Create  a new leave type in the system

scope: leaveType:write

Request Body (JSON):

{
"leaveName": "Annual Leave",
"leaveType": "1",
"entitlement": 152.00,
"accrualFrequency": "4",
"resetDate": "1",
"carryOverPolicy": 40,
"carryOverStatus": "1",
"paidLeaveStatus": "1",
"maxDaysAllowed": 10
}

Required Fields:

leaveName - Leave type name

leaveType - Leave type code (see enum values below)

All Fields:

FieldTypeRequiredDescription
leaveNameStringYesLeave type name
leaveTypeStringYesLeave type code: 1=Annual Leave, 2=Sick Leave, 3=Maternity Leave, 4=Long Service Leave, 5=Paid Leave, 6=Personal Leave, 7=Other Unpaid Leave, 8=Time off in lieu, 9=Maternity/Paternity Leave, 10=Bereavement Leave, 11=Birthday leave, 12=Carer's leave, 13=Floating Public Holiday
entitlementDecimalNoEntitlement (Hours/Year)
accrualFrequencyStringNo0=Weekly, 1=Monthly, 2=Quarterly, 3=Semi-Monthly, 4=Yearly
resetDateStringNo1=Anniversary Date, 2=Calendar Year
carryOverPolicyLongNoMaximum hours allowed to carry over
carryOverStatusStringNo1=Allow, 2=Reject
paidLeaveStatusStringNo0=Unpaid, 1=Paid

Success Response (201 Created):

{
"success": true,
"statusCode": 201,
"data": {
"leaveTypeId": 1001,
"leaveName": "Annual Leave",
"leaveType": "1",
"entitlement": 152.00,
"accrualFrequency": "4",
"resetDate": "1",
"carryOverPolicy": 40,
"carryOverStatus": "1",
"paidLeaveStatus": "1",
"maxDaysAllowed": 10,
"createDate": "2026-04-22T10:30:00",
"updatedDate": "2026-04-22T10:30:00"
}
}

4.3 Get Leave Type Details

Endpoint: GET /hr/v1/leave-types/{leaveTypeId}

Description: Retrieve detailed information for a specific leave type.

scope: leaveType:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"leaveTypeId": 1001,
"leaveName": "Annual Leave",
"leaveType": "1",
"entitlement": 152.00,
"accrualFrequency": "4",
"resetDate": "1",
"carryOverPolicy": 40,
"carryOverStatus": "1",
"paidLeaveStatus": "1",
"maxDaysAllowed": 10,
"createDate": "2026-04-01T10:30:00",
"updatedDate": "2026-04-01T10:30:00"
}
}

4.4 Update Leave Type

Endpoint: PUT /hr/v1/leave-types/{leaveTypeId}

Description: Update leave type information

scope: leaveType:write

Path Parameters:

leaveTypeId (required) - Leave type unique identifier

Request Body: Same fields as Create Leave Type, only include fields to update

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"leaveTypeId": 1001,
"leaveName": "Annual Leave (Updated)",
"leaveType": "1",
"entitlement": 160.00,
"accrualFrequency": "4",
"resetDate": "1",
"carryOverPolicy": 40,
"carryOverStatus": "1",
"paidLeaveStatus": "1",
"maxDaysAllowed": 10,
"createDate": "2026-04-01T10:30:00",
"updatedDate": "2026-04-22T14:00:00"
}
}

4.5 Delete Leave Type

Endpoint: DELETE /hr/v1/leave-types/{leaveTypeId}

Description: Delete a leave type record

scope: leaveType:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

5. LEAVE REQUEST MANAGEMENT APIs

Authentication Required: All endpoints require valid OAuth 2.0 access token in Authorization header

5.1 Get Leave Request List

Endpoint: GET /hr/v1/leave-requests

Description: Retrieve paginated list of leave requests

scope: leaveRequest:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)
statusStringLeave request status: 1=Approved, 3=Pending, 4=Rejected

Example Request:

GET /hr/v1/leave-requests?page=1&size=20 Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"leaveId": 2001,
"employeeId": 2046765589981163521,
"employeeName": "Jane Doe",
"leaveType": "1",
"fromDateTime": "2026-04-25 09:00",
"toDateTime": "2026-04-27 18:00",
"notes": "Family vacation",
"totalDays": 3,
"status": 1,
"rejectReason": null,
"approverId": null,
"approverName": null,
"createDate": "2026-04-22T10:00:00",
"updatedDate": "2026-04-22T10:00:00"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

5.2 Create Leave Request

Endpoint: POST /hr/v1/leave-requests

Description: Create  a new leave requests in the system

scope: leaveRequest:write

Request Body (JSON):

{
"employeeId": 2046765589981163521,
"leaveType": "1",
"fromDateTime": "2026-04-25 09:00",
"toDateTime": "2026-04-27 18:00",
"notes": "Family vacation",
"totalDays": 3,
"externalId": "4234"
}

Required Fields:

employeeId - Employee ID from HR Tool

leaveType - Leave type code (1-13, see Leave Type enum values in section 4.3)

fromDateTime - Start date and time (format: yyyy-MM-dd HH:mm)

toDateTime - End date and time (format: yyyy-MM-dd HH:mm)

All Fields:

FieldTypeRequiredDescription
employeeIdLongYesEmployee ID
leaveTypeStringYesLeave type code (1-13, see section 4.3)
fromDateTimeStringYesFrom date and time (yyyy-MM-dd HH:mm)
toDateTimeStringYesTo date and time (yyyy-MM-dd HH:mm)
notesStringNoLeave request notes
totalDaysDecimalNoTotal leave days
externalIdStringNoExternal system identifier

Success Response (201 Created):

{
"success": true,
"statusCode": 201,
"data": {
"leaveId": 2001,
"employeeId": 2046765589981163521,
"employeeName": "Jane Doe",
"leaveType": "1",
"fromDateTime": "2026-04-25 09:00",
"toDateTime": "2026-04-27 18:00",
"notes": "Family vacation",
"totalDays": 3,
"status": 1,
"createDate": "2026-04-22T10:00:00",
"updatedDate": "2026-04-22T10:00:00"
}
}

5.3 Get Leave Request Details

Endpoint: GET /hr/v1/leave-requests/{leaveId}

Description: Retrieve detailed information for a specific leave requests.

scope: leaveRequest:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"leaveId": 2001,
"employeeId": 2046765589981163521,
"employeeName": "Jane Doe",
"leaveType": "1",
"fromDateTime": "2026-04-25 09:00",
"toDateTime": "2026-04-27 18:00",
"notes": "Family vacation",
"totalDays": 3,
"status": 1,
"rejectReason": null,
"approverId": null,
"approverName": null,
"createDate": "2026-04-22T10:00:00",
"updatedDate": "2026-04-22T10:00:00"
}
}

5.4 Update Leave Request

Endpoint: PUT /hr/v1/leave-requests/{leaveId}

Description: Update leave request information

scope: leaveRequest:write

Path Parameters:

leaveId (required) - Leave request unique identifier

Request Body: Same fields as Create Leave Request (excluding employeeId), only include fields to update

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"leaveId": 2001,
"employeeId": 2046765589981163521,
"employeeName": "Jane Doe",
"leaveType": "1",
"fromDateTime": "2026-04-26 09:00",
"toDateTime": "2026-04-28 18:00",
"notes": "Family vacation",
"totalDays": 3,
"status": 1,
"createDate": "2026-04-22T10:00:00",
"updatedDate": "2026-04-22T14:00:00"
}
}

5.5 Approve Leave Request

Endpoint: POST /hr/v1/leave-requests/{leaveId}/approve

Description: Approve a pending leave request

scope: leaveRequest:write

Path Parameters:

leaveId (required) - Leave request unique identifier

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"leaveId": 2001,
"employeeId": 2046765589981163521,
"employeeName": "Jane Doe",
"leaveType": "1",
"fromDateTime": "2026-04-25 09:00",
"toDateTime": "2026-04-27 18:00",
"notes": "Family vacation",
"totalDays": 3,
"status": 1,
"approverId": 2046765589981163500,
"approverName": "Admin User",
"createDate": "2026-04-22T10:00:00",
"updatedDate": "2026-04-22T15:00:00"
}
}

5.6 Reject Leave Request

Endpoint: POST /hr/v1/leave-requests/{leaveId}/reject

Description: Reject a pending leave request

scope: leaveRequest:write

Path Parameters:

leaveId (required) - Leave request unique identifier

Query Parameters:

ParameterTypeDescription
rejectReasonStringReason for rejection

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"leaveId": 2001,
"employeeId": 2046765589981163521,
"employeeName": "Jane Doe",
"leaveType": "1",
"fromDateTime": "2026-04-25 09:00",
"toDateTime": "2026-04-27 18:00",
"notes": "Family vacation",
"totalDays": 3,
"status": 1,
"approverId": 2046765589981163500,
"approverName": "Admin User",
"createDate": "2026-04-22T10:00:00",
"updatedDate": "2026-04-22T15:00:00"
}
}

5.7 Delete Leave Request

Endpoint: DELETE /hr/v1/leave-requests/{leaveId}

Description: Delete a leave request record

scope: leaveRequest:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

6. POSITION MANAGEMENT APIs

Authentication Required: All endpoints require valid OAuth 2.0 access token in Authorization header

6.1 Get Position List

Endpoint: GET /hr/v1/positions

Description: Retrieve paginated list of positions

scope: position:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"positionId": 1,
"positionCode": "ENG-001",
"positionName": "Software Engineer",
"responsibilities": "Develop and maintain software systems",
"minimumSalary": 50000.0,
"maximumSalary": 100000.0,
"currency": "AUD",
"remarks": "Remote work available",
"createdDate": "2026-01-01T10:00:00",
"updatedDate": "2026-01-01T10:00:00"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

6.2 Create Position

Endpoint: POST /hr/v1/positions

Description: Create a new position record in the system

scope: position:write

Request Body (JSON):

{
"positionCode": "ENG-001",
"positionName": "Software Engineer",
"responsibilities": "Develop and maintain software systems",
"minimumSalary": 50000.0,
"maximumSalary": 100000.0,
"currency": "AUD",
"remarks": "Remote work available"
}

Required Fields:

positionName, responsibilities

All Fields:

ParameterTypeDescription
positionCodeStringPosition code (max: 50 chars)
positionNameStringPosition name (max: 100 chars) - Required
responsibilitiesStringJob responsibilities (max: 2000 chars) - Required
minimumSalaryDecimalMinimum salary (>= 0)
maximumSalaryDecimalMaximum salary (>= 0)
currencyStringCurrency code (e.g. AUD)
remarksStringAdditional remarks (max: 500 chars)

Success Response (201 Created):

{
"success": true,
"statusCode": 201,
"data": {
"positionId": 1,
"positionCode": "ENG-001",
"positionName": "Software Engineer",
"responsibilities": "Develop and maintain software systems",
"minimumSalary": 50000.0,
"maximumSalary": 100000.0,
"currency": "AUD",
"remarks": "Remote work available",
"createdDate": "2026-04-24T10:00:00",
"updatedDate": "2026-04-24T10:00:00"
}
}

6.3 Get Position Details

Endpoint: GET /hr/v1/positions/{positionId}

Description: Retrieve detailed information for a specific position

scope: position:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"positionId": 1,
"positionCode": "ENG-001",
"positionName": "Software Engineer",
"responsibilities": "Develop and maintain software systems",
"minimumSalary": 50000.0,
"maximumSalary": 100000.0,
"currency": "AUD",
"remarks": "Remote work available",
"createdDate": "2026-01-01T10:00:00",
"updatedDate": "2026-01-01T10:00:00"
}
}

6.4 Update Position

Endpoint: PUT /hr/v1/positions/{positionId}

Description: Update position information. Returns the complete updated position record.

scope: position:write

Request Body: Same fields as Create Position, only include fields to update

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"positionId": 1,
"positionCode": "ENG-001",
"positionName": "Senior Software Engineer",
"responsibilities": "Lead development and code reviews",
"minimumSalary": 70000.0,
"maximumSalary": 120000.0,
"currency": "AUD",
"remarks": "Hybrid work model",
"createdDate": "2026-01-01T10:00:00",
"updatedDate": "2026-04-24T14:00:00"
}
}

6.5 Delete Position

Endpoint: DELETE /hr/v1/positions/{positionId}

Description: Delete a position record

scope: position:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

7. JOB LISTINGS APIs

Authentication Required: All endpoints require valid OAuth 2.0 access token in Authorization header

7.1 Get Job Listings List

Endpoint: GET /hr/v1/job-listings

Description: Retrieve paginated list of job listings

scope: jobListings:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)
statusintegerStatus filter: 0=Discontinued, 1=Published

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"id": "abc123",
"title": "Senior Software Engineer",
"employmentType": 3,
"location": "Sydney, NSW",
"currency": "AUD",
"payMin": 80000,
"payMax": 120000,
"salaryType": 5,
"payType": 2,
"showPay": true,
"status": 1
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

7.2 Create Job Listing

Endpoint: POST /hr/v1/job-listings

Description: Create a new job listing record in the system

scope: jobListings:write

Request Body (JSON):

{
"title": "Senior Software Engineer",
"employmentType": 3,
"contentBody": "We are looking for...",
"contentFormatting": "html",
"location": "Sydney, NSW",
"currency": "AUD",
"payMin": 80000,
"payMax": 120000,
"salaryType": 5,
"payType": 2,
"showPay": true,
"showExperience": 3,
"status": 1,
"questions": [
{
"questionMsg": "What is your expected salary?",
"questionType": 1,
"isAnswerVideo": false,
"questionIndex": 1
}
]
}

Required Fields:

title, employmentType

All Fields:

ParameterTypeDescription
titleStringJob listing title (max: 200 chars) - Required
employmentTypeInteger1=Casual, 2=Part time, 3=Full time - Required
contentBodyStringJob description content
contentFormattingStringContent format: text or html
locationStringJob location (max: 200 chars)
currencyStringPay currency (max: 10 chars)
payMinDecimalMinimum pay amount (>= 0)
payMaxDecimalMaximum pay amount (>= 0)
salaryTypeInteger1=hourly, 2=daily, 3=weekly, 4=monthly, 5=annual
payTypeInteger1=Exact amount, 2=Pay range
showPayBooleanWhether to show pay on listing
showExperienceInteger0=no requirement, other=years of experience
statusInteger0=Discontinued, 1=Published
questionsArrayScreening questions (see Question Object below)

Question Object Fields:

ParameterTypeDescription
questionMsgStringQuestion text (max: 500 chars) - Required
questionTypeInteger1=Short answer, 2=Yes/No, 3=Single select - Required
answerOptionsStringComma-separated options (for Single select type)
isAnswerVideoBooleanWhether video answer is required
questionIndexIntegerQuestion display order index

Success Response (201 Created):

{
"code": 201,
"msg": "Job listing created successfully",
"data": {
"id": "abc123",
"title": "Senior Software Engineer",
"employmentType": 3,
"location": "Sydney, NSW",
"currency": "AUD",
"payMin": 80000,
"payMax": 120000,
"salaryType": 5,
"payType": 2,
"showPay": true,
"status": 1,
"questions": []
}
}

7.3 Get Job Listing Details

Endpoint: GET /hr/v1/job-listings/{id}

Description: Retrieve detailed information for a specific job listing

scope: jobListings:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"id": "abc123",
"title": "Senior Software Engineer",
"employmentType": 3,
"contentBody": "We are looking for...",
"contentFormatting": "html",
"location": "Sydney, NSW",
"currency": "AUD",
"payMin": 80000,
"payMax": 120000,
"salaryType": 5,
"payType": 2,
"showPay": true,
"showExperience": 3,
"status": 1,
"questions": []
}
}

7.4 Update Job Listing

Endpoint: PUT /hr/v1/job-listings/{id}

Description: Update job listing information. Returns the complete updated job listing record.

scope: jobListings:write

Request Body: Same fields as Create Job Listing, only include fields to update. Question objects require id field (UUID) for updates.

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"id": "abc123",
"title": "Senior Software Engineer (Updated)",
"employmentType": 3,
"status": 1
}
}

7.5 Delete Job Listing

Endpoint: DELETE /hr/v1/job-listings/{id}

Description: Delete a job listing record

scope: jobListings:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

8. HOLIDAY ENTITLEMENTS APIs

Authentication Required: All endpoints require valid OAuth 2.0 access token in Authorization header

8.1 Get Holiday Entitlements List

Endpoint: GET /hr/v1/holidays

Description: Retrieve paginated list of holiday entitlements for an employee

scope: holidays:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"empleHolidayId": 1,
"employeeId": 123456789,
"holidayName": "Annual Leave",
"holidayType": "1",
"fromDate": "2026-01-01",
"toDate": "2026-12-31",
"createdDate": "2026-04-27T10:00:00",
"updatedDate": "2026-04-27T10:00:00"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

8.2 Create Holiday Entitlement

Endpoint: POST /hr/v1/holidays

Description: Create a new holiday entitlement record for an employee

scope: holiday:write

Request Body (JSON):

{
"employeeId": 123456789,
"holidayName": "Annual Leave",
"holidayType": "1",
"fromDate": "2026-01-01",
"toDate": "2026-12-31"
}

Required Fields:

employeeId, holidayName, holidayType, fromDate, toDate

All Fields:

ParameterTypeDescription
employeeIdLongEmployee ID - Required
holidayNameStringHoliday entitlement name (max: 100 chars) - Required
holidayTypeStringHoliday type: 1=Public Holidays, 2=Private holidays, 3=Company holidays - Required
fromDateStringStart date (yyyy-MM-dd format) - Required
toDateStringEnd date (yyyy-MM-dd format) - Required
employeeIdLongEmployee ID - Required
holidayNameStringHoliday entitlement name (max: 100 chars) - Required

Success Response (201 Created):

{
"code": 201,
"msg": "Job listing created successfully",
"data": {
"empleHolidayId": 1,
"employeeId": 123456789,
"holidayName": "Annual Leave",
"holidayType": "1",
"fromDate": "2026-01-01",
"toDate": "2026-12-31",
"createdDate": "2026-04-27T10:00:00",
"updatedDate": "2026-04-27T10:00:00"
}
}

8.3 Get Holiday Entitlement Details

Endpoint: GET /hr/v1/holidays/{id}

Description: Retrieve detailed information for a specific holiday entitlement

scope: holiday:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"empleHolidayId": 1,
"employeeId": 123456789,
"holidayName": "Annual Leave",
"holidayType": "1",
"fromDate": "2026-01-01",
"toDate": "2026-12-31",
"createdDate": "2026-04-27T10:00:00",
"updatedDate": "2026-04-27T10:00:00"
}
}

8.4 Update Holiday Entitlement

Endpoint: PUT /hr/v1/holidays/{id}

Description: Update holiday entitlement information. Returns the complete updated record.

scope: holiday:write

Request Body: Same fields as Create Holiday Entitlement, only include fields to update. Question objects require id field (UUID) for updates.

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"empleHolidayId": 1,
"employeeId": 123456789,
"holidayName": "Annual Leave",
"holidayType": "1",
"fromDate": "2026-01-01",
"toDate": "2026-12-31",
"createdDate": "2026-04-27T10:00:00",
"updatedDate": "2026-04-27T10:00:00"
}
}

8.5 Delete Holiday Entitlement

Endpoint: DELETE /hr/v1/holidays/{id}

Description: Delete a holiday entitlement record

scope: holiday:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

9. DEPARTMENT MANAGEMENT APIs

Authentication Required: All endpoints require valid OAuth 2.0 access token.

9.1 Get Department List

Endpoint: GET /hr/v1/departments

Description: Retrieve paginated list of departments.

Scope: department:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)
X-Enterprise-IdheaderEnterprise ID (required for client_credentials)

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"deptId": 1,
"deptName": "Engineering",
"orderNum": 1,
"leader": 1001,
"leaderName": "John Smith",
"status": "0",
"empNum": 15
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 5,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

9.2 Create Department

Endpoint: POST /hr/v1/departments

Description: Create a new department in the system.

Scope: department:write

Required Fields: deptName, leader

Request Body (JSON):

{
"deptName": "Engineering",
"leader": 1001,
"orderNum": 1,
"status": "0",
"description": "Responsible for software development",
"employeeIds": [1001, 1002, 1003]
}

Success Response (201 Created):

{
"success": true,
"statusCode": 201,
"data": {
"deptId": 1,
"deptName": "Engineering",
"leader": 1001,
"status": "0"
}
}

9.3 Get Department Details

Endpoint: GET /hr/v1/departments/{deptId}

Description: Retrieve detailed information for a specific department.

Scope: department:read

Path Parameters:

ParameterDescription
deptIdDepartment ID (integer)

9.4 Update Department

Endpoint: PUT /hr/v1/departments/{deptId}

Description: Update department information.

Scope: department:write

Request Body fields: deptName, orderNum, leader, status, description, employeeIds (replaces existing).

9.5 Delete Department

Endpoint: DELETE /hr/v1/departments/{deptId}

Description: Delete a department record.

Scope: department:admin

Success Response (200 OK) on successful deletion.

10. ROLE MANAGEMENT APIs

10.1 Get Role List

Endpoint: GET /hr/v1/roles

Description: Retrieve paginated list of roles.

Scope: role:read

Query Parameters: page (default: 1), size (max: 100, default: 20).

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"roleId": 1,
"roleName": "HR Manager",
"roleKey": "hr_manager",
"status": "0",
"menuIds": [1, 2, 3],
"roleSort": 1,
"createdDate": "2025-01-01T00:00:00",
"updatedDate": "2025-06-01T00:00:00"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

10.2 Create Role

Endpoint: POST /hr/v1/roles

Description: Create a new role record.

Scope: role:write

Required Fields: roleName, roleKey

Request Body (JSON):

{
"roleName": "HR Manager",
"roleKey": "hr_manager",
"status": "0",
"menuIds": [1, 2, 3],
"remarks": "HR management role"
}

Success Response (201 Created):

{
"success": true,
"statusCode": 201,
"data": {
"roleId": 1,
"roleName": "HR Manager",
"roleKey": "hr_manager",
"status": "0"
}
}

10.3 Get Role Details

Endpoint: GET /hr/v1/roles/{roleId}

Description: Retrieve detailed information for a specific role.

Scope: role:read

10.4 Update Role

Endpoint: PUT /hr/v1/roles/{roleId}

Description: Update role information.

Scope: role:write

Request Body fields: roleName, roleKey, status (0=Normal, 1=Disabled), menuIds, remarks.

10.5 Delete Role

Endpoint: DELETE /hr/v1/roles/{roleId}

Description: Delete a role record.

Scope: role:admin

11. POLICY MANAGEMENT APIs

11.1 Get Policy List

Endpoint: GET /hr/v1/policies

Description: Retrieve paginated list of policies.

Scope: policy:read

Query Parameters: page (default: 1), size (max: 100, default: 20).

11.2 Create Policy

Endpoint: POST /hr/v1/policies

Description: Create a new policy. Supports both JSON body and multipart/form-data (with file upload).

Scope: policy:write

Required Fields: title

Request Body (JSON):

{
"title": "Code of Conduct Policy",
"deptId": 1,
"audience": "1",
"deptIds": [1, 2, 3],
"employeeIds": [100, 101, 102],
"attachmentUrl": "https://minio.example.com/bucket/policy.pdf",
"effectiveDate": "2026-01-01",
"acknowledgementDeadline": "2026-12-31",
"mandatoryAcknowledgement": true,
"resetAcknowledgement": false
}

Audience type: 1=Global, 2=Department, 3=Specific employees.

For multipart upload, pass file as form-data field and other fields as query parameters.

Success Response (201 Created):

{
"success": true,
"statusCode": 201,
"data": {
"policyId": 1,
"title": "Code of Conduct Policy",
"status": "DRAFT",
"audience": "1",
"audienceLabel": "Global",
"mandatoryAcknowledgement": true
}
}

11.3 Get Policy Details

Endpoint: GET /hr/v1/policies/{policyId}

Description: Retrieve policy details by ID.

Scope: policy:read

11.4 Update Policy

Endpoint: PUT /hr/v1/policies/{policyId}

Description: Update policy via JSON body or multipart/form-data.

Scope: policy:write

Request Body fields: title, audience, deptIds, employeeIds, attachmentUrl, effectiveDate, acknowledgementDeadline, mandatoryAcknowledgement, resetAcknowledgement, status (DRAFT/ACTIVE/ARCHIVED).

11.5 ARCHIVED Policy

Endpoint: POST /hr/v1/policies/{policyId}/archived

Description: Change policy status to ARCHIVED.

Scope: policy:write

Success Response (200 OK) with updated policy data.

11.6 Delete Policy

Endpoint: DELETE /hr/v1/policies/{policyId}

Description: Delete a policy and all its assignments.

Scope: policy:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

12. DOCUMENT MANAGEMENT APIs

12.1 Get Document List

Endpoint: GET /hr/v1/documents

Description: Retrieve paginated list of documents.

Scope: document:read

Query Parameters: page (default: 1), size (max: 100, default: 20).

12.2 Create Document

Endpoint: POST /hr/v1/documents

Description: Create a new document. Supports JSON body or multipart/form-data.

Scope: document:write

Required Fields (JSON): employeeId, documentName

Request Body (JSON):

{
"documentId": 1654546752552,
"employeeId": 1642343324555,
"documentName": "Employment Contract",
"fileUrl": "https://storage.example.com/contract.pdf",
"description": "Annual employment contract",
"status": "1",
"externalId": "4234",
"expiresAt": "2027-12-31",
"invitees": [
{ "sharedToEmployeeId": 123, "permissionType": "2" }
]
}

Note:

fileUrl: External temporary file URL. When provided, server will download the file and upload to MinIO. Takes priority over filePath.

permissionType: 1=READ, 2=DOWNLOAD

status: 0=disabled, 1=enabled

externalId: External system identifier

expiresAt: Document expiry date (yyyy-MM-dd)

12.3 Get Document Details

Endpoint: GET /hr/v1/documents/{documentId}

Description: Retrieve document with full invitee list.

Scope: document:read

12.4 Update Document

Endpoint: PUT /hr/v1/documents/{documentId}

Description: Update document information.

Scope: document:write

Request Body fields: documentName, fileUrl, description, status, expiresAt, invitees.

12.5 Delete Document

Endpoint: DELETE /hr/v1/documents/{documentId}

Description: Delete a document record and all its shares.

Scope: document:admin

Success Response (200 OK):

{
"success": true,
"statusCode": 200
}

13. EMPLOYEE CONTRACT APIs

13.1 Get Contract List

Endpoint: GET /hr/v1/contracts

Description: Retrieve paginated list of employee contracts.

Scope: contract:read

Query Parameters: page (default: 1), size (max: 100, default: 20).

13.2 Get Expired Contracts

Endpoint: GET /hr/v1/contracts/expired

Description: Retrieve paginated list of expired contracts.

Scope: contract:read

13.3 Create Contract

Endpoint: POST /hr/v1/contracts

Description: Create a new employee contract.

Scope: contract:write

Required Fields: employeeId, contractStartTime, contractEndTime

Request Body (JSON):

{
"employeeId": 1001,
"templateId": 5,
"position": "Engineer",
"contractName": "EMP-2026-001",
"contractType": "2",
"contractStartTime": "2026-01-01T00:00:00",
"contractEndTime": "2027-01-01T00:00:00",
"accessory": "https://storage.example.com/contract.pdf",
"isRenewal": "1"
}

contractType: 1=Paper, 2=Electronic | isRenewal: 1=No, 2=Yes

13.4 Get Contract by ID

Endpoint: GET /hr/v1/contracts/{id}

Description: Retrieve a specific employee contract.

Scope: contract:read

13.5 Update Contract

Endpoint: PUT /hr/v1/contracts/{id}

Description: Update employee contract.

Scope: contract:write

Request Body fields: templateId, position, contractName, contractType, contractStartTime, contractEndTime, signStatu (1=Pending, 2=Signed), isMaturity (0=No, 1=Yes), accessory, signDate.

13.6 Renew Contract

Endpoint: POST /hr/v1/contracts/{id}/renew

Description: Creates a new contract as a renewal of the specified contract.

Scope: contract:write

Required Fields: templateId, contractStartTime, contractEndTime

Request Body (JSON):

{
"templateId": 5,
"contractType": "2",
"contractStartTime": "2027-01-01T00:00:00",
"contractEndTime": "2028-01-01T00:00:00",
"accessory": "https://storage.example.com/renewed-contract.pdf",
"isRenewal": "2"
}

13.7 Delete Contract

Endpoint: DELETE /hr/v1/contracts/{id}

Description: Delete an employee contract record.

Scope: contract:admin

14. CONTRACT TEMPLATE APIs

14.1 Get Template List

Endpoint: GET /hr/v1/contracts/templates

Description: Retrieve paginated list of contract templates.

Scope: contractTemplate:read

Query Parameters: page (default: 1), size (max: 100, default: 20).

14.2 Create Template

Endpoint: POST /hr/v1/contracts/templates

Description: Create a new contract template.

Scope: contractTemplate:write

Required Fields: templateName

Request Body (JSON):

{
"templateName": "Standard Employment Contract",
"templateContent": "<p>This agreement...</p>",
"status": "0"
}

templateContent is an HTML string. status: 0=Normal, 1=Deactivated.

14.3 Get Template by ID

Endpoint: GET /hr/v1/contracts/templates/{templateId}

Description: Retrieve a specific contract template.

Scope: contractTemplate:read

14.4 Update Template

Endpoint: PUT /hr/v1/contracts/templates/{templateId}

Description: Update contract template.

Scope: contractTemplate:write

Required Fields: templateName. Other fields: templateContent (HTML), status.

14.5 Delete Template

Endpoint: DELETE /hr/v1/contracts/templates/{templateId}

Description: Delete a contract template record.

Scope: contractTemplate:admin

15. COMPANY SETTINGS APIs

15.1 Get Company Settings

Endpoint: GET /hr/v1/company-settings

Description: Retrieve company settings including security and working hours.

Scope: companySettings:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"enterpriseId": "ent_xxx",
"securitySettings": {
"minPasswordLength": 8,
"requireNumbers": true,
"requireUppercase": true,
"requireSpecialChars": true,
"enable2fa": false,
"sessionTimeoutMinutes": 30,
"maxFailedAttempts": 5
},
"workingHours": {
"defaultStartTime": "09:00:00",
"defaultEndTime": "18:00:00",
"gracePeriod": 15,
"enableOvertime": "1",
"maximumOvertime": 120
}
}
}

15.2 Update Company Settings

Endpoint: PUT /hr/v1/company-settings

Description: Update company settings including security and working hours.

Scope: companySettings:write

Request Body (JSON):

{
"securitySettings": {
"minPasswordLength": 8,
"requireNumbers": true,
"requireUppercase": true,
"requireSpecialChars": true,
"enable2fa": false,
"sessionTimeoutMinutes": 30,
"maxFailedAttempts": 5
},
"workingHours": {
"defaultStartTime": "09:00:00",
"defaultEndTime": "18:00:00",
"gracePeriod": 15,
"enableOvertime": "1",
"maximumOvertime": 120
}
}

enableOvertime: 1=Yes, 2=No | gracePeriod: 0-60 minutes | sessionTimeoutMinutes: 5-480

16. FILE UPLOAD API

16.1 Upload File

Endpoint: POST /hr/v1/files

Description: Upload a file to MinIO storage. Returns file URL and metadata.

Scope: file:write

Request: multipart/form-data with 'file' field (max size: 50MB).

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"fileName": "document.pdf",
"fileUrl": "https://minio.example.com/bucket/path/document.pdf",
"fileSize": 102400,
"fileType": "application/pdf"
}
}

The returned fileUrl can be used as attachmentUrl when creating policies or as filePath when creating documents.

17. MENU MANAGEMENT APIs

17.1 Get Menu List

Endpoint: GET /hr/v1/menus

Description: Retrieve list of all menus.

Scope: role:read

17.2 Get Menu Tree

Endpoint: GET /hr/v1/menus/tree

Description: Retrieve hierarchical menu tree structure.

Scope: role:read

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"menuId": 1,
"menuName": "Dashboard",
"parentId": 0,
"orderNum": 1,
"path": "/dashboard",
"menuType": "C",
"visible": "0",
"status": "0",
"perms": "dashboard:list",
"children": []
}
]
}

menuType: M=Directory, C=Menu, F=Button | visible: 0=Show, 1=Hide | status: 0=Normal, 1=Disabled

17.3 Get Menu by ID

Endpoint: GET /hr/v1/menus/{menuId}

Description: Retrieve a specific menu item.

Scope: role:read

17. COMPANY PROVISION API

Note: This is an internal API for ShiftCare to auto-provision new HR company instances. It requires a client_credentials M2M token with company:admin scope.

This API does not transmit X-Enterprise-Id

17.1 Auto-Provision HR Company Instance

Endpoint: POST /hr/v1/companies/provision

Description: Creates a new HR company, initializes system roles, creates the initial admin account, and binds the Shiftcare credentials.Triggered by ShiftCare on trial creation or plan purchase with HR add-on.

Scope: company:admin (client_credentials M2M token only)

Required Fields: companyName, contactEmail, adminFullName, adminEmail, adminUsername

Request Body (JSON):

{
"companyName": "Acme Corp",
"industryType": "healthcare",
"country": "AU",
"timeZone": "Australia/Sydney",
"contactEmail": "admin@acme.com",
"currency": "AUD",
"phone": "0400000000",
"phoneCode": "+61",
"logoUrl": "https://cdn.shiftcare.com/logos/acme.png",
"planId": "trial",
"adminFullName": "John Smith",
"adminEmail": "john@acme.com",
"adminUsername": "john.smith",
"encryptedApiCredentials": {
"iv": "MXc3JZLahWmB+FSO",
"ciphertext": "0KQlNzQ3Ufj+1cVSiZZ50C4IYbCdGOPTBOpCGBUFopR3fJ2ioouOz9mHHmLY27qc09Jk4MmP/M6pPPT5wH4On+dcgUlzFurZBVO2cdWNyF/DD7Ml6mS6koHxiVS23F42NQZOHQ=="
}
}

Success Response (201 Created):

{
"enterpriseId": "1234567890123456789",
"companyName": "Acme Corp",
"createdFrom": "Shiftcare",
"adminUsername": "john.smith",
"adminEmail": "john@acme.com",
"status": "provisioned",
"createdAt": "2026-04-27T10:00:00Z"
}

Error Responses:

HTTP CodeDescription
400Invalid request - validation errors
401Unauthorized - invalid or expired token
403Forbidden - insufficient scope or user JWT not allowed
409Conflict - company with same email already exists
500Internal server error

18. REPORT API

18.1 Get Emergency Contacts Report List

Endpoint: GET /hr/v1/reports/emergency-contacts

Description: Retrieve paginated list of employee emergency contacts.

Scope: employee:read

Query Parameters: page (default: 1), size (max: 100, default: 20).

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"leaveId": 2001,
"employeeId": 2046765589981163521,
"employeeName": "Jane Doe",
"leaveType": "1",
"fromDateTime": "2026-04-25 09:00",
"toDateTime": "2026-04-27 18:00",
"notes": "Family vacation",
"totalDays": 3,
"status": 1,
"rejectReason": null,
"approverId": null,
"approverName": null,
"createDate": "2026-04-22T10:00:00",
"updatedDate": "2026-04-22T10:00:00"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false
}
}

18.2 Get Leave Report Statistics

Endpoint: GET /hr/v1/reports/leave-statistics

Description: Retrieve leave statistics summary.

Scope: leaveRequest:read

Query Parameters:

ParameterTypeDescription
leaveTypeStringLeave type code (1-13, see section 4.3)
deptIdLongDepartment ID filter
startDateStringStart date filter (YYYY-MM-DD)
endDateStringEnd date filter (YYYY-MM-DD)

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": {
"totalLeaveLiability": 0.0,
"totalAccruedThisPeriod": 0,
"totalTakenThisPeriod": 23
}
}

18.3 Get Leave Report List

Endpoint: GET /hr/v1/reports/leave-report-list

Description: Retrieve paginated leave report list with filters.

Scope: leaveRequest:read

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
sizeintegerPage size (max: 100, default: 20)
leaveTypeStringLeave type code (1-13, see section 4.3)
deptIdLongDepartment ID filter
startDateStringStart date filter (YYYY-MM-DD)
endDateStringEnd date filter (YYYY-MM-DD)

Success Response (200 OK):

{
"success": true,
"statusCode": 200,
"data": [
{
"employeeId": 1980092118274641922,
"employeeName": "AFrank11 AAFrank11",
"deptName": "Test",
"leaveType": "13",
"opening": 1,
"taken": 1
}
],
"pagination": {
"currentPage": 1,
"pageSize": 3,
"totalItems": 96,
"totalPages": 32,
"hasNextPage": true,
"hasPreviousPage": false
}
}

18. ERROR HANDLING

18.1 Standard Error Response

All error responses follow a consistent format:

{
"success": false,
"statusCode": 400,
"errorMessage": "Missing required field: email",
}

18.2 HTTP Status Codes

CodeStatusDescription
200OKRequest succeeded
201CreatedResource created successfully
400Bad RequestInvalid request format or missing required fields
401UnauthorizedMissing, invalid, or expired access token
403ForbiddenInsufficient permissions for requested operation
404Not FoundResource not found
429Too Many RequestsRate limit exceeded (100 req/min per client)
500Internal Server ErrorServer error - contact support if persists

18.3 OAuth Error Codes

OAuth 2.0 token endpoint returns specific error codes per RFC 6749:

Error CodeDescription
invalid_requestMalformed request (missing parameters, etc.)
invalid_clientInvalid client_id or client_secret
invalid_grantInvalid or expired refresh_token
unauthorized_clientClient not authorized for this grant type
unsupported_grant_typeGrant type not supported

19. RATE LIMITING & SECURITY

19.1 Rate Limits

API requests are rate limited to ensure system stability:

Endpoint TypeLimit
OAuth Token Endpoint10 requests per minute per IP address
General API Endpoints100 requests per minute per client_id

Rate Limit Headers:

Response headers include rate limit information:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1702387200

When rate limit is exceeded:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
"success": false,
"statusCode": 429,
"errorMessage": "API rate limit exceeded",
}

19.2 Security Requirements

HTTPS Required: All API calls must use HTTPS (TLS 1.2 minimum)

Token Storage: Store client_secret securely, never expose in client-side code

Token Transmission: Only send tokens in Authorization header, never in URL

Error Handling: Don't log sensitive information (tokens, secrets) in error messages

20. INTEGRATION CHECKLIST FOR YOUR COMPANY

Required Actions:

20.1 Pre-Integration

Obtain OAuth 2.0 credentials (client_id and client_secret) from HR Tool

Confirm external_id mapping strategy for employees

Set up testing environment access

20.2 Implementation Tasks

Implement OAuth 2.0 client credentials flow

Implement token refresh logic with proper rotation

Implement JWT signature verification using public keys

Build employee sync logic (create, update, delete)

Implement error handling and retry logic

Handle rate limiting with exponential backoff

20.3 Testing Requirements

Test OAuth token acquisition in testing environment

Test token refresh and rotation

Test employee CRUD operations

Test error scenarios (invalid tokens, rate limits, etc.)

Load testing to verify rate limits

20.4 Production Readiness

Complete security review

Set up monitoring and alerting

Configure production credentials

Document integration for internal teams

Plan rollout and migration strategy

APPENDIX A: QUICK REFERENCE

A.1 Key Endpoints Summary

MethodEndpointDescription
POST/oauth2/tokenGet access token
GET/hr/v1/employeesList employees
POST/hr/v1/employeesCreate employee
PUT/hr/v1/employees/{id}Update employee
DELETE/hr/v1/employees/{id}Delete employee
PUT/hr/v1/employees/{id}/offboardOffboard employee
PUT/hr/v1/employees/{id}/restoreRestore employee
GET/hr/v1/employees/{id}Get employee Details
GET/hr/v1/leave-typesList leave types
POST/hr/v1/leave-typesCreate leave type
GET/hr/v1/leave-types/{id}Get leave type details
PUT/hr/v1/leave-types/{id}Update leave type
DELETE/hr/v1/leave-types/{id}Delete leave type
GET/hr/v1/leave-requestsList leave requests
POST/hr/v1/leave-requestsCreate leave request
GET/hr/v1/leave-requests/{id}Get leave request details
PUT/hr/v1/leave-requests/{id}Update leave request
POST/hr/v1/leave-requests/{id}/approveApprove leave request
POST/hr/v1/leave-requests/{id}/rejectReject leave request
DELETE/hr/v1/leave-requests/{id}Delete leave request
GET/hr/v1/positionsList positions
POST/hr/v1/positionsCreate position
GET/hr/v1/positions/{id}Get position details
PUT/hr/v1/positions/{id}Update position
DELETE/hr/v1/positions/{id}Delete position
GET/hr/v1/job-listingsList job listings
POST/hr/v1/job-listingsCreate job listing
GET/hr/v1/job-listings/{id}Get job listing details
PUT/hr/v1/job-listings/{id}Update job listing
DELETE/hr/v1/job-listings/{id}Delete job listing
GET/hr/v1/departmentsList departments
POST/hr/v1/departmentsCreate department
GET/hr/v1/departments/{deptId}Get department details
PUT/hr/v1/departments/{deptId}Update department
DELETE/hr/v1/departments/{deptId}Delete department
GET/hr/v1/rolesList roles
POST/hr/v1/rolesCreate role
GET/hr/v1/roles/{roleId}Get role details
PUT/hr/v1/roles/{roleId}Update role
DELETE/hr/v1/roles/{roleId}Delete role
GET/hr/v1/policiesList policies
POST/hr/v1/policiesCreate policy
GET/hr/v1/policies/{policyId}Get policy details
PUT/hr/v1/policies/{policyId}Update policy
POST/hr/v1/policies/{policyId}/publishPublish policy
DELETE/hr/v1/policies/{policyId}Delete policy
GET/hr/v1/documentsList documents
POST/hr/v1/documentsCreate document
GET/hr/v1/documents/{documentId}Get document details
PUT/hr/v1/documents/{documentId}Update document
DELETE/hr/v1/documents/{documentId}Delete document
GET/hr/v1/contractsList employee contracts
POST/hr/v1/contractsCreate employee contract
GET/hr/v1/contracts/expiredGet expired contracts
GET/hr/v1/contracts/{id}Get contract by ID
PUT/hr/v1/contracts/{id}Update contract
POST/hr/v1/contracts/{id}/renewRenew contract
DELETE/hr/v1/contracts/{id}Delete contract
GET/hr/v1/contracts/templatesList contract templates
POST/hr/v1/contracts/templatesCreate contract template
GET/hr/v1/contracts/templates/{templateId}Get template by ID
PUT/hr/v1/contracts/templates/{templateId}Update template
DELETE/hr/v1/contracts/templates/{templateId}Delete template
GET/hr/v1/company-settingsGet company settings
PUT/hr/v1/company-settingsUpdate company settings
POST/hr/v1/filesUpload file
GET/hr/v1/menusList menus
GET/hr/v1/menus/treeGet menu tree
GET/hr/v1/menus/{menuId}Get menu by ID
POST/hr/v1/companies/provisionAuto-provision company instance
GET/hr/v1/holidaysList holiday entitlements
GET/hr/v1/holidays/{holidayId}Get holiday entitlement by ID
POST/hr/v1/holidaysCreate holiday entitlement
PUT/hr/v1/holidays/{holidayId}Update holiday entitlement
DELETE/hr/v1/holidays/{holidayId}Delete holiday entitlement
GET/hr/v1/reports/emergency-contactsGet emergency contacts reports
GET/hr/v1/reports/leave-statisticsRetrieve leave statistics summary
GET/hr/v1/reports/leave-report-listRetrieve paginated leave report list with filters

A.2 Token Lifetimes

TokenLifetime
Access Token15 minutes