Preview a layer before adding it
The next six turns a layer would give, worked out on the schedule's
clock, without storing anything. Send the layer as you would to
POST /api/v1/schedules/{id}/layers, plus user_ids, the members in
rota order. name may be left out. With no user_ids the handovers are
still returned, each with an empty user_id. The turns start from
rotation_start when it lies in the future, otherwise from now. Each
turn runs from handover to handover; it is not cut to the shift window.
A schedule that belongs to a team is visible only to callers in that team (and to administrators acting in person); others get 404, as if it did not exist.
Permission (API-key scope): oncall:schedule:write.
Authorization
bearerAuth(oncall:schedule:write)apiKeyHeader(oncall:schedule:write)
Parameters
Path parameters
idstring requiredThe schedule's id.
Request body required
A whole layer as a form sends it — its settings and its members in rota order.
namestringpriorityintegerrotation_typeRotationTyperotation_unitstringWhathandoff_daycounts on acustomrotation;daywhen left out.rotation_startstring (date-time)handoff_dayintegerFor acustomrotation, the days (1–365) or hours (1–168) each turn lasts.handoff_weekdayintegerThe weekday aweeklyrotation hands over on, 0 (Sunday) to 6. Left out, it hands over on the weekdayrotation_startfalls on.handoff_timestringHH:MMon the schedule's clock.restrict_to_weekdaysarray of integerrestrict_start_timestringrestrict_end_timestringuser_idsarray of stringThe members in rota order, each once.
Responses
200
The next six turns.
dataobject requiredturnsarray of ScheduleTurn requiredShow ScheduleTurn properties
layer_idstringThe layer giving the turn (previewfor a layer that is not stored yet).user_idstringWho holds the turn; empty in a preview with no members.startstring (date-time)endstring (date-time)
successboolean required
400
The body is not JSON (INVALID_BODY), or a field is invalid as on create, or user_ids names someone twice or holds an empty id (VALIDATION_FAILED).
errorobject requiredcodestring requiredmessagestring requiredrequest_idstringThe request'sX-Request-ID. Quote it to support.detailsarray of object requiredfieldstringmessagestring
401
No API key was sent, or it is unknown, revoked or expired (UNAUTHORIZED).
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.request_idstringThe request'sX-Request-ID. Quote it to support.
403
The key lacks the scope this endpoint needs (FORBIDDEN).
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.request_idstringThe request'sX-Request-ID. Quote it to support.
404
No schedule with this id in your organization (NOT_FOUND).
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.request_idstringThe request'sX-Request-ID. Quote it to support.
429
Too many requests (RATE_LIMITED). Wait Retry-After seconds.
Retry-AfterintegerSeconds to wait.
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.request_idstringThe request'sX-Request-ID. Quote it to support.
500
Something went wrong on EvoHub's side (INTERNAL_ERROR). Retry later.
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.request_idstringThe request'sX-Request-ID. Quote it to support.
Example request
curl -X POST 'https://evohub.io/api/v1/schedules/5b1c7d2e-8f3a-4b9c-a0d1-e2f3a4b5c6d7/layers/preview' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"user_ids": [
"0b8e6c1a-2f4d-4e9b-8a7c-3d5e6f708192",
"9a7b5c3d-1e2f-4a6b-8c0d-2e4f6a8b0c1d"
],
"handoff_time": "09:00",
"rotation_type": "weekly",
"rotation_start": "2026-10-19T06:00:00Z",
"handoff_weekday": 1
}'
