An endpoint receives every event, or only those ticked when it was set up. Events are grouped as they are in KalHR's settings: Basic, Standard and Advanced. Filter the list below by an event's name, its area or a field, and use the link icon on a card to share that event.
The envelope
Every event has the same outer shape. Only data changes from one event type to another.
{
"id": "0b8e7f1a-2c3d-4e5f-8a9b-0c1d2e3f4a5b",
"type": "leave.approved",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T14:30:00.1234567Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": { }
}
| Field | Meaning |
|---|---|
id | The event's id. The same on every retry and redelivery, so use it to skip repeats. |
type | What happened, such as leave.approved |
apiVersion | The version of this format, currently 2026-10-15 |
occurredAt | When it happened, in UTC with a Z |
organizationId | Your organisation |
data | The event's details, described on each event below |
Reading the data
- Ids and statuses only.
datanever carries pay, bank details, reasons or case notes. Fetch what you need with the API; fields that have an endpoint behind them link to it. - Nulls are sent. Unlike API answers, an event includes a field it has no value for, as
null. A field marked nullable below can be null. - Statuses are names, as KalHR shows them:
Approved,PendingApproval. - Calendar dates (leave days, pay days, exit dates) come as midnight,
2026-11-02T00:00:00. Use the date part. - Samples are made up, but each one has exactly the shape KalHR sends.
Events
BasicPeople, onboarding and leave
9 eventsSent when an employee record is created: by HR, by bulk upload, or by approved self-onboarding.
Field in data | Description |
|---|---|
employeeIduuid | The employee recordGET v1/employee/{id} |
employeeNumberstringnullable | Your own employee number |
fullNamestringnullable | First and last name |
emailstringnullable | Work email |
companyIduuidnullable | The company the record belongs to |
statusstringnullable | The employee status Every value |
{
"id": "230e84f6-86fc-4341-a7e3-67d7635f17ac",
"type": "employee.created",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T08:02:11.5034127Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"employeeId": "6f5e4d3c-2b1a-4c9d-8e7f-0a1b2c3d4e5f",
"employeeNumber": "ACM-0057",
"fullName": "Chinedu Eze",
"email": "chinedu.eze@acme.ng",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"status": "Active"
}
}Sent when an employee's record is changed, by HR or by an approved profile update.
Field in data | Description |
|---|---|
employeeIduuid | The employee recordGET v1/employee/{id} |
employeeNumberstringnullable | Your own employee number |
fullNamestringnullable | First and last name |
emailstringnullable | Work email |
companyIduuidnullable | The company the record belongs to |
statusstringnullable | The employee status Every value |
{
"id": "91d97d59-ae76-4b96-a572-4a428955f7c2",
"type": "employee.updated",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T09:15:42.7781093Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"employeeNumber": "ACM-0042",
"fullName": "Ada Okafor",
"email": "ada.okafor@acme.ng",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"status": "Active"
}
}Sent when an employee's exit is final.
Field in data | Description |
|---|---|
employeeIduuid | The employee who is leaving |
terminationIduuidnullable | The exit record in KalHR |
exitDatedatenullable | Their last day |
{
"id": "90a95f93-109a-4b4d-8b4b-478aff50d82f",
"type": "employee.terminated",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T10:40:03.2219846Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"terminationId": "fc9d3cd0-35d1-49b9-a4fa-46c12d96f07b",
"exitDate": "2026-10-31T00:00:00"
}
}Sent when a new hire submits the onboarding form.
When the organisation has no onboarding approval, the form creates the employee at once: this event and employee.created arrive together, and employeeId is already set.
Field in data | Description |
|---|---|
onboardingIduuid | The onboarding submission. When there is no onboarding approval, the same id as employeeId. |
companyIduuidnullable | The company they are joining |
emailstringnullable | The new hire's email |
employeeIduuidnullable | The employee record, once created. null while the onboarding waits for approval. |
{
"id": "c7cd5bf2-5e4f-4dc8-ac15-6fb19a3f6f50",
"type": "onboarding.submitted",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T07:55:20.1180452Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"onboardingId": "a5af6725-2b00-434b-b225-9a0e3cf30d4c",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"email": "chinedu.eze@acme.ng",
"employeeId": null
}
}Sent when a submitted onboarding is approved and the employee is created.
Field in data | Description |
|---|---|
onboardingIduuid | The onboarding submission. When there is no onboarding approval, the same id as employeeId. |
companyIduuidnullable | The company they are joining |
emailstringnullable | The new hire's email |
employeeIduuidnullable | The employee record, once created. null while the onboarding waits for approval. |
{
"id": "3b5912f1-a368-44cc-a530-66eb0e8473c2",
"type": "onboarding.approved",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T08:02:11.5034127Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"onboardingId": "a5af6725-2b00-434b-b225-9a0e3cf30d4c",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"email": "chinedu.eze@acme.ng",
"employeeId": "6f5e4d3c-2b1a-4c9d-8e7f-0a1b2c3d4e5f"
}
}Sent when an employee asks for leave.
status is Submitted.
Field in data | Description |
|---|---|
leaveRequestIduuid | The leave requestGET v1/leaverequest/details/{id} |
employeeIduuidnullable | Who asked |
leaveTypeIduuidnullable | The leave type |
leaveTypestringnullable | The leave type's name |
startDatedatenullable | First day off |
endDatedatenullable | Last day off |
statusstringnullable | The request's status after this eventSubmittedApprovedRejectedAbandonedDeleted |
{
"id": "33dbe3ed-214a-4192-9a19-a7d495d01aa9",
"type": "leave.requested",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T11:05:37.9042210Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"leaveRequestId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"leaveTypeId": "c0ffee00-1234-4abc-9def-0123456789ab",
"leaveType": "Annual leave",
"startDate": "2026-11-02T00:00:00",
"endDate": "2026-11-06T00:00:00",
"status": "Submitted"
}
}Sent when a leave request is approved.
Field in data | Description |
|---|---|
leaveRequestIduuid | The leave requestGET v1/leaverequest/details/{id} |
employeeIduuidnullable | Who asked |
leaveTypeIduuidnullable | The leave type |
leaveTypestringnullable | The leave type's name |
startDatedatenullable | First day off |
endDatedatenullable | Last day off |
statusstringnullable | The request's status after this eventSubmittedApprovedRejectedAbandonedDeleted |
{
"id": "cd0bb99b-3cbe-4a0e-916e-aa511cbe6876",
"type": "leave.approved",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T14:30:00.1234567Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"leaveRequestId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"leaveTypeId": "c0ffee00-1234-4abc-9def-0123456789ab",
"leaveType": "Annual leave",
"startDate": "2026-11-02T00:00:00",
"endDate": "2026-11-06T00:00:00",
"status": "Approved"
}
}Sent when a leave request is rejected.
Field in data | Description |
|---|---|
leaveRequestIduuid | The leave requestGET v1/leaverequest/details/{id} |
employeeIduuidnullable | Who asked |
leaveTypeIduuidnullable | The leave type |
leaveTypestringnullable | The leave type's name |
startDatedatenullable | First day off |
endDatedatenullable | Last day off |
statusstringnullable | The request's status after this eventSubmittedApprovedRejectedAbandonedDeleted |
{
"id": "76cb5e55-855a-40ea-bde3-7da29697866f",
"type": "leave.rejected",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T14:30:00.1234567Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"leaveRequestId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"leaveTypeId": "c0ffee00-1234-4abc-9def-0123456789ab",
"leaveType": "Annual leave",
"startDate": "2026-11-02T00:00:00",
"endDate": "2026-11-06T00:00:00",
"status": "Rejected"
}
}Sent when a leave request is withdrawn or deleted.
status is Abandoned when it was withdrawn, Deleted when it was deleted.
Field in data | Description |
|---|---|
leaveRequestIduuid | The leave requestGET v1/leaverequest/details/{id} |
employeeIduuidnullable | Who asked |
leaveTypeIduuidnullable | The leave type |
leaveTypestringnullable | The leave type's name |
startDatedatenullable | First day off |
endDatedatenullable | Last day off |
statusstringnullable | The request's status after this eventSubmittedApprovedRejectedAbandonedDeleted |
{
"id": "4d6c90bf-86d2-48d0-8a78-3ea156760542",
"type": "leave.cancelled",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-20T08:12:49.6610375Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"leaveRequestId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"leaveTypeId": "c0ffee00-1234-4abc-9def-0123456789ab",
"leaveType": "Annual leave",
"startDate": "2026-11-02T00:00:00",
"endDate": "2026-11-06T00:00:00",
"status": "Abandoned"
}
}StandardPayroll, loans and attendance
9 eventsSent when a payroll run is created.
status is PendingApproval when an approval workflow applies. Without one it is Active, and payroll.approved follows at once.
Field in data | Description |
|---|---|
payrollIduuid | The payroll runGET v1/payroll/schedule/{id} |
payrollCodestringnullable | The run's code, such as ACM-3F9A1C |
companyIduuidnullable | The company being paid |
payrollDatedatenullable | The pay day |
statusstringnullable | The run's status after this event Every value |
{
"id": "253b1ad4-037b-4a04-b2ca-b8b3d6ea21b8",
"type": "payroll.created",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-25T09:00:14.3301268Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"payrollId": "f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7",
"payrollCode": "ACM-3F9A1C",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"payrollDate": "2026-10-31T00:00:00",
"status": "PendingApproval"
}
}Sent when a payroll run is approved and can be paid.
Field in data | Description |
|---|---|
payrollIduuid | The payroll runGET v1/payroll/schedule/{id} |
payrollCodestringnullable | The run's code, such as ACM-3F9A1C |
companyIduuidnullable | The company being paid |
payrollDatedatenullable | The pay day |
statusstringnullable | The run's status after this event Every value |
{
"id": "16ad9e01-c815-4abe-b4e4-844f25237586",
"type": "payroll.approved",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-26T10:22:05.8873140Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"payrollId": "f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7",
"payrollCode": "ACM-3F9A1C",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"payrollDate": "2026-10-31T00:00:00",
"status": "Active"
}
}Sent when the last transfer of a payroll run settles.
status is Paid when every transfer succeeded, Processed when some failed. Each failure also sends payroll.transfer_failed.
Field in data | Description |
|---|---|
payrollIduuid | The payroll runGET v1/payroll/schedule/{id} |
payrollCodestringnullable | The run's code, such as ACM-3F9A1C |
companyIduuidnullable | The company being paid |
payrollDatedatenullable | The pay day |
statusstringnullable | The run's status after this event Every value |
{
"id": "0739470a-ddba-46f2-98f3-52fe62c9481d",
"type": "payroll.paid",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-31T12:47:31.0412596Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"payrollId": "f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7",
"payrollCode": "ACM-3F9A1C",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"payrollDate": "2026-10-31T00:00:00",
"status": "Paid"
}
}Sent when one employee's salary transfer fails or is reversed.
Field in data | Description |
|---|---|
payrollIduuid | The payroll run |
payrollCodestringnullable | The run's code |
employeeIduuidnullable | Whose salary didn't arrive |
referencestring | The transfer's reference with the payment provider |
outcomestring | What happened to the transferfailedreversed |
{
"id": "7eedad2e-7ec3-4e01-936e-f9d9839056d7",
"type": "payroll.transfer_failed",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-31T12:46:58.7719832Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"payrollId": "f00dbabe-2026-4e10-8a1b-c2d3e4f5a6b7",
"payrollCode": "ACM-3F9A1C",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"reference": "pay_7f1f5ca0bacf47f0ba7aa1cf97e4954e",
"outcome": "failed"
}
}Sent when an employee applies for a loan.
Field in data | Description |
|---|---|
loanIduuid | The loan |
employeeIduuidnullable | Who borrowed |
statusstringnullable | The loan's status after this eventPendingApprovedActive |
{
"id": "e427f1e5-3349-4602-a971-8b23933e3a7a",
"type": "loan.requested",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T13:10:27.4405918Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"loanId": "7f552bfb-de1d-4ef4-8ccc-5f4b9745f3c1",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"status": "Pending"
}
}Sent when a loan is approved.
Field in data | Description |
|---|---|
loanIduuid | The loan |
employeeIduuidnullable | Who borrowed |
statusstringnullable | The loan's status after this eventPendingApprovedActive |
{
"id": "63fdcf6a-5d20-4e6f-ab31-32318e56369a",
"type": "loan.approved",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-20T09:31:44.2087365Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"loanId": "7f552bfb-de1d-4ef4-8ccc-5f4b9745f3c1",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"status": "Approved"
}
}Sent when a loan is paid out.
status is Active: repayments have started.
Field in data | Description |
|---|---|
loanIduuid | The loan |
employeeIduuidnullable | Who borrowed |
statusstringnullable | The loan's status after this eventPendingApprovedActive |
{
"id": "444c0702-72a5-4946-aeed-fa865270401a",
"type": "loan.disbursed",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-21T15:03:09.6652701Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"loanId": "7f552bfb-de1d-4ef4-8ccc-5f4b9745f3c1",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"status": "Active"
}
}Sent when an attendance exception (an excused day, a day off, a remote day, a closure) takes effect.
Field in data | Description |
|---|---|
exceptionIduuid | The attendance exceptionGET v1/attendance/exceptions/{id} |
employeeIduuidnullable | Who is excused |
typestringnullable | What kind of exceptionExcusedAbsenceDayOffGrantedRemoteDayCompanyClosure |
startDatedatenullable | First day covered |
endDatedatenullable | Last day covered |
{
"id": "873906c2-8d11-4d4b-9149-66b170320107",
"type": "attendance.exception.approved",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T16:20:51.3398724Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"exceptionId": "dd849990-851f-4abe-a742-6816382df667",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"type": "RemoteDay",
"startDate": "2026-10-22T00:00:00",
"endDate": "2026-10-22T00:00:00"
}
}Sent when the absence report for a day finishes, so that day's attendance is complete.
Field in data | Description |
|---|---|
reportIduuid | The day's reportGET v1/attendance/report/{id} |
datedatenullable | The day the report covers |
statusstringnullable | Always CompletedCompleted |
{
"id": "a37c2ada-79f1-4e5e-ad7a-4ee312af259b",
"type": "attendance.absence_report.completed",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T18:00:36.9124403Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"reportId": "433f98d0-ea88-4554-9af1-6ae2e5704fee",
"date": "2026-10-19T00:00:00",
"status": "Completed"
}
}AdvancedRecruitment, offers, approvals, cases and policies
14 eventsSent when someone applies to a job.
Field in data | Description |
|---|---|
applicationIduuid | The job application |
jobPostIduuidnullable | The job |
stageIduuidnullable | The pipeline stage |
stageNamestringnullable | The stage's name, such as Interview |
{
"id": "f4f38395-eef7-45e2-aac8-349e67cf65c3",
"type": "candidate.applied",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T10:01:12.2281945Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"applicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"jobPostId": "76e132d4-71c0-466c-b604-873b567e371e",
"stageId": "d9c6d1c0-6cc3-4435-ab7d-50662630e836",
"stageName": "Applied"
}
}Sent when a candidate moves to another pipeline stage.
The stage fields are the new stage.
Field in data | Description |
|---|---|
applicationIduuid | The job application |
jobPostIduuidnullable | The job |
stageIduuidnullable | The pipeline stage |
stageNamestringnullable | The stage's name, such as Interview |
{
"id": "a0c77763-b525-48a2-9888-fb4cc2f5bf9c",
"type": "candidate.stage_changed",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-20T11:34:08.5527306Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"applicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"jobPostId": "76e132d4-71c0-466c-b604-873b567e371e",
"stageId": "3baa18d0-047f-48d9-a48a-ba5406ce77bb",
"stageName": "First interview"
}
}Sent when a candidate is rejected.
The stage fields are the stage they were in.
Field in data | Description |
|---|---|
applicationIduuid | The job application |
jobPostIduuidnullable | The job |
stageIduuidnullable | The pipeline stage |
stageNamestringnullable | The stage's name, such as Interview |
{
"id": "ac217278-4cce-4c5c-8af7-9b2eb6bd9a6d",
"type": "candidate.rejected",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-23T09:48:17.0036619Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"applicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"jobPostId": "76e132d4-71c0-466c-b604-873b567e371e",
"stageId": "3baa18d0-047f-48d9-a48a-ba5406ce77bb",
"stageName": "First interview"
}
}Sent when an interviewer submits a scorecard.
Field in data | Description |
|---|---|
scorecardIduuid | The submitted scorecard |
applicationIduuidnullable | The candidate's application |
stageIduuidnullable | The stage it scores |
{
"id": "d081cb1c-f005-4fc2-8af8-e5a42ffe3887",
"type": "interview.scorecard_submitted",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-22T15:12:40.7149823Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"scorecardId": "a4e1cbe9-f89e-491a-a9a1-b44283d296c0",
"applicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"stageId": "3baa18d0-047f-48d9-a48a-ba5406ce77bb"
}
}Sent when an offer letter is sent to a candidate.
Field in data | Description |
|---|---|
offerIduuid | The offer letter |
jobApplicationIduuidnullable | The application it was made on |
companyIduuidnullable | The hiring company |
statusstringnullable | The offer's status after this eventSentAcceptedDeclinedExpired |
{
"id": "28f8621a-7d80-4fb8-a0fc-2c110fc81e42",
"type": "offer.sent",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-24T10:05:55.3816247Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"offerId": "ae463440-4a23-46db-9284-d6543b2b62e3",
"jobApplicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"status": "Sent"
}
}Sent when a candidate accepts an offer.
Field in data | Description |
|---|---|
offerIduuid | The offer letter |
jobApplicationIduuidnullable | The application it was made on |
companyIduuidnullable | The hiring company |
statusstringnullable | The offer's status after this eventSentAcceptedDeclinedExpired |
{
"id": "a854af50-3e63-48fb-a5e8-c9c9c12ee63c",
"type": "offer.accepted",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-25T08:41:02.9927510Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"offerId": "ae463440-4a23-46db-9284-d6543b2b62e3",
"jobApplicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"status": "Accepted"
}
}Sent when a candidate declines an offer.
Field in data | Description |
|---|---|
offerIduuid | The offer letter |
jobApplicationIduuidnullable | The application it was made on |
companyIduuidnullable | The hiring company |
statusstringnullable | The offer's status after this eventSentAcceptedDeclinedExpired |
{
"id": "fd526615-d06b-44da-a387-21f9dd081cad",
"type": "offer.declined",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-25T08:41:02.9927510Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"offerId": "ae463440-4a23-46db-9284-d6543b2b62e3",
"jobApplicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"status": "Declined"
}
}Sent when an offer passes its respond-by date unanswered.
Field in data | Description |
|---|---|
offerIduuid | The offer letter |
jobApplicationIduuidnullable | The application it was made on |
companyIduuidnullable | The hiring company |
statusstringnullable | The offer's status after this eventSentAcceptedDeclinedExpired |
{
"id": "d0226609-ab59-40f0-a7cc-7d201a767c76",
"type": "offer.expired",
"apiVersion": "2026-10-15",
"occurredAt": "2026-11-01T00:00:21.4470138Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"offerId": "ae463440-4a23-46db-9284-d6543b2b62e3",
"jobApplicationId": "1fe9c638-5cfb-4570-8dcd-708a7412b0a9",
"companyId": "1f2e3d4c-5b6a-4987-8a6b-5c4d3e2f1a0b",
"status": "Expired"
}
}Sent when something is submitted for approval.
The sample is a leave request, so subjectId is the leave request's id.
Field in data | Description |
|---|---|
approvalInstanceIduuid | This run of the approval workflow |
scenariostringnullable | What is being approvedLeaveRequestPayrollScheduleCreationProbationConfirmationEmployeeTerminationLoanEmployeeSelfOnboardingDisciplinaryActionDisciplinarySuspensionDisciplinaryTerminationRecommendationAttendanceExceptionOfferLetter |
subjectIduuid | The record being approved: the leave request, payroll run, loan... For OfferLetter, that submission of the offer. |
statusstringnullable | Pending when requested; Approved or Rejected when completedPendingApprovedRejected |
{
"id": "e5fbfd73-2706-4907-8d5e-ce7629a2bd3a",
"type": "approval.requested",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T11:05:37.9042210Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"approvalInstanceId": "0b12d36e-a81a-47f9-bd8a-b5d9de769b2d",
"scenario": "LeaveRequest",
"subjectId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"status": "Pending"
}
}Sent when an approval finishes, approved or rejected.
Field in data | Description |
|---|---|
approvalInstanceIduuid | This run of the approval workflow |
scenariostringnullable | What is being approvedLeaveRequestPayrollScheduleCreationProbationConfirmationEmployeeTerminationLoanEmployeeSelfOnboardingDisciplinaryActionDisciplinarySuspensionDisciplinaryTerminationRecommendationAttendanceExceptionOfferLetter |
subjectIduuid | The record being approved: the leave request, payroll run, loan... For OfferLetter, that submission of the offer. |
statusstringnullable | Pending when requested; Approved or Rejected when completedPendingApprovedRejected |
{
"id": "3c2253a9-f3f2-450d-8449-be86e8485640",
"type": "approval.completed",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T14:30:00.1234567Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"approvalInstanceId": "0b12d36e-a81a-47f9-bd8a-b5d9de769b2d",
"scenario": "LeaveRequest",
"subjectId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"status": "Approved"
}
}Sent when a disciplinary case is opened.
Only ids, the case number and the status: what a case is about stays in KalHR.
Field in data | Description |
|---|---|
caseIduuid | The disciplinary case |
employeeIduuidnullable | The employee the case is about |
caseNumberstringnullable | Such as DISC-2026-0007 |
statusstringnullable | The case's status after this eventOpenClosedCancelled |
{
"id": "ef61e946-f6a7-47bf-8729-4404d3d8bc5c",
"type": "disciplinary.case.opened",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-20T13:25:18.6603952Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"caseId": "53796174-393f-438f-9ada-b24b0d56dc52",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"caseNumber": "DISC-2026-0007",
"status": "Open"
}
}Sent when a disciplinary case is closed or cancelled.
status is Closed, or Cancelled when the case was cancelled.
Field in data | Description |
|---|---|
caseIduuid | The disciplinary case |
employeeIduuidnullable | The employee the case is about |
caseNumberstringnullable | Such as DISC-2026-0007 |
statusstringnullable | The case's status after this eventOpenClosedCancelled |
{
"id": "9c93645f-415e-4d15-b386-66d940d6eb8e",
"type": "disciplinary.case.closed",
"apiVersion": "2026-10-15",
"occurredAt": "2026-11-10T16:02:44.1185037Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"caseId": "53796174-393f-438f-9ada-b24b0d56dc52",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"caseNumber": "DISC-2026-0007",
"status": "Closed"
}
}Sent when a staff policy is published.
Field in data | Description |
|---|---|
policyIduuid | The staff policy |
titlestringnullable | Its title |
{
"id": "7784a1ae-8e86-4370-b5dd-c1fc81407380",
"type": "policy.published",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T09:00:03.8841526Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"policyId": "92f13f88-9342-4b14-b7e8-ab8bc4d7e685",
"title": "Remote Work Policy"
}
}Sent when an employee acknowledges a staff policy.
Field in data | Description |
|---|---|
policyIduuid | The staff policy |
employeeIduuid | Who acknowledged it |
acknowledgedAtdatetime | When, in UTC |
{
"id": "056ffbf7-7295-4299-8a60-798a1946a88a",
"type": "policy.acknowledged",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-21T08:17:29.3374061Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"policyId": "92f13f88-9342-4b14-b7e8-ab8bc4d7e685",
"employeeId": "4b9d2c1e-7a3f-4e8b-9c21-5d6e7f8a9b0c",
"acknowledgedAt": "2026-10-21T08:17:29.3374061Z"
}
}TestSent only when you test an endpoint
1 eventSent when someone selects Test on an endpoint in KalHR. Sent whatever events the endpoint subscribes to.
Field in data | Description |
|---|---|
endpointIduuid | The endpoint being tested |
messagestring | A fixed sentence |
{
"id": "5d70f28d-fbe3-4483-b1de-8c11f9eee79c",
"type": "webhook.test",
"apiVersion": "2026-10-15",
"occurredAt": "2026-10-19T12:00:00.4517283Z",
"organizationId": "8c1d0e2f-4a6b-4c8d-9e0f-1a2b3c4d5e6f",
"data": {
"endpointId": "4befcb31-d204-4972-8330-52f3fe5d4179",
"message": "This is a test event from KalHR. If you can read this, your endpoint works."
}
}Changes to events
New event types and new fields in data may be added at any time, so ignore what you don't recognise. A field is never
renamed or removed, and an event's meaning never changes, without a new apiVersion.
Related
- Receiving webhooks
- Verifying signatures
- API reference: fetch the record behind an event