Skip to content

Get who is on call

GET
/v1/rotations/{rotationId}/on-call
curl --request GET \
--url https://api.roundrobinbot.eu/v1/rotations/example/on-call \
--header 'Authorization: Bearer <token>'

Who holds the shift right now, in one call. Add ?expand=users to side-load the directory record for everybody the answer names, which saves a lookup per person but drops the ETag: the directory is not covered by the rotation’s version.

rotationId
required
string
expand
string

OK

Media typeapplication/json

Current on-call assignments for a rotation. Responses with externalAssignments have no ETag; read the assignment freshness and coverage fields on each response.

object
externalAssignments
One of:
null
rotationId

Rotation ID.

string
onCall

Current mapped Slack assignments. An empty list does not establish a coverage gap: check externalAssignments or unmappedExternalDuty.

Array<object>

One current mapped Slack assignment. A user can appear more than once when they hold multiple assignments.

object
userId

Slack user ID of the person on duty.

string
turn

Position in the native turn order. External assignments have no native turn order.

integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
cellId

Cell holding this assignment.

null | string
laneId

Lane containing the cell. Lanes for external assignments do not identify provider roles.

null | string
laneName

Lane name, when available.

null | string
windowId

Window containing the cell. External assignment windows do not define provider recurrence.

null | string
windowName

Window name, when available.

null | string
since

Assignment start in UTC, when known.

null | string format: date-time
until

Exclusive assignment end in UTC, when known.

null | string format: date-time
skippedForAbsence

Members skipped for absence when this assignment began.

Array<object>

A member skipped because of an absence at assignment time.

object
userId

Slack user ID of the skipped member.

string
from

Absence start in UTC, when known.

null | string format: date-time
until

Absence end in UTC, when known.

null | string format: date-time
source

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

null | string
unmappedExternalDuty
One of:
null
users

Directory records for current mapped Slack users and skipped members when ?expand=users is requested. Null otherwise. Expansion disables ETag validation.

Array<object> | null

A Slack user, as Round Robin knows them.

object
id

The Slack user id.

string
teamId

The workspace that owns this person’s directory entry, which under Enterprise Grid can differ from the calling key’s workspace.

string
displayName
null | string
realName
null | string
email

Null when the install was never granted users:read.email, not only when unknown.

null | string
isGuest
boolean
isExternal

A Slack Connect person: visible through a shared channel, never a member of the workspace.

boolean
isDeleted

Deactivated in Slack, or gone from the workspace. These people are still answered rather than hidden, so an id a rotation still names resolves to something you can render.

boolean
avatarUrl

The person’s Slack avatar, at 192px.

null | string
timeZone

The person’s Slack time zone, as an IANA identifier (Europe/Rome). Absent when Round Robin has not seen one for them.

null | string
Examplegenerated
{
"externalAssignments": {
"asOfUtc": "2026-04-15T12:00:00Z",
"state": "example",
"coverage": "example",
"lastSuccessfulReadUtc": "2026-04-15T12:00:00Z",
"lastReadFailureUtc": "2026-04-15T12:00:00Z",
"knownFromUtc": "2026-04-15T12:00:00Z",
"knownUntilUtc": "2026-04-15T12:00:00Z",
"current": [
{
"localAssignmentId": "example",
"cellId": "example",
"user": "example",
"externalName": "example",
"externalEmail": "example",
"sinceUtc": "2026-04-15T12:00:00Z",
"untilUtc": "2026-04-15T12:00:00Z",
"externalAssignment": {
"memberKind": "example",
"participantId": "example",
"sourceType": "example",
"rotationId": "example",
"shiftId": "example",
"overrideId": "example",
"originalStartUtc": "2026-04-15T12:00:00Z",
"originalEndUtc": "2026-04-15T12:00:00Z"
}
}
],
"requiredAssignmentCount": 1,
"assignedAssignmentCount": 1,
"lastReadFailure": "example",
"distinctResponderCount": 1,
"distinctParticipantCount": 1,
"unmappedAssignmentCount": 1,
"emptyAssignmentCount": 1,
"nextChange": {
"atUtc": "2026-04-15T12:00:00Z",
"starting": [
{
"localAssignmentId": "example",
"cellId": "example",
"user": "example",
"externalName": "example",
"externalEmail": "example",
"sinceUtc": "2026-04-15T12:00:00Z",
"untilUtc": "2026-04-15T12:00:00Z",
"externalAssignment": {
"memberKind": "example",
"participantId": "example",
"sourceType": "example",
"rotationId": "example",
"shiftId": "example",
"overrideId": "example",
"originalStartUtc": "2026-04-15T12:00:00Z",
"originalEndUtc": "2026-04-15T12:00:00Z"
}
}
],
"continuing": [
{
"localAssignmentId": "example",
"cellId": "example",
"user": "example",
"externalName": "example",
"externalEmail": "example",
"sinceUtc": "2026-04-15T12:00:00Z",
"untilUtc": "2026-04-15T12:00:00Z",
"externalAssignment": {
"memberKind": "example",
"participantId": "example",
"sourceType": "example",
"rotationId": "example",
"shiftId": "example",
"overrideId": "example",
"originalStartUtc": "2026-04-15T12:00:00Z",
"originalEndUtc": "2026-04-15T12:00:00Z"
}
}
],
"ending": [
{
"localAssignmentId": "example",
"cellId": "example",
"user": "example",
"externalName": "example",
"externalEmail": "example",
"sinceUtc": "2026-04-15T12:00:00Z",
"untilUtc": "2026-04-15T12:00:00Z",
"externalAssignment": {
"memberKind": "example",
"participantId": "example",
"sourceType": "example",
"rotationId": "example",
"shiftId": "example",
"overrideId": "example",
"originalStartUtc": "2026-04-15T12:00:00Z",
"originalEndUtc": "2026-04-15T12:00:00Z"
}
}
]
}
},
"rotationId": "example",
"onCall": [
{
"userId": "example",
"turn": 1,
"cellId": "example",
"laneId": "example",
"laneName": "example",
"windowId": "example",
"windowName": "example",
"since": "2026-04-15T12:00:00Z",
"until": "2026-04-15T12:00:00Z",
"skippedForAbsence": [
{
"userId": "example",
"from": "2026-04-15T12:00:00Z",
"until": "2026-04-15T12:00:00Z",
"source": "example"
}
]
}
],
"unmappedExternalDuty": {
"email": "example",
"name": "example",
"until": "2026-04-15T12:00:00Z"
},
"users": [
{
"id": "example",
"teamId": "example",
"displayName": "example",
"realName": "example",
"email": "example",
"isGuest": true,
"isExternal": true,
"isDeleted": true,
"avatarUrl": "example",
"timeZone": "example"
}
]
}

Bad Request

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Unauthorized

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Forbidden

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Not Found

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}