On-Call API › Schedule layers
Add a layer
Adds a rotation layer. A layer runs its people in turn, handing over every
day or week from rotation_start (default: now; an unreadable value is
ignored). Restrict it to a shift — certain weekdays and a time window in the
schedule's timezone — with the three restrict_* fields; a window may cross
midnight. Leave them out for a layer that covers all day, every day.
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
On create name and rotation_type are required.
namestringpriorityintegerrotation_typeRotationTyperotation_startstring (date-time)Defaults to now on create.handoff_dayintegerhandoff_timestringHH:MMrestrict_to_weekdaysarray of integer0 is Sunday.restrict_start_timestringHH:MM; give the end too. Empty clears the window.restrict_end_timestringHH:MM; may be earlier than the start for a shift across midnight.
Responses
201
The layer.
dataScheduleLayer requiredShow ScheduleLayer properties
idstringschedule_idstringnamestringpriorityintegerLayers with a higher priority win over lower ones.rotation_typeRotationTyperotation_startstring (date-time)When the rota's first turn started.handoff_dayintegerWeekday of the handover for weekly rotas, 0 (Sunday) to 6.handoff_timestringHH:MMof the handover.restrict_to_weekdaysarray of integerrestrict_start_timestringHH:MMrestrict_end_timestringHH:MMrotationsarray of ScheduleRotationShow ScheduleRotation properties
idstringlayer_idstringuser_idstringpositioninteger0-based place in the rota.created_atstring (date-time)
created_atstring (date-time)updated_atstring (date-time)
successboolean required
400
The body is not JSON (INVALID_BODY); name or rotation_type is missing, a weekday is outside 0–6, or the shift window is incomplete or malformed (VALIDATION_FAILED).
errorobject requiredcodestring requiredmessagestring requireddetailsarray 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.
403
The key lacks the scope this endpoint needs (FORBIDDEN).
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.
404
No schedule with this id in your organization (NOT_FOUND).
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.
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.
500
Something went wrong on EvoHub's side (INTERNAL_ERROR). Retry later.
errorobject requiredcodestring requiredMachine-readable code. Branch on this.messagestring requiredHuman-readable explanation.
Example request
curl -X POST 'https://evohub.io/api/v1/schedules/5b1c7d2e-8f3a-4b9c-a0d1-e2f3a4b5c6d7/layers' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"name": "Business hours",
"handoff_day": 1,
"handoff_time": "09:00",
"rotation_type": "weekly",
"rotation_start": "2026-09-01T06:00:00Z",
"restrict_end_time": "18:00",
"restrict_start_time": "09:00",
"restrict_to_weekdays": [
1,
2,
3,
4,
5
]
}'