Skip to content
ShiftlyDevelopers
Documentation menu

Projects

Jobs or cost centres that shifts and timesheets are recorded against. The business may call them something else in Shiftly. Archive a project by changing its status; projects are not deleted.

Needs one of the settings:read or roster:read or timesheets:read or people:read or leave:read or projects:write permissions, depending on the operation. The business sees it as "Business details and locations".

Fields

Project fields
FieldTypeAccessMeaning
idstringRead-onlyThe project.
namestringWritableThe project's name.
codestringWritableA short code, unique in the business.
colourstring, may be nullWritableThe colour Shiftly shows it in, as #RRGGBB.
status"active", "archived"Writableactive, or archived when it can no longer be picked for new work. Archived projects keep their history.
employee_idsarray of stringWritableStaff assigned to the project. A manager limited to some locations sees only their own staff here, and a change they make keeps the others.
budgetnumber, may be nullRead-onlyThe budget, in dollars. Set in Shiftly. Returned only with pay:read.
linked_to_payroll_trackingbooleanRead-onlyTrue when the project is linked to a tracking category in the business's payroll.
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 projects

GET/v1/projects

Permission: settings:read, roster:read, timesheets:read, people:read, leave:read Needs any one of: settings:read, roster:read, timesheets:read, people:read, leave: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.
status"active", "archived"OptionalOnly records in this status.
200 response
{
  "data": [
    {
      "id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "name": "text",
      "code": "text",
      "colour": "text",
      "status": "active",
      "employee_ids": [],
      "budget": 1.5,
      "linked_to_payroll_tracking": 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 a project

POST/v1/projects

Permission: projects:write

Request body
FieldTypeRequiredMeaning
namestringRequiredThe project's name.
codestringRequiredA short code, unique in the business.
colourstringOptionalThe colour Shiftly shows it in, as #RRGGBB.
employee_idsarray of stringOptionalStaff assigned to the project. A manager limited to some locations sees only their own staff here, and a change they make keeps the others.
Request body
{
  "name": "text",
  "code": "text",
  "colour": "text",
  "employee_ids": [
    "66f1c2a4b3d9e8f7a6b5c4d3"
  ]
}
201 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "name": "text",
  "code": "text",
  "colour": "text",
  "status": "active",
  "employee_ids": [
    "66f1c2a4b3d9e8f7a6b5c4d3"
  ],
  "budget": 1.5,
  "linked_to_payroll_tracking": 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 project

GET/v1/projects/{id}

Permission: settings:read, roster:read, timesheets:read, people:read, leave:read Needs any one of: settings:read, roster:read, timesheets:read, people:read, leave:read.

200 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "name": "text",
  "code": "text",
  "colour": "text",
  "status": "active",
  "employee_ids": [
    "66f1c2a4b3d9e8f7a6b5c4d3"
  ],
  "budget": 1.5,
  "linked_to_payroll_tracking": 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.

Change or archive a project

PATCH/v1/projects/{id}

Permission: projects:write

Request body
FieldTypeRequiredMeaning
namestringOptionalThe project's name.
codestringOptionalA short code, unique in the business.
colourstring, may be nullOptionalThe colour Shiftly shows it in, as #RRGGBB.
employee_idsarray of stringOptionalStaff assigned to the project. A manager limited to some locations sees only their own staff here, and a change they make keeps the others.
status"active", "archived"Optionalactive, or archived when it can no longer be picked for new work. Archived projects keep their history.
Request body
{
  "name": "text",
  "code": "text",
  "colour": "text",
  "employee_ids": [
    "66f1c2a4b3d9e8f7a6b5c4d3"
  ],
  "status": "active"
}
200 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "name": "text",
  "code": "text",
  "colour": "text",
  "status": "active",
  "employee_ids": [
    "66f1c2a4b3d9e8f7a6b5c4d3"
  ],
  "budget": 1.5,
  "linked_to_payroll_tracking": 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.