Skip to content

Get a rotation's projected schedule

GET
/v1/rotations/{rotationId}/schedule
curl --request GET \
--url 'https://api.roundrobinbot.eu/v1/rotations/example/schedule?from=2026-04-15T12%3A00%3A00Z&to=2026-04-15T12%3A00%3A00Z' \
--header 'Authorization: Bearer <token>'

The shifts the rotation’s rules produce inside a window you name. from and to are both required and no more than 90 days apart. No ETag: the answer is computed forward from the rules and the clock, so no stored version stands behind it.

rotationId
required
string
from
required
string format: date-time
to
required
string format: date-time
page
integer format: int32
pageSize
integer format: int32
sort
string

OK

Media typeapplication/json

The envelope every /v1 collection comes back in.

object
data
Array<object>

One shift in a rotation’s projected schedule.

object
cellId

Which place in the grid this shift fills, and the lane and window that cross there.

null | string
end

When it ends, or null for a shift with no computed end (a manual rotation waiting to be advanced by hand).

null | string format: date-time
laneId
null | string
laneName
null | string
rosterId

The list this shift was dealt from, where the grid names one.

null | string
skippedForAbsence

Members the plan would otherwise have named, passed over because they were absent. The userId above is who holds the shift instead.

Array<object>

A member skipped because of an absence at assignment time.

object
from

Absence start in UTC, when known.

null | string format: date-time
source

Absence source: googleCalendar or internalAvailability. Null when the source is unknown.

null | string
until

Absence end in UTC, when known.

null | string format: date-time
userId

Slack user ID of the skipped member.

string
source

Either scheduled, when the rotation’s own rules produced this shift, or manual, when somebody put a person on it by hand. There is no third value.

string
start

When the shift starts.

string format: date-time
turn

Their position in the turn order of the list this shift was dealt from.

integer format: int32
userId

The Slack user id of whoever actually holds the shift.

string
windowId
null | string
windowName
null | string
page
integer format: int32
pageSize
integer format: int32
totalItems
integer format: int64
totalPages
integer format: int32
Examplegenerated
{
"data": [
{
"cellId": "example",
"end": "2026-04-15T12:00:00Z",
"laneId": "example",
"laneName": "example",
"rosterId": "example",
"skippedForAbsence": [
{
"from": "2026-04-15T12:00:00Z",
"source": "example",
"until": "2026-04-15T12:00:00Z",
"userId": "example"
}
],
"source": "example",
"start": "2026-04-15T12:00:00Z",
"turn": 1,
"userId": "example",
"windowId": "example",
"windowName": "example"
}
],
"page": 1,
"pageSize": 1,
"totalItems": 1,
"totalPages": 1
}

Bad Request

Media typeapplication/json
object
detail
null | string
instance
null | string
status
null | integer format: int32
title
null | string
type
null | string
Examplegenerated
{
"detail": "example",
"instance": "example",
"status": 1,
"title": "example",
"type": "example"
}

Unauthorized

Media typeapplication/json
object
detail
null | string
instance
null | string
status
null | integer format: int32
title
null | string
type
null | string
Examplegenerated
{
"detail": "example",
"instance": "example",
"status": 1,
"title": "example",
"type": "example"
}

Forbidden

Media typeapplication/json
object
detail
null | string
instance
null | string
status
null | integer format: int32
title
null | string
type
null | string
Examplegenerated
{
"detail": "example",
"instance": "example",
"status": 1,
"title": "example",
"type": "example"
}

Not Found

Media typeapplication/json
object
detail
null | string
instance
null | string
status
null | integer format: int32
title
null | string
type
null | string
Examplegenerated
{
"detail": "example",
"instance": "example",
"status": 1,
"title": "example",
"type": "example"
}