CloudPay API

Read employees, leave, attendance and payroll summaries from your other systems, file leave requests and record clock punches.

Base URL
https://cloudpay.cloudbox8.com/api/v1
Authentication
An API key from Settings › Integrations › Developers, sent as Authorization: Bearer cpk_…. It opens only its scopes.
Rate limit
120 requests a minute per key unless set otherwise. Answers carry X-RateLimit-* headers; past the limit, 429 with Retry-After.
Errors
{ "error": "…", "code": "…" } with the HTTP status. Lists take page and pageSize (up to 200).
Privacy
NIC, passport, work permit, bank account, address and medical details are never returned. Salaries need payroll:read.
curl https://cloudpay.cloudbox8.com/api/v1/employees \
  -H "Authorization: Bearer cpk_…"
OpenAPI 3.1 document (openapi.json)

Employees

The people of your company.

  • GET/employeesList employees

    Active employees by default, ordered by employee number. Pass `status=all` (or one status) for the others.

    Scope employees:read — read employees.

    Parameters

    statusone of ACTIVE, ON_LEAVE, SUSPENDED, TERMINATED, RESIGNED, all
    An employee status, or `all`. Default ACTIVE.
    departmentIdstring
    locationIdstring
    updatedSincedate-time
    Only rows changed at or after this instant
    pageinteger
    Page number, from 1
    pageSizeinteger
    Rows per page
  • GET/employees/{id}Get an employee

    By CloudPay id or employee number.

    Scope employees:read — read employees.

    Parameters

    idstring · required
    Employee id or employee number

Leave

Leave types, balances and requests.

  • GET/leave/typesList leave types

    The leave types a request can name, by id or code.

    Scope leave:read — read leave.

  • GET/leave/balancesList leave balances

    The balances of one leave year — the calendar year its validity window starts in — for the company or one employee.

    Scope leave:read — read leave.

    Parameters

    yearinteger
    Leave year. Default: the current year.
    employeeIdstring
    One employee, by CloudPay id
    employeeNostring
    One employee, by employee number
    leaveTypeIdstring
    pageinteger
    Page number, from 1
    pageSizeinteger
    Rows per page
  • GET/leave/requestsList leave requests

    Newest first. `from` / `to` return the requests that touch the period.

    Scope leave:read — read leave.

    Parameters

    statusone of PENDING, SUPERVISOR_APPROVED, APPROVED, REJECTED, CANCELLED, OPEN
    OPEN = awaiting a decision at either step.
    employeeIdstring
    One employee, by CloudPay id
    employeeNostring
    One employee, by employee number
    fromdate
    todate
    updatedSincedate-time
    Only rows changed at or after this instant
    pageinteger
    Page number, from 1
    pageSizeinteger
    Rows per page
  • POST/leave/requestsRequest leave for an employee

    Files a request as HR would on the employee's behalf: CloudPay counts the working days (work week and public holidays), checks the balance and overlapping requests, and refuses days of a closed pay period. The request then waits for approval in CloudPay. A full day, half a day, or a number of hours on one day.

    Scope leave:write — request leave.

    JSON body

    employeeIdstring
    Give employeeId or employeeNo
    employeeNostring
    leaveTypeIdstring
    Give leaveTypeId or leaveTypeCode
    leaveTypeCodestring
    startDatedate · required
    endDatedate · required
    isHalfDayboolean
    halfDayPeriodone of MORNING, AFTERNOON
    hoursnumber
    Hourly leave on one day: the hours off (or startTime / endTime)
    startTimestring
    HH:MM
    endTimestring
    HH:MM
    reasonstring
  • GET/leave/requests/{id}Get a leave request

    Follow a request you filed until it is decided.

    Scope leave:read — read leave.

    Parameters

    idstring · required
    In the path

Attendance

Clock-in and clock-out punches.

  • GET/attendance/punchesList punches

    One record per shift, with its clock-in and clock-out and the hours they make, for at most 31 days (default: the last 7). Days without a clock-in are left out. A day can have two records: an Office + WFH day has an office part and a work-from-home part (`place`, `splitDay`, `dayShare`).

    Scope attendance:read — read attendance.

    Parameters

    fromdate
    todate
    employeeIdstring
    One employee, by CloudPay id
    employeeNostring
    One employee, by employee number
    updatedSincedate-time
    Only rows changed at or after this instant
    pageinteger
    Page number, from 1
    pageSizeinteger
    Rows per page
  • POST/attendance/punchesRecord a punch

    A clock-in or clock-out from a time clock, badge reader or another system, at most 7 days old. Send punches in the order they happened. Without `direction` the punch clocks out an employee who is clocked in and clocks in one who is not. The same punch sent again within 2 minutes — even after the shift has closed — is answered with `duplicate: true` and changes nothing; a clock-in that would overlap a recorded shift is refused with 409 OUT_OF_ORDER. Hours are worked out like a clock-out in the app (break, overtime, meal allowance).

    Scope attendance:write — record punches.

    JSON body

    employeeIdstring
    Give employeeId or employeeNo
    employeeNostring
    timestampdate-time · required
    When the punch happened, with its offset (e.g. 2026-10-18T08:02:11+04:00)
    directionone of IN, OUT
    Omit to let CloudPay decide from the employee's open session
    methodone of FINGERPRINT, QR_CODE, MANUAL · required
    How the employee punched: FINGERPRINT, QR_CODE, or MANUAL for any other terminal
    locationIdstring
    The site the terminal is at (default: the roster's, else the employee's)
    notestring

Time terminals

Punches from badge, fingerprint and card terminals, sent with the terminal's device key.

  • POST/punchesSend terminal punches

    One punch, or `{ "punches": [...] }` up to 200 (a terminal flushing its buffer), each naming the employee by `badgeNumber` (or `employeeNo` / `employeeId`) with its time — ISO 8601 with an offset, or the terminal's local time without one, read as Mauritius time. Without `direction`, CloudPay pairs the punches: one closes the open shift, else opens one; a lone punch nearer the end of the shift than its start, with nothing open, is left for HR (IGNORED, UNPAIRED). The same punch within 2 minutes, or a record id (`externalId`) sent before, is a DUPLICATE and changes nothing. Each result says APPLIED, DUPLICATE, IGNORED (REGULARISED, UNPAIRED) or REJECTED (UNKNOWN_BADGE, NO_ACCESS, EMPLOYEE_NOT_ACTIVE, PERIOD_CLOSED, OUT_OF_ORDER…), in the order sent.

    Sent by a time terminal with its own device key (Bearer cpd_…, Settings › Integrations › Time terminals), not an API key.

Payroll

Payroll run summaries. Needs the Payroll module.

  • GET/payroll/runsList payroll runs

    Run summaries, newest period first. Cancelled runs only when asked for with `status=CANCELLED`.

    Scope payroll:read — read payroll.

    Parameters

    yearinteger
    Pay year
    monthinteger
    Pay month (1–12): the month the period ends in
    statusone of DRAFT, PROCESSING, PROCESSED, APPROVED, PAID, CANCELLED
    runTypeone of REGULAR, OFF_CYCLE, BONUS
    pageinteger
    Page number, from 1
    pageSizeinteger
    Rows per page
  • GET/payroll/runs/{id}Get a payroll run

    The run's summary and each employee's totals: gross, deductions, net and employer cost.

    Scope payroll:read — read payroll.

    Parameters

    idstring · required
    In the path