HR API

REST endpoints for the HR module — employees, leave, payroll, contracts.

Endpoints

MethodPathPurpose
GET/api/hr/employeesList. Filters: status, department_id, q.
POST/api/hr/employeesCreate.
GET/PATCH/DELETE/api/hr/employees/{id}CRUD.
GET/api/hr/departmentsList.
POST/api/hr/departmentsCreate.
GET/api/hr/leaveList leave requests. Filters: status, employee_id.
POST/api/hr/leaveSubmit a leave request.
POST/api/hr/leave/{id}/approveApprove OR reject (body: {action: 'approve' | 'reject'}). Emits hr.leave.approved or hr.leave.rejected accordingly.
GET/api/hr/leave-balancesList balances per employee.
GET/api/hr/leave-policiesList policies.
GET/api/hr/payrollList payroll runs.
POST/api/hr/payroll/{id}/processCompute + insert payroll_items. Requires hr.payroll.process.
GET/api/hr/contractsList contracts.
POST/api/hr/contracts/{id}/sendSend contract for signature via Resend.
GET/api/hr/contracts/{id}/pdfRender unsigned contract PDF.
GET/api/hr/contracts/{id}/signed-pdfRender signed contract PDF (post-signature).

Key entity shapes

Employee

{
  "id": "uuid",
  "first_name": "string",
  "last_name": "string",
  "email": "string",
  "position": "string?",
  "department_id": "uuid?",
  "hire_date": "iso-8601?",
  "status": "active | inactive | terminated",
  "salary": 0,
  "salary_currency": "USD"
}

Leave request

{
  "id": "uuid",
  "employee_id": "uuid",
  "type": "vacation | sick | personal | bereavement | parental",
  "start_date": "iso-8601",
  "end_date": "iso-8601",
  "status": "pending | approved | rejected",
  "approved_by": "uuid?",
  "approved_at": "iso-8601?"
}

Permissions

hr.employees.*, hr.departments.*, hr.leave.read|create|approve, hr.payroll.read|process, hr.contracts.*. Employees can read their own profile + balances even without admin permissions.

Events

  • hr.employee.created|updated|deleted
  • hr.leave.requested|approved|rejected
  • hr.contract.created|sent|updated|deleted
  • hr.payroll.created|processed

OpenAPI

Full schema at /api/openapi.json.