Skip to content
ShiftlyDevelopers
Documentation menu

Timesheets

Worked time. A timesheet your app creates is pending until a manager approves it in Shiftly. Pay is always worked out by Shiftly.

Needs one of the timesheets:read or timesheets:write permissions, depending on the operation. The business sees it as "Timesheets".

Fields

Timesheet fields
FieldTypeAccessMeaning
idstringRead-onlyThe timesheet.
employee_idstringWritableWho worked.
location_idstringWritableWhere.
position_idstringWritableThe position worked.
shift_idstring, may be nullWritableThe rostered shift this timesheet is for, if any.
start_timetimestampWritableWhen work started. Stored to the whole minute.
end_timetimestamp, may be nullWritableWhen work ended. Stored to the whole minute.
status"pending", "approved", "rejected", "active", "posted", "warning", "skipped"Read-onlypending until a manager approves it in Shiftly.
breaksarray of objectWritableBreaks taken.
notestring, may be nullWritableA note on the timesheet.
project_idstring, may be nullRead-onlyThe project the time is charged to, if any.
clock_in_photo_takenboolean, may be nullRead-onlyTrue when a photo was taken at clock-in, false when one was asked for and none was taken, null when none was asked for. The photo itself is never shared.
clock_out_photo_takenboolean, may be nullRead-onlyThe same for clock-out. Null while the person is still clocked in.
paid_hoursnumberRead-onlyHours paid, after unpaid breaks. Worked out by Shiftly.
payobjectRead-onlyWhat the timesheet costs, in dollars. Worked out by Shiftly. Returned only with pay:read.
created_by_appbooleanRead-onlyTrue when your app created this timesheet.
archivedbooleanRead-onlyTrue when the record has been removed in Shiftly.
created_attimestampRead-onlyWhen the record was created.
updated_attimestampRead-onlyWhen the record last changed.

Operations

List timesheets

GET/v1/timesheets

Permission: timesheets:read

Query parameters
ParameterTypeMeaning
limitinteger, default 50, up to 200OptionalHow many records per page. Up to 200.
afterstringOptionalThe next_cursor from the previous page.
updated_sincetimestampOptionalOnly records changed at or after this moment. Pair it with include_archived to see removals.
include_archived"true", "false"OptionalInclude records that have been archived.
fromdateOptionalThe first day of the range, in the location's timezone. With to, at most 92 days.
todateOptionalThe last day of the range, inclusive.
location_idstringOptionalOnly this location.
employee_idstringOptionalOnly this person.
200 response
{
  "data": [
    {
      "id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "employee_id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "shift_id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "start_time": "2026-10-06T09:00:00+11:00",
      "end_time": "2026-10-06T09:00:00+11:00",
      "status": "pending",
      "breaks": [],
      "note": "text",
      "project_id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "clock_in_photo_taken": true,
      "clock_out_photo_taken": true,
      "paid_hours": 1.5,
      "pay": {
        "total": null,
        "subtotal": null,
        "super": null,
        "allowances": null,
        "position_loading": null,
        "breakdown": null
      },
      "created_by_app": true,
      "archived": true,
      "created_at": "2026-10-06T09:00:00+11:00",
      "updated_at": "2026-10-06T09:00:00+11:00"
    }
  ],
  "has_more": true,
  "next_cursor": "text"
}
Refusals
StatusWhen
400The error's code is invalid_request or range_too_long. The Errors page describes each code.
401The error's code is invalid_token or token_expired. The Errors page describes each code.
403The error's code is origin_not_allowed, permission_denied, not_available, connection_disconnected, connection_suspended or app_suspended. The Errors page describes each code.
404There is nothing at this address, or no such record in this business.
429Too many requests. Retry-After says when to try again.
500Something went wrong at Shiftly. Quote the request id.
503This environment is not set up for partner apps yet.

Create one pending timesheet, or up to 100 in one all-or-nothing request

POST/v1/timesheets

Permission: timesheets:write

Request body
FieldTypeRequiredMeaning
employee_idstringRequiredWho worked.
location_idstringRequiredWhere.
position_idstringRequiredThe position worked.
shift_idstringOptionalThe rostered shift this timesheet is for, if any.
start_timetimestampRequiredWhen work started. Stored to the whole minute.
end_timetimestampRequiredWhen work ended. Stored to the whole minute.
breaksarray of objectOptionalBreaks taken.
notestring, may be nullOptionalA note on the timesheet.

Or send { "data": [ ... ] } with up to 100 items to create several in one request. A refused batch saves nothing.

Request body
{
  "employee_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "shift_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "breaks": [
    {
      "start": "2026-10-06T09:00:00+11:00",
      "end": "2026-10-06T09:00:00+11:00",
      "paid": true
    }
  ],
  "note": "text"
}
201 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "employee_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "shift_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "status": "pending",
  "breaks": [
    {
      "start": "2026-10-06T09:00:00+11:00",
      "end": "2026-10-06T09:00:00+11:00",
      "paid": true
    }
  ],
  "note": "text",
  "project_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "clock_in_photo_taken": true,
  "clock_out_photo_taken": true,
  "paid_hours": 1.5,
  "pay": {
    "total": 1.5,
    "subtotal": 1.5,
    "super": 1.5,
    "allowances": 1.5,
    "position_loading": 1.5,
    "breakdown": [
      {
        "category": null,
        "hours": null,
        "rate": null,
        "cost": null
      }
    ]
  },
  "created_by_app": true,
  "archived": true,
  "created_at": "2026-10-06T09:00:00+11:00",
  "updated_at": "2026-10-06T09:00:00+11:00"
}
Refusals
StatusWhen
400The error's code is invalid_request or range_too_long. The Errors page describes each code.
401The error's code is invalid_token or token_expired. The Errors page describes each code.
403The error's code is origin_not_allowed, permission_denied, not_available, connection_disconnected, connection_suspended or app_suspended. The Errors page describes each code.
404There is nothing at this address, or no such record in this business.
409The error's code is conflict, idempotency_key_reused or request_in_progress. The Errors page describes each code.
422A field is wrong. The field property names it.
429Too many requests. Retry-After says when to try again.
500Something went wrong at Shiftly. Quote the request id.
503This environment is not set up for partner apps yet.

Get one timesheet

GET/v1/timesheets/{id}

Permission: timesheets:read

200 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "employee_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "shift_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "status": "pending",
  "breaks": [
    {
      "start": "2026-10-06T09:00:00+11:00",
      "end": "2026-10-06T09:00:00+11:00",
      "paid": true
    }
  ],
  "note": "text",
  "project_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "clock_in_photo_taken": true,
  "clock_out_photo_taken": true,
  "paid_hours": 1.5,
  "pay": {
    "total": 1.5,
    "subtotal": 1.5,
    "super": 1.5,
    "allowances": 1.5,
    "position_loading": 1.5,
    "breakdown": [
      {
        "category": null,
        "hours": null,
        "rate": null,
        "cost": null
      }
    ]
  },
  "created_by_app": true,
  "archived": true,
  "created_at": "2026-10-06T09:00:00+11:00",
  "updated_at": "2026-10-06T09:00:00+11:00"
}
Refusals
StatusWhen
400The error's code is invalid_request or range_too_long. The Errors page describes each code.
401The error's code is invalid_token or token_expired. The Errors page describes each code.
403The error's code is origin_not_allowed, permission_denied, not_available, connection_disconnected, connection_suspended or app_suspended. The Errors page describes each code.
404There is nothing at this address, or no such record in this business.
429Too many requests. Retry-After says when to try again.
500Something went wrong at Shiftly. Quote the request id.
503This environment is not set up for partner apps yet.

Correct a pending timesheet

PATCH/v1/timesheets/{id}

Permission: timesheets:write

Request body
FieldTypeRequiredMeaning
position_idstringOptionalThe position worked.
start_timetimestampOptionalWhen work started. Stored to the whole minute.
end_timetimestampOptionalWhen work ended. Stored to the whole minute.
breaksarray of objectOptionalBreaks taken.
notestring, may be nullOptionalA note on the timesheet.
Request body
{
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "breaks": [
    {
      "start": "2026-10-06T09:00:00+11:00",
      "end": "2026-10-06T09:00:00+11:00",
      "paid": true
    }
  ],
  "note": "text"
}
200 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "employee_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "shift_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "status": "pending",
  "breaks": [
    {
      "start": "2026-10-06T09:00:00+11:00",
      "end": "2026-10-06T09:00:00+11:00",
      "paid": true
    }
  ],
  "note": "text",
  "project_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "clock_in_photo_taken": true,
  "clock_out_photo_taken": true,
  "paid_hours": 1.5,
  "pay": {
    "total": 1.5,
    "subtotal": 1.5,
    "super": 1.5,
    "allowances": 1.5,
    "position_loading": 1.5,
    "breakdown": [
      {
        "category": null,
        "hours": null,
        "rate": null,
        "cost": null
      }
    ]
  },
  "created_by_app": true,
  "archived": true,
  "created_at": "2026-10-06T09:00:00+11:00",
  "updated_at": "2026-10-06T09:00:00+11:00"
}
Refusals
StatusWhen
400The error's code is invalid_request or range_too_long. The Errors page describes each code.
401The error's code is invalid_token or token_expired. The Errors page describes each code.
403The error's code is origin_not_allowed, permission_denied, not_available, connection_disconnected, connection_suspended or app_suspended. The Errors page describes each code.
404There is nothing at this address, or no such record in this business.
409The error's code is conflict, timesheet_not_pending, idempotency_key_reused or request_in_progress. The Errors page describes each code.
422A field is wrong. The field property names it.
429Too many requests. Retry-After says when to try again.
500Something went wrong at Shiftly. Quote the request id.
503This environment is not set up for partner apps yet.

Delete a pending timesheet

DELETE/v1/timesheets/{id}

Permission: timesheets:write

200 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "deleted": true
}
Refusals
StatusWhen
400The error's code is invalid_request or range_too_long. The Errors page describes each code.
401The error's code is invalid_token or token_expired. The Errors page describes each code.
403The error's code is origin_not_allowed, permission_denied, not_available, connection_disconnected, connection_suspended or app_suspended. The Errors page describes each code.
404There is nothing at this address, or no such record in this business.
409The error's code is conflict, timesheet_not_pending, idempotency_key_reused or request_in_progress. The Errors page describes each code.
422A field is wrong. The field property names it.
429Too many requests. Retry-After says when to try again.
500Something went wrong at Shiftly. Quote the request id.
503This environment is not set up for partner apps yet.

Not available to partner apps

  • POST /v1/timesheets/{id}/approve

    Timesheets are approved in Shiftly, not by partner apps.