Leave
Manage time-off types, requests, balances, and allocations via the API.
The Leave endpoints let you read and manage time off programmatically.
Call https://api.kuahr.com with the company’s authorised Live key in KUA_API_KEY. The SDKs use this address by default: Node or Python. Replace the illustrative IDs with real records from this company; the public API does not list employees. Persist an operation-specific idempotency key before writes and reuse the exact request on interrupted responses.
Leave types
The kinds of leave the company offers (Annual, Sick, …).
curl "https://api.kuahr.com/v1/leave/types" \
-H "X-Api-Key: kua_live_your_key_here"const types = await kua.leave.listTypes();types = kua.leave.list_types()Create one (leave:write):
curl "https://api.kuahr.com/v1/leave/types" \
-X POST \
-H "X-Api-Key: kua_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "name": "Annual leave", "defaultDaysPerYear": 20, "isPaid": true, "maxCarryoverDays": 5 }'const type = await kua.leave.createType({
name: "Annual leave",
defaultDaysPerYear: 20,
isPaid: true,
maxCarryoverDays: 5,
});leave_type = kua.leave.create_type(
name="Annual leave", default_days_per_year=20, is_paid=True, max_carryover_days=5
)Leave requests
List requests (filter by status and/or employeeId), then create, approve,
reject, or cancel:
# List pending requests
curl "https://api.kuahr.com/v1/leave/requests?status=Submitted" \
-H "X-Api-Key: kua_live_your_key_here"
# Submit a request
curl "https://api.kuahr.com/v1/leave/requests" \
-X POST -H "X-Api-Key: kua_live_your_key_here" -H "Content-Type: application/json" \
-d '{ "employeeId": "b2c3…", "leaveTypeId": "5e6f…", "startDate": "2026-08-03", "endDate": "2026-08-07", "reason": "Family trip" }'
# Choose one authorised decision and use the returned request ID.
case "$LEAVE_DECISION" in
approve) curl -X POST "https://api.kuahr.com/v1/leave/requests/$REQUEST_ID/approve" -H "X-Api-Key: $KUA_API_KEY" ;;
reject) curl -X POST "https://api.kuahr.com/v1/leave/requests/$REQUEST_ID/reject" -H "X-Api-Key: $KUA_API_KEY" -H "Content-Type: application/json" -d '{"comment":"Blackout period"}' ;;
cancel) curl -X POST "https://api.kuahr.com/v1/leave/requests/$REQUEST_ID/cancel" -H "X-Api-Key: $KUA_API_KEY" ;;
*) echo "Set one authorised LEAVE_DECISION before continuing" >&2; exit 1 ;;
esacconst pending = await kua.leave.listRequests({ status: "Submitted" });
const req = await kua.leave.createRequest({
employeeId: "b2c3…",
leaveTypeId: "5e6f…",
startDate: "2026-08-03",
endDate: "2026-08-07",
reason: "Family trip",
});
// decision is ONE explicit authorised choice, not all three actions.
if (decision === "approve") await kua.leave.approveRequest(req.id);
else if (decision === "reject") await kua.leave.rejectRequest(req.id, "Blackout period");
else if (decision === "cancel") await kua.leave.cancelRequest(req.id);pending = kua.leave.list_requests(status="Submitted")
req = kua.leave.create_request(
employee_id="b2c3…", leave_type_id="5e6f…",
start_date="2026-08-03", end_date="2026-08-07", reason="Family trip",
)
# Choose one authorised branch.
if decision == "approve":
kua.leave.approve_request(req.id)
elif decision == "reject":
kua.leave.reject_request(req.id, comment="Blackout period")
elif decision == "cancel":
kua.leave.cancel_request(req.id)Balances & allocations
Check an employee’s remaining days per type, and grant an allocation:
curl "https://api.kuahr.com/v1/leave/balances?employeeId=b2c3…&year=2026" \
-H "X-Api-Key: kua_live_your_key_here"
curl "https://api.kuahr.com/v1/leave/allocations" \
-X POST -H "X-Api-Key: kua_live_your_key_here" -H "Content-Type: application/json" \
-d '{ "employeeId": "b2c3…", "leaveTypeId": "5e6f…", "year": 2026, "totalDays": 20 }'const balances = await kua.leave.balances({ employeeId: "b2c3…", year: 2026 });
await kua.leave.grantAllocation({ employeeId: "b2c3…", leaveTypeId: "5e6f…", year: 2026, totalDays: 20 });balances = kua.leave.balances(employee_id="b2c3…", year=2026)
kua.leave.grant_allocation(employee_id="b2c3…", leave_type_id="5e6f…", year=2026, total_days=20)Events
You can also react to leave changes via webhooks: leave_request.submitted,
leave_request.approved, leave_request.rejected.
Verify the chosen outcome
| Branch | Required starting state | Verify |
|---|---|---|
| Approve | Submitted, eligible request and approval authority | Request is Approved; read its balances again |
| Reject | Submitted, explicit reason/comment | Request is Rejected; no approval is performed |
| Cancel | Submitted or eligible Approved request | Request is Cancelled; re-read balances |
Cancellation uses POST /v1/leave/requests/{id}/cancel. The Node/Python methods above call that route. On an outdated-state conflict, refresh the request list and decide whether the intended action still applies instead of trying every branch. Overlapping dates, missing allocation or eligibility errors must be resolved from the returned code. Read available leave types and balances before requesting or allocating days; allocation is an explicit HR policy action, not a workaround for a denied request.
Done when: the selected request has the intended terminal state and balances agree. Types, requests and balances use leave:read; type creation, allocation and request decisions use leave:write plus endpoint policy. Continue with events or go-live readiness.