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
| Field | Type | Access | Meaning |
|---|---|---|---|
| id | string | Read-only | The OnDemand shift. |
| location_id | string | Writable | Where the shift is. |
| position_id | string | Writable | The position the worker fills. |
| start_time | timestamp | Writable | When the shift starts. |
| end_time | timestamp | Writable | When the shift ends. |
| status | "draft", "posted", "filled", "in_progress", "completed", "no_show", "expired" | Read-only | draft, posted, filled, in_progress, completed, no_show or expired. The venue publishes drafts in Shiftly. |
| rate_set | boolean | Read-only | True once the venue has set the hourly rate. A draft needs one before the venue can publish it. |
| rate | number, may be null | Read-only | The hourly rate the venue set, in dollars. Empty until the venue sets it. Returned only with pay:read. |
| paid_hours | number, may be null | Read-only | Hours paid, after unpaid breaks. |
| notes | string, may be null | Writable | The shift description the venue sees in Shiftly. The worker app doesn't show it yet. |
| posted_at | timestamp, may be null | Read-only | When the venue published the shift. Empty for a draft. |
| created_by_app | boolean | Read-only | True when your app created this shift. |
| archived | boolean | Read-only | True when the record has been removed in Shiftly. |
| created_at | timestamp | Read-only | When the record was created. |
| updated_at | timestamp | Read-only | When the record last changed. |
Operations
List OnDemand shifts
GET/v1/on-demand-shifts
Permission: ondemand:read
| Parameter | Type | Meaning | |
|---|---|---|---|
| limit | integer, default 50, up to 200 | Optional | How many records per page. Up to 200. |
| after | string | Optional | The next_cursor from the previous page. |
| updated_since | timestamp | Optional | Only records changed at or after this moment. Pair it with include_archived to see removals. |
| include_archived | "true", "false" | Optional | Include records that have been archived. |
| from | date | Optional | The first day of the range, in the location's timezone. With to, at most 92 days. |
| to | date | Optional | The last day of the range, inclusive. |
| location_id | string | Optional | Only this location. |
| status | "draft", "posted", "filled", "in_progress", "completed", "no_show", "expired" | Optional | Only records in this status. |
{
"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"
}| 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. |
Create one draft OnDemand shift, or up to 100 in one all-or-nothing request
POST/v1/on-demand-shifts
Permission: ondemand:write
| Field | Type | Required | Meaning |
|---|---|---|---|
| location_id | string | Required | Where the shift is. |
| position_id | string | Required | The position the worker fills. |
| start_time | timestamp | Required | When the shift starts. |
| end_time | timestamp | Required | When the shift ends. |
| notes | string, may be null | Optional | The 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.
{
"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"
}{
"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"
}| 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, app_suspended or ondemand_unavailable. The Errors page describes each code. |
| 404 | There is nothing at this address, or no such record in this business. |
| 409 | The error's code is conflict, idempotency_key_reused or request_in_progress. The Errors page describes each code. |
| 422 | A field is wrong. The field property names it. |
| 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. |
Get one OnDemand shift
GET/v1/on-demand-shifts/{id}
Permission: ondemand:read
{
"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"
}| 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. |
Change a draft OnDemand shift that has not started
PATCH/v1/on-demand-shifts/{id}
Permission: ondemand:write
| Field | Type | Required | Meaning |
|---|---|---|---|
| position_id | string | Optional | The position the worker fills. |
| start_time | timestamp | Optional | When the shift starts. |
| end_time | timestamp | Optional | When the shift ends. |
| notes | string, may be null | Optional | The shift description the venue sees in Shiftly. The worker app doesn't show it yet. |
{
"position_id": "66f1c2a4b3d9e8f7a6b5c4d3",
"start_time": "2026-10-06T09:00:00+11:00",
"end_time": "2026-10-06T09:00:00+11:00",
"notes": "text"
}{
"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"
}| 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, app_suspended or ondemand_unavailable. The Errors page describes each code. |
| 404 | There is nothing at this address, or no such record in this business. |
| 409 | The error's code is conflict, shift_started, not_a_draft, idempotency_key_reused or request_in_progress. The Errors page describes each code. |
| 422 | A field is wrong. The field property names it. |
| 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. |
Delete a draft OnDemand shift
DELETE/v1/on-demand-shifts/{id}
Permission: ondemand:write
{
"id": "66f1c2a4b3d9e8f7a6b5c4d3",
"deleted": true
}| 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, app_suspended or ondemand_unavailable. The Errors page describes each code. |
| 404 | There is nothing at this address, or no such record in this business. |
| 409 | The error's code is conflict, shift_started, not_a_draft, idempotency_key_reused or request_in_progress. The Errors page describes each code. |
| 422 | A field is wrong. The field property names it. |
| 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. |
Not available to partner apps
POST /v1/on-demand-shifts/{id}/publish
The venue sets the rate and publishes OnDemand shifts in Shiftly.
