Timesheet totals
Hours, counts and cost of timesheets started in a date range, split into approved and pending. Rejected timesheets and timesheets still open are left out, and a range with none returns no rows. Totals are rounded once, so they can differ by a few cents from adding up each timesheet.
Needs the timesheets:read permission, depending on the operation. The business sees it as "Timesheets".
Fields
| Field | Type | Access | Meaning |
|---|---|---|---|
| employee_id | string, may be null | Read-only | The person, when grouped by employee. |
| location_id | string, may be null | Read-only | The location, when grouped by location. |
| date | date, may be null | Read-only | The day in the location's timezone, when grouped by day. |
| approved_hours | number | Read-only | Paid hours on approved timesheets. |
| approved_count | integer | Read-only | How many approved timesheets. |
| approved_cost | object, may be null | Read-only | What the approved timesheets cost, including super and allowances. Returned only with pay:read. |
| pending_hours | number | Read-only | Paid hours on pending timesheets. |
| pending_count | integer | Read-only | How many pending timesheets. |
| pending_cost | object, may be null | Read-only | What the pending timesheets cost, including super and allowances. Returned only with pay:read. |
Operations
Total timesheets over a date range
GET/v1/timesheet-totals
Permission: timesheets:read
| Parameter | Type | Meaning | |
|---|---|---|---|
| from | date | Required | The first day of the range, in the location's timezone. With to, at most 92 days. |
| to | date | Required | The last day of the range, inclusive. |
| location_id | string | Optional | Only this location. |
| employee_id | string | Optional | Only this person. |
| group_by | "employee", "location", "day" | Optional |
{
"data": [
{
"employee_id": "66f1c2a4b3d9e8f7a6b5c4d3",
"location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
"date": "2026-10-06",
"approved_hours": 1.5,
"approved_count": 1,
"approved_cost": {
"total": null,
"subtotal": null,
"super": null,
"allowances": null,
"position_loading": null
},
"pending_hours": 1.5,
"pending_count": 1,
"pending_cost": {
"total": null,
"subtotal": null,
"super": null,
"allowances": null,
"position_loading": null
}
}
],
"has_more": true,
"next_cursor": "text"
}| Status | When |
|---|---|
| 400 | The error's code is invalid_request or range_too_long. The Errors page describes each code. |
| 401 | The error's code is invalid_token or token_expired. The Errors page describes each code. |
| 403 | The error's code is origin_not_allowed, permission_denied, not_available, connection_disconnected, connection_suspended or app_suspended. The Errors page describes each code. |
| 404 | There is nothing at this address, or no such record in this business. |
| 429 | Too many requests. Retry-After says when to try again. |
| 500 | Something went wrong at Shiftly. Quote the request id. |
| 503 | This environment is not set up for partner apps yet. |
