Complete API documentation for the leave management system.
All API endpoints are prefixed with the following base URL.
https://api.adamus.com/api/v1OTP authentication by SMS or email. Codes are 4 digits and expire after 10 minutes.
POST /auth/request-sms-otp
Sends a 4-digit OTP to the user's phone number via SMS for authentication.
{
"phone": "+233XXXXXXXXX"
}{
"status": "success",
"message": "OTP sent to phone number",
"data": {
"phone": "+233XXXXXXXXX"
}
}Preferred endpoint for SMS-based authentication.
POST /auth/request-otp
Sends a 4-digit OTP to the user's phone number via SMS for authentication.
{
"phone": "+233XXXXXXXXX"
}{
"status": "success",
"message": "OTP sent to phone number",
"data": {
"phone": "+233XXXXXXXXX"
}
}Maintained for backward compatibility. Use /auth/request-sms-otp for new implementations.
POST /auth/verify-sms-otp
Verifies the SMS OTP provided by the user and returns a JWT token if valid.
{
"phone": "+233XXXXXXXXX",
"otp": "1234"
}{
"status": "success",
"message": "Authentication successful",
"data": {
"user": {
"_id": "6075d1505f943a2e34b1fff1",
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"role": "staff",
"permissions": [],
"department": "6075d1505f943a2e34b1fff2",
"position": "Software Engineer",
"staffId": "EMP001"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}Preferred endpoint for SMS-based authentication.
POST /auth/verify-otp
Verifies the SMS OTP provided by the user and returns a JWT token if valid.
{
"phone": "+233XXXXXXXXX",
"otp": "1234"
}{
"status": "success",
"message": "Authentication successful",
"data": {
"user": {
"_id": "6075d1505f943a2e34b1fff1",
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"role": "staff",
"permissions": [],
"department": "6075d1505f943a2e34b1fff2",
"position": "Software Engineer",
"staffId": "EMP001"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}POST /auth/request-email-otp
Sends a 4-digit OTP to the user's email address for authentication.
{
"email": "user@example.com"
}{
"status": "success",
"message": "OTP sent to email address",
"data": {
"email": "user@example.com"
}
}Returns 404 if no active user has this email, and 500 if the email could not be sent.
POST /auth/verify-email-otp
Verifies the email OTP provided by the user and returns a JWT token if valid.
{
"email": "user@example.com",
"otp": "1234"
}{
"status": "success",
"message": "Authentication successful",
"data": {
"user": {
"_id": "6075d1505f943a2e34b1fff1",
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"role": "staff",
"permissions": [],
"department": "6075d1505f943a2e34b1fff2",
"position": "Software Engineer",
"staffId": "EMP001"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}Returns 401 for a wrong code, or for a code that has expired or was already used.
Endpoints for managing departments
GET /departments
Retrieves all departments, optionally in a hierarchical structure.
| Parameter | Type | Description | Required |
|---|---|---|---|
| hierarchical | Boolean | If true, returns departments in a hierarchical structure | No |
GET /departments?id={departmentId}
Retrieves a specific department by its ID.
GET /departments?id={departmentId}&users=true
Retrieves all users in a specific department, with pagination support.
| Parameter | Type | Description | Required |
|---|---|---|---|
| includeSubDepartments | Boolean | If true, includes users from sub-departments | No |
| page | Number | Page number for pagination | No |
| limit | Number | Number of users per page | No |
POST /departments
Creates a new department.
{
"name": "Engineering",
"description": "Software Engineering Department",
"manager": "6075d1505f943a2e34b1fff1",
"parent": "6075d1505f943a2e34b1fff3" // Optional parent department
}{
"status": "success",
"message": "Department created successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff4",
"name": "Engineering",
"description": "Software Engineering Department",
"manager": "6075d1505f943a2e34b1fff1",
"parent": "6075d1505f943a2e34b1fff3",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}Endpoints for calculating leave details before submission
POST /leave-calculator
Calculates leave details based on input parameters.
{
"startDate": "2025-05-01T00:00:00.000Z",
"endDate": "2025-05-10T00:00:00.000Z",
"numberOfDays": 10,
"leaveType": "annual",
"isShiftWorker": false
}{
"status": "success",
"message": "Leave details calculated successfully",
"data": {
"startDate": "2025-05-01T00:00:00.000Z",
"endDate": "2025-05-10T00:00:00.000Z",
"numberOfDays": 10,
"workingDays": 7,
"resumptionDate": "2025-05-11T00:00:00.000Z",
"includesWeekendsAndHolidays": false,
"isValid": true
}
}Endpoints for managing leave requests
GET /leave-records
Retrieves all leave records with filtering and pagination.
| Parameter | Type | Description | Required |
|---|---|---|---|
| page | Number | Page number for pagination | No |
| limit | Number | Number of records per page | No |
| status | String | Filter by status (pending, approved, rejected, cancelled) | No |
| type | String | Filter by leave type (annual, sick, maternity, etc.) | No |
| staffId | String | Filter by staff ID | No |
| startDate | Date | Only leave that ends on or after this date (YYYY-MM-DD) | No |
| endDate | Date | Only leave that starts on or before this date (YYYY-MM-DD) | No |
| search | String | Search by staff name, email or staff ID | No |
| filterDepartmentId | String | Only staff in this department or its sub-departments | No |
GET /leave-records?id={leaveId}
Retrieves a specific leave record by its ID.
POST /leave-records
Submits a new leave request.
{
"staffId": "6075d1505f943a2e34b1fff1", // Optional, defaults to authenticated user
"startDate": "2025-05-01T00:00:00.000Z",
"endDate": "2025-05-10T00:00:00.000Z",
"numberOfDays": 10,
"type": "annual",
"reason": "Vacation",
"isShiftWorker": false
}{
"status": "success",
"message": "Leave request submitted successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff5",
"staff": "6075d1505f943a2e34b1fff1",
"requestedBy": "6075d1505f943a2e34b1fff1",
"startDate": "2025-05-01T00:00:00.000Z",
"endDate": "2025-05-10T00:00:00.000Z",
"resumptionDate": "2025-05-11T00:00:00.000Z",
"type": "annual",
"status": "pending",
"reason": "Vacation",
"numberOfDays": 10,
"workingDaysCount": 7,
"isShiftWorker": false,
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}PUT /leave-records?id={leaveId}
Updates a leave record status (approve/reject).
{
"status": "approved",
"comment": "Approved by manager" // Optional comment
}{
"status": "success",
"message": "Leave request approved successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff5",
"staff": "6075d1505f943a2e34b1fff1",
"requestedBy": "6075d1505f943a2e34b1fff1",
"startDate": "2025-05-01T00:00:00.000Z",
"endDate": "2025-05-10T00:00:00.000Z",
"resumptionDate": "2025-05-11T00:00:00.000Z",
"type": "annual",
"status": "approved",
"reason": "Vacation",
"numberOfDays": 10,
"workingDaysCount": 7,
"isShiftWorker": false,
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}PUT /leave-records?id={leaveId}&action=cancel
Cancels a leave request.
{
"comment": "Personal reasons" // Optional comment for cancellation
}{
"status": "success",
"message": "Leave request cancelled successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff5",
"status": "cancelled",
// ... other leave record properties
}
}DELETE /leave-records?id={leaveId}
Deletes a leave record (soft delete, admin only).
{
"status": "success",
"message": "Leave record deleted successfully",
"data": null
}Endpoints for managing leave balances
GET /leave-balances
Retrieves leave balances for all staff (admin only).
| Parameter | Type | Description | Required |
|---|---|---|---|
| page | Number | Page number for pagination | No |
| limit | Number | Number of records per page | No |
GET /leave-balances?staffId={staffId}
Retrieves leave balance for a specific staff member.
{
"status": "success",
"message": "Leave balance retrieved successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff6",
"staff": "6075d1505f943a2e34b1fff1",
"annual": 24,
"sick": 60,
"maternity": 90,
"paternity": 3,
"bereavement": 10,
"casual": 0,
"accrued": 15,
"total": 204,
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}PUT /leave-balances?staffId={staffId}
Updates leave balance for a staff member (admin/HR only).
{
"annual": 24,
"sick": 60,
"maternity": 90,
"paternity": 5,
"bereavement": 10,
"casual": 0,
"accrued": 15
}{
"status": "success",
"message": "Leave balance updated successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff6",
"staff": "6075d1505f943a2e34b1fff1",
"annual": 24,
"sick": 60,
"maternity": 90,
"paternity": 3,
"bereavement": 10,
"casual": 0,
"accrued": 15,
"total": 204,
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}Endpoints for managing company holidays
GET /holidays
Retrieves all holidays.
| Parameter | Type | Description | Required |
|---|---|---|---|
| year | Number | Filter by year | No |
{
"status": "success",
"message": "Holidays retrieved successfully",
"data": [
{
"_id": "6075d1505f943a2e34b1fff7",
"name": "New Year's Day",
"type": "fixed",
"fixedDate": "2025-01-01T00:00:00.000Z",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
},
{
"_id": "6075d1505f943a2e34b1fff8",
"name": "Christmas Day",
"type": "fixed",
"fixedDate": "2025-12-25T00:00:00.000Z",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
]
}POST /holidays
Creates a new holiday (admin/HR only).
{
"name": "Independence Day",
"type": "fixed",
"fixedDate": "2025-07-04T00:00:00.000Z"
}{
"status": "success",
"message": "Holiday created successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff9",
"name": "Independence Day",
"type": "fixed",
"fixedDate": "2025-07-04T00:00:00.000Z",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}PUT /holidays?id={holidayId}
Updates a holiday (admin/HR only).
{
"name": "Updated Holiday Name",
"type": "fixed",
"fixedDate": "2025-07-05T00:00:00.000Z"
}{
"status": "success",
"message": "Holiday updated successfully",
"data": {
"_id": "6075d1505f943a2e34b1fff9",
"name": "Updated Holiday Name",
"type": "fixed",
"fixedDate": "2025-07-05T00:00:00.000Z",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}DELETE /holidays?id={holidayId}
Deletes a holiday (admin/HR only).
{
"status": "success",
"message": "Holiday deleted successfully",
"data": null
}Endpoints for managing users
GET /users
Retrieves all users with filtering and pagination.
| Parameter | Type | Description | Required |
|---|---|---|---|
| page | Number | Page number for pagination | No |
| limit | Number | Number of users per page | No |
| role | String | Filter by role (admin, staff, manager, general-manager) | No |
| department | String | Filter by department ID | No |
| search | String | Search by name, email, or staff ID | No |
GET /users?id={userId}
Retrieves a specific user by ID.
POST /users
Creates a new user (admin only).
{
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"staffId": "EMP002",
"phone": "+233123456789",
"role": "staff",
"position": "UI Designer",
"permissions": ["request_on_behalf"],
"department": "6075d1505f943a2e34b1fff2"
}{
"status": "success",
"message": "User created successfully",
"data": {
"_id": "6075d1505f943a2e34b1fffa",
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"staffId": "EMP002",
"phone": "+233123456789",
"role": "staff",
"position": "UI Designer",
"permissions": ["request_on_behalf"],
"department": "6075d1505f943a2e34b1fff2",
"employeeStatus": "active",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}PUT /users?id={userId}
Updates a user (admin only).
{
"firstName": "Jane",
"lastName": "Smith",
"email": "jane.smith@example.com",
"phone": "+233123456789",
"role": "manager",
"position": "Lead UI Designer",
"permissions": ["request_on_behalf", "approve_leaves"],
"department": "6075d1505f943a2e34b1fff2",
"employeeStatus": "active"
}{
"status": "success",
"message": "User updated successfully",
"data": {
"_id": "6075d1505f943a2e34b1fffa",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane.smith@example.com",
"staffId": "EMP002",
"phone": "+233123456789",
"role": "manager",
"position": "Lead UI Designer",
"permissions": ["request_on_behalf", "approve_leaves"],
"department": "6075d1505f943a2e34b1fff2",
"employeeStatus": "active",
"createdAt": "2023-01-01T00:00:00.000Z",
"updatedAt": "2023-01-01T00:00:00.000Z"
}
}DELETE /users?id={userId}
Soft deletes a user (admin only).
{
"status": "success",
"message": "User deleted successfully",
"data": null
}Endpoints for generating and retrieving leave reports and analytics
GET /reports
Generates leave reports based on scope (individual, department, or organization) and date range.
| Parameter | Type | Description | Required |
|---|---|---|---|
| scope | String | Scope of the report: 'individual', 'department', or 'organization' | Yes |
| staffId | String | ID of the staff member (required when scope is 'individual') | No |
| departmentId | String | ID of the department (required when scope is 'department') | No |
| startDate | Date (ISO String) | Start date for report data (default: start of current month) | No |
| endDate | Date (ISO String) | End date for report data (default: end of current month) | No |
{
"status": "success",
"message": "Reports generated successfully",
"data": {
// For individual scope
"metadata": {
"scope": "individual",
"startDate": "2023-06-01T00:00:00.000Z",
"endDate": "2023-06-30T23:59:59.999Z",
"generatedAt": "2023-06-15T12:34:56.789Z",
"contextName": "John Doe",
"staffDetails": {
"staffId": "6075d1505f943a2e34b1fff1",
"name": "John Doe",
"position": "Software Engineer",
"department": "Engineering",
"email": "john.doe@example.com"
}
},
"reports": {
"leaveBalances": {
"title": "Leave Balances",
"columns": ["Leave Type", "Allocated", "Used", "Remaining", "Percentage Used"],
"data": [
{
"leaveType": "Annual",
"allocated": 30,
"used": 12,
"remaining": 18,
"percentageUsed": 40
},
// ... other leave types
]
},
"leaveHistory": {
"title": "Leave History Timeline",
"columns": ["Date", "Leave Type", "Duration", "Status", "Comments", "Performed By"],
"grouped": true,
"data": [
{
"isGroupHeader": true,
"groupId": "leave123",
"leaveType": "Annual",
"duration": 5,
"period": "2023-06-01 to 2023-06-05",
"status": "APPROVED"
},
{
"groupId": "leave123",
"date": "2023-05-15",
"status": "Leave Requested",
"comments": "Need some time off",
"performedBy": "John Doe"
},
// ... other history entries
]
},
"upcomingLeaves": {
"title": "Upcoming Leaves",
"columns": ["Start Date", "End Date", "Return Date", "Leave Type", "Duration", "Status"],
"data": [
{
"startDate": "2023-07-10",
"endDate": "2023-07-20",
"returnDate": "2023-07-21",
"leaveType": "Annual",
"duration": 10,
"status": "APPROVED"
},
// ... other upcoming leaves
]
},
"leaveRequests": {
"title": "Leave Requests Summary",
"columns": ["Request Date", "Start Date", "End Date", "Return Date", "Leave Type", "Duration", "Status", "Status Date", "Processed By", "Processing Time", "Reason/Comment"],
"data": [
{
"requestDate": "2023-05-15",
"startDate": "2023-06-01",
"endDate": "2023-06-05",
"returnDate": "2023-06-06",
"leaveType": "Annual",
"duration": 5,
"status": "APPROVED",
"statusChangeDate": "2023-05-16",
"processedBy": "Jane Manager",
"processingTime": "24 hours",
"reason": "Time off for personal matters"
},
// ... other leave requests
]
}
}
// For department scope
// Similar structure as individual, but with departmentName instead of staffDetails
// and aggregated data for all staff in the department and its children
}
}Users can only access reports they are permitted to view. HR staff and general managers can view all reports. Department managers can view reports for their department and child departments. Regular staff can only view their own reports.