All three endpoints need Payroll: View. Amounts are in naira.
A payroll run is one company's pay for one pay date. Paying it is never available to a key: a person disburses it in
KalHR, and the payroll.paid event tells you when every
transfer has settled.
Payroll statuses
status | Number | Meaning |
|---|---|---|
Draft, Pending | 2, 5 | Being prepared |
PendingApproval | 4 | Waiting for approval |
Active | 0 | Approved and ready to pay |
Processing | 8 | Transfers are going out |
Paid | 3 | Every transfer succeeded |
Processed | 9 | Finished, but some transfers failed |
Rejected | 7 | Rejected by an approver |
InActive | 1 | Switched off |
Abandoned runs are never returned.
List payroll runs
GET/v1/payroll/schedule/listKey needs Payroll: ViewReturns one company's payroll runs, a page at a time, newest first.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
CompanyId | uuid | Required. The company whose runs to list. Ids come from Companies. | |
PageNumber | integer | 1 | The page to return |
PageSize | integer | 25 | Runs per page |
SearchTerm | string | Part of the payroll code | |
StartDate, EndDate | date | Only runs created on or between these dates | |
OrderBy | integer | 1 | 0 oldest first, 1 newest first |
curl "https://api.kalhr.com/v1/payroll/schedule/list?CompanyId=1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b" \
-H "Authorization: Bearer $KALHR_API_KEY"Response
{
"isSuccessful": true,
"code": "00",
"message": "Success",
"data": {
"data": [
{
"id": "f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7",
"payrollCode": "ACM-3F9A1C",
"totalNumberOfEmployee": 134,
"totalNetSalary": 48230115.75,
"totalGrossSalary": 63500000,
"paycycleId": 0,
"paycycle": "Monthly",
"status": "Paid",
"payDate": "2026-10-25T00:00:00",
"startDate": "2026-10-01T00:00:00",
"dateCreated": "2026-10-20T11:42:09.117"
}
],
"pageNumber": 1,
"pageSize": 25,
"totalRecords": 10,
"totalPages": 1
}
}
| Field | Type | Description |
|---|---|---|
id, payrollCode | uuid, string | The run |
totalNumberOfEmployee | integer | Employees paid in the run |
totalNetSalary, totalGrossSalary | number | Totals for the run |
paycycleId, paycycle | integer, string | 0 Monthly, 1 SemiMonthly, 2 Weekly |
status | string | See statuses |
payDate, startDate | date | Pay day, and the first day of its month |
dateCreated | datetime | When the run was created (UTC) |
Get a payroll run
GET/v1/payroll/schedule/{id}Key needs Payroll: Viewcurl "https://api.kalhr.com/v1/payroll/schedule/f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7" \
-H "Authorization: Bearer $KALHR_API_KEY"Response
{
"isSuccessful": true,
"code": "00",
"message": "Success",
"data": {
"id": "f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7",
"numberOfEmployees": 134,
"totalAllowance": 21800000,
"totalDeduction": 9416884.25,
"totalNetSalary": 48230115.75,
"totalGrossSalary": 63500000,
"totalPaye": 5853000,
"created": "2026-10-20T11:42:09.117",
"payDate": "2026-10-25T00:00:00",
"startDate": "2026-10-01T00:00:00",
"status": { "id": 3, "name": "Paid" }
}
}
status is an object here: id is its number and name one of the statuses.
Get each employee's pay in a run
GET/v1/payroll/schedule/{id}/salariesKey needs Payroll: ViewReturns one line per employee in the run, as a plain list (not paged).
curl "https://api.kalhr.com/v1/payroll/schedule/f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7/salaries" \
-H "Authorization: Bearer $KALHR_API_KEY"Response
{
"isSuccessful": true,
"code": "00",
"message": "Success",
"data": [
{
"id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"employeeCode": "ACM-0042",
"employeeName": "Ada Okafor",
"grossSalary": 650000,
"netSalary": 462340.5,
"salary": 462340.5,
"monthlyAllowance": 210000,
"monthlyDeduction": 187659.5,
"loanDeduction": 50000,
"payePerMonth": 84120,
"grossAnnual": 7800000,
"netAnnual": 5548086,
"totalAnnualAllowance": 2520000,
"totalAnnualDeduction": 2251914,
"payeAnnual": 1009440,
"loans": [
{
"loanId": "1c2d3e4f-…",
"amount": 600000,
"monthlyRepayment": 50000,
"totalRepayable": 600000,
"totalRepaid": 250000,
"outstandingBalance": 350000,
"status": "Active",
"nextDueDate": "2026-11-25T00:00:00Z",
"installmentsRemaining": 7
}
],
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"dueDate": "2026-10-25T00:00:00Z",
"isActive": true
}
]
}
| Field | Type | Description |
|---|---|---|
id | uuid | This pay line (not the employee) |
employeeId, employeeCode, employeeName | uuid, string, string | The employee, their employee number and name |
grossSalary, netSalary | number | Pay for this run; salary repeats netSalary |
monthlyAllowance, monthlyDeduction, payePerMonth | number | Allowances, deductions (including any loan repayment) and PAYE |
loanDeduction | number | Loan repayment taken from this run |
grossAnnual, netAnnual, totalAnnualAllowance, totalAnnualDeduction, payeAnnual | number | The monthly figures × 12 |
loans | array | The employee's approved, disbursed or active loans |
dueDate | date | The run's pay day |
Related
- Event catalogue:
payroll.created,payroll.approved,payroll.paid,payroll.transfer_failed