KalHR logo

Webhooks

Event catalogue

Every event KalHR can send to a webhook, when it is sent, what each field means, and a sample of the whole request body.

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": { }
}
FieldMeaning
idThe event's id. The same on every retry and redelivery, so use it to skip repeats.
typeWhat happened, such as leave.approved
apiVersionThe version of this format, currently 2026-10-15
occurredAtWhen it happened, in UTC with a Z
organizationIdYour organisation
dataThe event's details, described on each event below

Reading the data

  • Ids and statuses only. data never 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 events

employee.created

PeopleBasic

Sent when an employee record is created: by HR, by bulk upload, or by approved self-onboarding.

employeeIduuidThe employee recordGET v1/employee/{id}
employeeNumberstringnullableYour own employee number
fullNamestringnullableFirst and last name
emailstringnullableWork email
companyIduuidnullableThe company the record belongs to
statusstringnullableThe 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"
  }
}

employee.updated

PeopleBasic

Sent when an employee's record is changed, by HR or by an approved profile update.

employeeIduuidThe employee recordGET v1/employee/{id}
employeeNumberstringnullableYour own employee number
fullNamestringnullableFirst and last name
emailstringnullableWork email
companyIduuidnullableThe company the record belongs to
statusstringnullableThe 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"
  }
}

employee.terminated

PeopleBasic

Sent when an employee's exit is final.

employeeIduuidThe employee who is leaving
terminationIduuidnullableThe exit record in KalHR
exitDatedatenullableTheir 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"
  }
}

onboarding.submitted

OnboardingBasic

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.

onboardingIduuidThe onboarding submission. When there is no onboarding approval, the same id as employeeId.
companyIduuidnullableThe company they are joining
emailstringnullableThe new hire's email
employeeIduuidnullableThe 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
  }
}

onboarding.approved

OnboardingBasic

Sent when a submitted onboarding is approved and the employee is created.

onboardingIduuidThe onboarding submission. When there is no onboarding approval, the same id as employeeId.
companyIduuidnullableThe company they are joining
emailstringnullableThe new hire's email
employeeIduuidnullableThe 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"
  }
}

leave.requested

LeaveBasic

Sent when an employee asks for leave.

status is Submitted.

leaveRequestIduuidThe leave requestGET v1/leaverequest/details/{id}
employeeIduuidnullableWho asked
leaveTypeIduuidnullableThe leave type
leaveTypestringnullableThe leave type's name
startDatedatenullableFirst day off
endDatedatenullableLast day off
statusstringnullableThe 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"
  }
}

leave.approved

LeaveBasic

Sent when a leave request is approved.

leaveRequestIduuidThe leave requestGET v1/leaverequest/details/{id}
employeeIduuidnullableWho asked
leaveTypeIduuidnullableThe leave type
leaveTypestringnullableThe leave type's name
startDatedatenullableFirst day off
endDatedatenullableLast day off
statusstringnullableThe 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"
  }
}

leave.rejected

LeaveBasic

Sent when a leave request is rejected.

leaveRequestIduuidThe leave requestGET v1/leaverequest/details/{id}
employeeIduuidnullableWho asked
leaveTypeIduuidnullableThe leave type
leaveTypestringnullableThe leave type's name
startDatedatenullableFirst day off
endDatedatenullableLast day off
statusstringnullableThe 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"
  }
}

leave.cancelled

LeaveBasic

Sent when a leave request is withdrawn or deleted.

status is Abandoned when it was withdrawn, Deleted when it was deleted.

leaveRequestIduuidThe leave requestGET v1/leaverequest/details/{id}
employeeIduuidnullableWho asked
leaveTypeIduuidnullableThe leave type
leaveTypestringnullableThe leave type's name
startDatedatenullableFirst day off
endDatedatenullableLast day off
statusstringnullableThe 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 events

payroll.created

PayrollStandard

Sent 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.

payrollIduuidThe payroll runGET v1/payroll/schedule/{id}
payrollCodestringnullableThe run's code, such as ACM-3F9A1C
companyIduuidnullableThe company being paid
payrollDatedatenullableThe pay day
statusstringnullableThe 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"
  }
}

payroll.approved

PayrollStandard

Sent when a payroll run is approved and can be paid.

payrollIduuidThe payroll runGET v1/payroll/schedule/{id}
payrollCodestringnullableThe run's code, such as ACM-3F9A1C
companyIduuidnullableThe company being paid
payrollDatedatenullableThe pay day
statusstringnullableThe 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"
  }
}

payroll.paid

PayrollStandard

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.

payrollIduuidThe payroll runGET v1/payroll/schedule/{id}
payrollCodestringnullableThe run's code, such as ACM-3F9A1C
companyIduuidnullableThe company being paid
payrollDatedatenullableThe pay day
statusstringnullableThe 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"
  }
}

payroll.transfer_failed

PayrollStandard

Sent when one employee's salary transfer fails or is reversed.

payrollIduuidThe payroll run
payrollCodestringnullableThe run's code
employeeIduuidnullableWhose salary didn't arrive
referencestringThe transfer's reference with the payment provider
outcomestringWhat 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"
  }
}

loan.requested

LoansStandard

Sent when an employee applies for a loan.

loanIduuidThe loan
employeeIduuidnullableWho borrowed
statusstringnullableThe 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"
  }
}

loan.approved

LoansStandard

Sent when a loan is approved.

loanIduuidThe loan
employeeIduuidnullableWho borrowed
statusstringnullableThe 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"
  }
}

loan.disbursed

LoansStandard

Sent when a loan is paid out.

status is Active: repayments have started.

loanIduuidThe loan
employeeIduuidnullableWho borrowed
statusstringnullableThe 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"
  }
}

attendance.exception.approved

AttendanceStandard

Sent when an attendance exception (an excused day, a day off, a remote day, a closure) takes effect.

exceptionIduuidThe attendance exceptionGET v1/attendance/exceptions/{id}
employeeIduuidnullableWho is excused
typestringnullableWhat kind of exceptionExcusedAbsenceDayOffGrantedRemoteDayCompanyClosure
startDatedatenullableFirst day covered
endDatedatenullableLast 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"
  }
}

attendance.absence_report.completed

AttendanceStandard

Sent when the absence report for a day finishes, so that day's attendance is complete.

reportIduuidThe day's reportGET v1/attendance/report/{id}
datedatenullableThe day the report covers
statusstringnullableAlways 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 events

candidate.applied

RecruitmentAdvanced

Sent when someone applies to a job.

applicationIduuidThe job application
jobPostIduuidnullableThe job
stageIduuidnullableThe pipeline stage
stageNamestringnullableThe 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"
  }
}

candidate.stage_changed

RecruitmentAdvanced

Sent when a candidate moves to another pipeline stage.

The stage fields are the new stage.

applicationIduuidThe job application
jobPostIduuidnullableThe job
stageIduuidnullableThe pipeline stage
stageNamestringnullableThe 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"
  }
}

candidate.rejected

RecruitmentAdvanced

Sent when a candidate is rejected.

The stage fields are the stage they were in.

applicationIduuidThe job application
jobPostIduuidnullableThe job
stageIduuidnullableThe pipeline stage
stageNamestringnullableThe 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"
  }
}

interview.scorecard_submitted

RecruitmentAdvanced

Sent when an interviewer submits a scorecard.

scorecardIduuidThe submitted scorecard
applicationIduuidnullableThe candidate's application
stageIduuidnullableThe 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"
  }
}

offer.sent

OffersAdvanced

Sent when an offer letter is sent to a candidate.

offerIduuidThe offer letter
jobApplicationIduuidnullableThe application it was made on
companyIduuidnullableThe hiring company
statusstringnullableThe 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"
  }
}

offer.accepted

OffersAdvanced

Sent when a candidate accepts an offer.

offerIduuidThe offer letter
jobApplicationIduuidnullableThe application it was made on
companyIduuidnullableThe hiring company
statusstringnullableThe 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"
  }
}

offer.declined

OffersAdvanced

Sent when a candidate declines an offer.

offerIduuidThe offer letter
jobApplicationIduuidnullableThe application it was made on
companyIduuidnullableThe hiring company
statusstringnullableThe 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"
  }
}

offer.expired

OffersAdvanced

Sent when an offer passes its respond-by date unanswered.

offerIduuidThe offer letter
jobApplicationIduuidnullableThe application it was made on
companyIduuidnullableThe hiring company
statusstringnullableThe 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"
  }
}

approval.requested

ApprovalsAdvanced

Sent when something is submitted for approval.

The sample is a leave request, so subjectId is the leave request's id.

approvalInstanceIduuidThis run of the approval workflow
scenariostringnullableWhat is being approvedLeaveRequestPayrollScheduleCreationProbationConfirmationEmployeeTerminationLoanEmployeeSelfOnboardingDisciplinaryActionDisciplinarySuspensionDisciplinaryTerminationRecommendationAttendanceExceptionOfferLetter
subjectIduuidThe record being approved: the leave request, payroll run, loan... For OfferLetter, that submission of the offer.
statusstringnullablePending 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"
  }
}

approval.completed

ApprovalsAdvanced

Sent when an approval finishes, approved or rejected.

approvalInstanceIduuidThis run of the approval workflow
scenariostringnullableWhat is being approvedLeaveRequestPayrollScheduleCreationProbationConfirmationEmployeeTerminationLoanEmployeeSelfOnboardingDisciplinaryActionDisciplinarySuspensionDisciplinaryTerminationRecommendationAttendanceExceptionOfferLetter
subjectIduuidThe record being approved: the leave request, payroll run, loan... For OfferLetter, that submission of the offer.
statusstringnullablePending 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"
  }
}

disciplinary.case.opened

DisciplinaryAdvanced

Sent when a disciplinary case is opened.

Only ids, the case number and the status: what a case is about stays in KalHR.

caseIduuidThe disciplinary case
employeeIduuidnullableThe employee the case is about
caseNumberstringnullableSuch as DISC-2026-0007
statusstringnullableThe 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"
  }
}

disciplinary.case.closed

DisciplinaryAdvanced

Sent when a disciplinary case is closed or cancelled.

status is Closed, or Cancelled when the case was cancelled.

caseIduuidThe disciplinary case
employeeIduuidnullableThe employee the case is about
caseNumberstringnullableSuch as DISC-2026-0007
statusstringnullableThe 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"
  }
}

policy.published

Staff policiesAdvanced

Sent when a staff policy is published.

policyIduuidThe staff policy
titlestringnullableIts 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"
  }
}

policy.acknowledged

Staff policiesAdvanced

Sent when an employee acknowledges a staff policy.

policyIduuidThe staff policy
employeeIduuidWho acknowledged it
acknowledgedAtdatetimeWhen, 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 event

webhook.test

TestingTest

Sent when someone selects Test on an endpoint in KalHR. Sent whatever events the endpoint subscribes to.

endpointIduuidThe endpoint being tested
messagestringA 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.

Last updated October 19, 2026

Missing an endpoint or an event?

Tell us what you're building. The API grows from what integrators ask for.

See KalHR in action - 30 min demo