How to Use the Timecloud Public API
The Timecloud Public API lets you connect external systems — payroll tools, HRIS platforms, scheduling engines, or custom dashboards — directly to your Timecloud data. Use it to automate employee management, roster scheduling, attendance tracking, and more.
Getting Started
- Contact your Timecloud account manager to enable API access for your company.
- You will receive client credentials (a Client ID and Client Secret).
- All API communication happens over HTTPS.
- Call the /oauth/token endpoint with your Client ID and Client Secret.
- You'll receive a Bearer token.
- Include this token in the Authorization header of all subsequent requests:
Authorization: Bearer <your-token>
- Request date fields:
YYYY-MM-DD(e.g.2024-01-15) - Response date-time fields: ISO 8601 UTC (e.g.
2024-01-15T09:30:00.000Z) - All times are returned in UTC.
Below is an overview of what you can manage through the API. Full endpoint details (request/response schemas, query parameters, and error codes) are available in the interactive Swagger documentation provided with your API credentials.
Employees
|
Action |
Method & Path |
|---|---|
|
List all employees |
GET /employees |
|
Get a single employee |
GET /employees/{employeeId} |
|
Create an employee |
POST /employees |
|
Update an employee |
PATCH /employees/{employeeId} |
|
Archive an employee |
PATCH /employees/{employeeId} with {"active": false} |
Tips:
- Assign roles, departments, or default job items by passing arrays of IDs in
companyRoles,userGroups, ordefaultJobItems.
Company Roles
|
Action |
Method & Path |
|---|---|
|
List roles |
GET /company-roles |
|
Create a role |
POST /company-roles |
|
Update a role |
PATCH /company-roles/{roleId} |
|
Delete a role |
DELETE /company-roles/{roleId} |
Note: You cannot delete a role while active employees are still assigned to it. Unassign employees first.
Departments (User Groups)
|
Action |
Method & Path |
|---|---|
|
List departments |
GET /company/groups |
|
Create a department |
POST /company/groups |
|
Update a department |
PATCH /company/groups/{groupId} |
|
Delete a department |
DELETE /company/groups/{groupId} |
|
List employees in a department |
GET /company/groups/{groupId}/users |
Notes:
- Departments can be nested. Pass
parentGroupIdwhen creating to nest under a parent. - Deleting a department also removes its sub-departments. Employees are automatically unassigned.
- Deletion is blocked if active job items reference the department.
Roster — Employee View
|
Action |
Method & Path |
|---|---|
|
Get roster assignments |
GET /rosters/employee |
|
Create or update shifts |
POST /rosters/employee |
|
Publish draft shifts |
POST /rosters/employee/publish |
|
Clear draft shifts |
POST /rosters/employee/clear |
|
Delete a shift assignment |
DELETE /rosters/employee/shifts/{shiftId}/{employeeId} |
|
Batch delete shift assignments |
POST /rosters/employee/shifts/delete |
Tips:
- Set
isPublished: trueon a shift to publish it immediately. Otherwise, it stays as a draft until you call /publish. - Use
conflictAuthorised: trueto bypass overlap checks when you know a double-booking is intentional. - Filter publish/clear actions by
employeeIdsoruserGroupIdsquery parameters.
Roster — Shift View
|
Action |
Method & Path |
|---|---|
|
Get shift roster grid |
GET /rosters/shift |
|
Create or update shifts |
POST /rosters/shift |
|
Publish draft shifts |
POST /rosters/shift/publish |
|
Clear draft shifts |
POST /rosters/shift/clear |
|
Delete a shift |
DELETE /rosters/shift/{shiftId} |
|
List invitations |
GET /rosters/shift/invitations |
|
Send invitations |
POST /rosters/shift/invitations |
|
Update draft invitations |
PATCH /rosters/shift/invitations |
Tips:
- After creating shifts, the response includes
shiftMappingsso you can map your payload to the created shift IDs. - Send invitations with
draft=trueto save without notifying employees.
Attendance & Checkin Pairs
|
Action |
Method & Path |
|---|---|
|
List attendance days |
GET /attendances |
|
Create or update a checkin pair |
POST /attendances/{attendanceId}/checkin-pairs |
|
Delete checkins |
POST /attendances/checkins/delete |
Notes:
- Checkin pairs use upsert via POST: include the checkin
_idto update an existing checkin, or omit it to create a new one. - Writes and deletes are blocked when the attendance day has been manager-approved (signed off).
- Each response returns the fully recalculated attendance record, so you always have up-to-date totals.
Job Items
|
Action |
Method & Path |
|---|---|
|
List job items |
GET /job-items |
|
Search job items |
GET /job-items/search |
|
Create a job item |
POST /job-items |
|
Update a job item |
PATCH /job-items/{jobItemId} |
|
Deactivate a job item |
PATCH /job-items/{jobItemId} with {"isActive": false} |
Company & Shift Templates
|
Action |
Method & Path |
|---|---|
|
Get company details |
GET /company |
|
List shift templates |
GET /shift-templates |
Payroll Report
|
Action |
Method & Path |
|---|---|
|
Generate a custom payroll report |
POST /payroll/providers/{payrollProviderId}/report-builder/generate |
How it works:
- Provide a date range (
start-date,end-date), optional employee IDs, and optional department filters. - Results are paginated by employee. Use the optional
pageandpageSizefields to control which slice of employees is returned. - The response returns data (report rows), errors (employees that could not be calculated), and pagination metadata (
total,page,pageSize,totalPages). - Successfully processed employees appear in data. Employees that encountered a processing issue are omitted from data and reported in errors instead.
Pagination:
- page — The page number to retrieve (default:
1). - pageSize — Number of employees per page (default:
50, maximum:50). - Employees are returned in a consistent order. To retrieve all employees, increment
pageuntilpageexceedstotalPages. - If
pageis beyond the last page of results, data returns an empty array with no error.
Response structure:
- data — A two-dimensional array of strings. When data rows exist, the first row contains column headers; subsequent rows contain the timesheet data for each successfully processed employee. When the requested page has no matching data, data is an empty array.
- errors — An array of objects, each describing an employee whose timesheet could not be generated. Each error includes:
- employeeId — The ID of the affected employee.
- employeeName — The employee's full name.
- date — The date (in your company timezone,
YYYY-MM-DD) of the shift that caused the issue, ornullif not shift-specific. - message — A human-readable description of what went wrong.
- total — Total number of employees matching your filters.
- page — The current page number.
- pageSize — The number of employees per page.
- totalPages — The total number of pages available.
Tips:
- Always check the errors array after receiving a response. An empty errors array means all employees on that page were processed successfully.
- If an employee appears in errors, their timesheet lines are excluded from data. Review the error message and correct the underlying issue before re-generating.
- The maximum date range is governed by your company's pay period.
- To fetch a complete report for all employees, loop through pages starting at
page=1and increment untilpageexceedstotalPages.
- Sync employees from your HRIS: Use
GET /employeesto compare, thenPOSTto create orPATCHto update. - Build a roster: List shift templates, then
POST /rosters/employeeorPOST /rosters/shiftto assign shifts. Call /publish when ready. - Push timesheet data: Use
POST /attendances/{id}/checkin-pairsto write clock-in/out records from an external system. - Archive leavers:
PATCH /employees/{id}with{"active": false}. - Set up your org structure: Create departments via
POST /company/groups(nest withparentGroupId), then assign employees. - Generate payroll reports: Call
POST /payroll/providers/{payrollProviderId}/report-builder/generatewith your date range. UsepageandpageSizeto paginate through employees. Process the data rows from each page and handle any entries in errors for employees that could not be calculated.
- 400 — Bad request (missing or invalid fields). Check the response body for details.
- 401 — Unauthorised. Your token may have expired — request a new one.
- 404 — Resource not found. Verify the ID exists.
- 409 — Conflict (e.g. overlapping roster shifts). Use
conflictAuthorised: trueto override where appropriate. - 422 — Unprocessable (e.g. writing to a manager-approved attendance day).
Reach out to your Timecloud account manager or contact support@jointimecloud.com for API access, troubleshooting, or integration guidance.