Skip to content
ShiftlyDevelopers
Documentation menu

OnDemand shifts

Shifts a venue offers to independent workers through Shiftly OnDemand. Your app can create, change and delete drafts. The venue sets the hourly rate and publishes each shift in Shiftly. Nothing about the worker is shared.

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

Fields

OnDemandShift fields
FieldTypeAccessMeaning
idstringRead-onlyThe OnDemand shift.
location_idstringWritableWhere the shift is.
position_idstringWritableThe position the worker fills.
start_timetimestampWritableWhen the shift starts.
end_timetimestampWritableWhen the shift ends.
status"draft", "posted", "filled", "in_progress", "completed", "no_show", "expired"Read-onlydraft, posted, filled, in_progress, completed, no_show or expired. The venue publishes drafts in Shiftly.
rate_setbooleanRead-onlyTrue once the venue has set the hourly rate. A draft needs one before the venue can publish it.
ratenumber, may be nullRead-onlyThe hourly rate the venue set, in dollars. Empty until the venue sets it. Returned only with pay:read.
paid_hoursnumber, may be nullRead-onlyHours paid, after unpaid breaks.
notesstring, may be nullWritableThe shift description the venue sees in Shiftly. The worker app doesn't show it yet.
posted_attimestamp, may be nullRead-onlyWhen the venue published the shift. Empty for a draft.
created_by_appbooleanRead-onlyTrue when your app created this shift.
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 OnDemand shifts

GET/v1/on-demand-shifts

Permission: ondemand: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.
status"draft", "posted", "filled", "in_progress", "completed", "no_show", "expired"OptionalOnly records in this status.
200 response
{
  "data": [
    {
      "id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
      "start_time": "2026-10-06T09:00:00+11:00",
      "end_time": "2026-10-06T09:00:00+11:00",
      "status": "draft",
      "rate_set": true,
      "rate": 1.5,
      "paid_hours": 1.5,
      "notes": "text",
      "posted_at": "2026-10-06T09:00:00+11:00",
      "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 draft OnDemand shift, or up to 100 in one all-or-nothing request

POST/v1/on-demand-shifts

Permission: ondemand:write

Request body
FieldTypeRequiredMeaning
location_idstringRequiredWhere the shift is.
position_idstringRequiredThe position the worker fills.
start_timetimestampRequiredWhen the shift starts.
end_timetimestampRequiredWhen the shift ends.
notesstring, may be nullOptionalThe shift description the venue sees in Shiftly. The worker app doesn't show it yet.

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

Request body
{
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "notes": "text"
}
201 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "status": "draft",
  "rate_set": true,
  "rate": 1.5,
  "paid_hours": 1.5,
  "notes": "text",
  "posted_at": "2026-10-06T09:00:00+11:00",
  "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, app_suspended or ondemand_unavailable. 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 OnDemand shift

GET/v1/on-demand-shifts/{id}

Permission: ondemand:read

200 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "status": "draft",
  "rate_set": true,
  "rate": 1.5,
  "paid_hours": 1.5,
  "notes": "text",
  "posted_at": "2026-10-06T09:00:00+11:00",
  "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.

Change a draft OnDemand shift that has not started

PATCH/v1/on-demand-shifts/{id}

Permission: ondemand:write

Request body
FieldTypeRequiredMeaning
position_idstringOptionalThe position the worker fills.
start_timetimestampOptionalWhen the shift starts.
end_timetimestampOptionalWhen the shift ends.
notesstring, may be nullOptionalThe shift description the venue sees in Shiftly. The worker app doesn't show it yet.
Request body
{
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "notes": "text"
}
200 response
{
  "id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "location_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
  "start_time": "2026-10-06T09:00:00+11:00",
  "end_time": "2026-10-06T09:00:00+11:00",
  "status": "draft",
  "rate_set": true,
  "rate": 1.5,
  "paid_hours": 1.5,
  "notes": "text",
  "posted_at": "2026-10-06T09:00:00+11:00",
  "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, app_suspended or ondemand_unavailable. 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, shift_started, not_a_draft, 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 draft OnDemand shift

DELETE/v1/on-demand-shifts/{id}

Permission: ondemand: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, app_suspended or ondemand_unavailable. 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, shift_started, not_a_draft, 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/on-demand-shifts/{id}/publish

    The venue sets the rate and publishes OnDemand shifts in Shiftly.