Paging and filtering
At the end of this guide your app reads a whole list a page at a time, asks only for what changed, and gets date ranges right across timezones.
Paging
Every list answers with data, has_more and next_cursor. Pass next_cursor back as after to read the next page. A cursor is opaque and belongs to the query that produced it; change the filters and start again from the first page.
curl "https://host.shiftly.au/v1/employees?limit=200" -H "Authorization: Bearer ..."
# ... "has_more": true, "next_cursor": "eyJ..." ...
curl "https://host.shiftly.au/v1/employees?limit=200&after=eyJ..." -H "Authorization: Bearer ..."| Parameter | Default | Limit |
|---|---|---|
| limit | 50 | 200 |
| after | the first page | a cursor from the previous page |
Only what changed
Pass updated_since with a timestamp to receive records changed at or after that moment. Record the newest updated_at you have seen and send it next time. Pair it with include_archived=true, or a record removed since your last read is left out and you never learn it went.
curl "https://host.shiftly.au/v1/shifts?updated_since=2026-10-05T22:00:00Z&include_archived=true" \
-H "Authorization: Bearer ..."Date ranges
Shifts, timesheets, leave requests and availability take from and to as calendar dates. The range is inclusive and is resolved in each location's timezone, so from=2026-10-05 means midnight in Sydney for a Sydney location and midnight in Perth for a Perth one. A range may cover up to 92 days; a longer one is refused with range_too_long.
Filter by location_id to read one location, or by employee_id for one person. See Times, dates and timezones for how timestamps and dates differ.
Archived records
Shiftly archives rather than deletes. A deleted shift, an ended employment or a cancelled leave request is still there with archived set to true, and is left out of lists unless you send include_archived=true. Reading one by id always works.
What can go wrong
| You see | Why | What to do |
|---|---|---|
| 400 invalid_request naming after | The cursor is malformed or came from a different query. | Start from the first page. |
| 400 invalid_request naming a parameter | An unknown or misspelt query parameter. | The reference lists each resource's parameters. |
| 400 range_too_long | from and to span more than 92 days. | Split the range. |
