Skip to content

Preview a swap request

POST
/v1/rotations/{rotationId}/swap-requests/preview
curl --request POST \
--url https://api.roundrobinbot.eu/v1/rotations/example/swap-requests/preview \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/*+json' \
--data '{ "acknowledgedConflictIds": [ "example" ], "legs": [ { "cellId": "example", "from": "2026-04-15T12:00:00Z", "holderUserId": "example", "key": "example", "to": "2026-04-15T12:00:00Z" } ], "operationId": "example", "reason": "example", "recipientUserId": "example" }'

Requires a Slack member access token. API keys are refused. Returns the proposed intervals and rotation ETag without changing duty or creating a request.

rotationId
required
string

Two full future shifts to exchange with another Slack member in the same rotation.

object
acknowledgedConflictIds

Current conflict identifiers acknowledged for the interval this caller would receive.

Array<string>
legs

Exactly two full shifts: one held by the requester and one held by the recipient. Both must start after the current time.

Array<object>

One duty interval offered by a swap participant.

object
cellId

The cell identifier from the rotation plan.

string
from

The full shift’s inclusive start, with UTC offset zero. Must be after the current time when proposing a swap.

string format: date-time
holderUserId

The Slack user identifier of the person who holds this interval.

string
key

A nonempty identifier unique to this interval within the request.

string
to

The full shift’s exclusive end, with UTC offset zero. Must be no more than six months after the current time.

string format: date-time
operationId

A caller-generated identifier of at most 128 characters. Reuse it only for an identical retry.

string
reason

An optional explanation of at most 2000 characters. Use an empty string to omit it.

string
recipientUserId

The other participant’s Slack user identifier. Must differ from the requester.

string
Examplegenerated
{
"acknowledgedConflictIds": [
"example"
],
"legs": [
{
"cellId": "example",
"from": "2026-04-15T12:00:00Z",
"holderUserId": "example",
"key": "example",
"to": "2026-04-15T12:00:00Z"
}
],
"operationId": "example",
"reason": "example",
"recipientUserId": "example"
}

OK

Media typeapplication/json

The proposed assignments and whether conflict acknowledgments and remaining-time consent permit proceeding.

object
canProceed
required

Whether conflict acknowledgments and remaining-time consent permit proceeding.

boolean
legs
required

The proposed assignments.

Array<object>

One proposed assignment and its conflicts. canAcknowledge identifies conflicts this caller may acknowledge. When hasStarted is true, from and to describe the remaining time; accepting requires its key in acknowledgedStartedLegKeys.

object
acknowledged
boolean
assigneeUserId
required
string
canAcknowledge
required
boolean
conflicts
required
Array<object>

A conflict or an uncertainty affecting the proposed assignment.

object
canAcknowledge
required

Whether explicit acknowledgment permits proceeding with this conflict. False means the conflict blocks the write.

boolean
from
required

The inclusive UTC start of the conflict intersection with the requested interval.

string format: date-time
id
required

The acknowledgment identifier for this conflict and the previewed terms.

string
source
required

arrangement, manualAvailability, googleCalendar or slackStatus.

string
to
required

The exclusive UTC end of the conflict intersection with the requested interval.

string format: date-time
type
required

absence, sameCellArrangement or unknownAvailability.

string
userId
required

The affected person’s Slack user identifier.

string
from
required
string format: date-time
hasStarted
boolean
key
required
string
to
required
string format: date-time
oneClick

Set on an acceptance preview and null on a proposal preview.

null | string
Example
{
"legs": [
{
"acknowledged": false,
"hasStarted": false
}
]
}