For AI agents: markdown of this page — /docs-content-en/infra/wake-schedules/update.md documentation index — /llms.txt
Update a wake window
PATCH /v1/infra/servers/:id/wake-schedules/:scheduleId
Replaces the window in full — despite the PATCH method, the semantics match a full replacement (PUT). Omitted optional fields reset to their defaults instead of keeping their previous value: enabled → true, label/lead → empty. Send the complete window object, not just the field that changed.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (UUID) | yes | ID of the BLACKHOLE server |
scheduleId |
path | string | yes | Window ID, taken from data[].id in the window list or data.id from creating a window |
Request fields (body)
Same field set as creating a window. Omitted optional fields don't keep their old value — they reset to the default.
| Field | Type | Required | Default when omitted | Description |
|---|---|---|---|---|
cronExpr |
string | yes | — | A 5-field cron expression, 9 to 120 characters |
timezone |
string | yes | — | IANA timezone of the window |
label |
string | no | resets to empty | Window label, up to 80 characters |
lead |
number | no | resets to empty (the server's or the platform's margin is used) | Margin, in seconds, before the cronExpr moment. 0 to 3600 |
enabled |
boolean | no | resets to true |
Whether the window is active |
Examples
curl — personal key
curl -X PATCH "https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/wake-schedules/SCHEDULE_ID" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"cronExpr": "0 10 * * 1-5",
"timezone": "America/New_York",
"label": "daily report",
"enabled": true
}'
curl — OAuth app
curl -X PATCH "https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/wake-schedules/SCHEDULE_ID" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"cronExpr": "0 10 * * 1-5",
"timezone": "America/New_York",
"label": "daily report",
"enabled": true
}'
JavaScript — personal key
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/wake-schedules/${scheduleId}`,
{
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
// Full window object — fields omitted here reset to their defaults
body: JSON.stringify({
cronExpr: '0 10 * * 1-5',
timezone: 'America/New_York',
label: 'daily report',
enabled: true,
}),
}
)
JavaScript — OAuth app
const res = await fetch(
`https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/wake-schedules/${scheduleId}`,
{
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
cronExpr: '0 10 * * 1-5',
timezone: 'America/New_York',
label: 'daily report',
enabled: true,
}),
}
)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.id |
string | Window ID |
data.serverId |
string (UUID) | ID of the owning server |
data.cronExpr |
string | The updated cron expression |
data.timezone |
string | The updated timezone |
data.label |
string | null | Window label |
data.lead |
number | null | Margin in seconds |
data.enabled |
boolean | Whether the window is active after the update |
data.source |
string | How the window was created. Unaffected by an update |
data.lastFiredAt |
string (ISO 8601) | null | Timestamp of the last confirmed firing. An update doesn't touch this field |
data.wakeAttemptStartedAt |
string (ISO 8601) | null | Internal scheduler marker, normally null |
data.lastWakeLateAt |
string (ISO 8601) | null | Timestamp of the last late wake |
data.createdAt |
string (ISO 8601) | Record creation date |
data.updatedAt |
string (ISO 8601) | Date of this update |
tzWarning |
string | null | Timezone-mismatch advisory, as text. null when the server has no active windows left after this mutation |
tzWarningCode |
string | null | Machine-readable code for the same advisory: "SINGLE_ZONE", "MULTI_ZONE", or null |
preemptibleAdvisoryCode |
string | null | "PREEMPTIBLE_BEST_EFFORT" when the server runs on a preemptible plan — otherwise null |
preemptibleAdvisory |
string | null | An explanation of the same advisory, as text (in English, for non-UI API clients). null when the server is on a non-preemptible plan |
tzWarning, tzWarningCode, preemptibleAdvisoryCode, and preemptibleAdvisory are top-level response fields, not nested under data.
Response example
{
"success": true,
"data": {
"id": "cm38x02qp0001ml08g7k3h2a",
"serverId": "e765edfc-ba0a-43de-b8ea-838dd872c522",
"cronExpr": "0 10 * * 1-5",
"timezone": "America/New_York",
"label": "daily report",
"lead": null,
"enabled": true,
"source": "MANUAL",
"lastFiredAt": "2026-07-10T06:00:04.000Z",
"wakeAttemptStartedAt": null,
"lastWakeLateAt": null,
"createdAt": "2026-07-03T08:12:00.000Z",
"updatedAt": "2026-07-10T09:30:00.000Z"
},
"tzWarning": "The VM may have been deployed with a different timezone (or not redeployed since this window was declared) — verify the in-VM cron or redeploy the app so TZ is re-injected.",
"tzWarningCode": "SINGLE_ZONE",
"preemptibleAdvisoryCode": null,
"preemptibleAdvisory": null
}
A server on a preemptible plan would get "preemptibleAdvisoryCode": "PREEMPTIBLE_BEST_EFFORT" and a non-empty preemptibleAdvisory instead of null in those same two fields — the rest of the response shape is unchanged.
Error response example
404 — window not found:
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Wake window not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR |
Body validation failed — missing cronExpr/timezone, timezone not in the IANA timezone list, label over 80 characters, lead outside 0–3600, or an unknown field in the body |
| 400 | BLACKHOLE_ONLY |
The server is not in BLACKHOLE mode |
| 400 | GALAXY_NOT_SUPPORTED |
The server is a Galaxy host (kind: "GALAXY"). Nested apps (kind: "GALAXY_APP") are accepted — only the host itself is rejected |
| 400 | ALWAYS_ON_CONFLICT |
The server runs in always-on mode — no auto-sleep |
| 400 | CADENCE_TOO_LOW |
The gap between consecutive cronExpr occurrences is below the platform's floor — currently 5 minutes |
| 401 | MISSING_API_KEY |
The X-Api-Key header is missing |
| 401 | INVALID_API_KEY |
The API key is invalid or expired |
| 403 | WAKE_SCHEDULE_DISABLED |
Scheduled wake is not enabled for this portal |
| 403 | INFRA_SCOPE_REQUIRED |
The key lacks the vibe:infra scope |
| 404 | NOT_FOUND |
The server was not found/deleted/belongs to a different API key, or no window with that scheduleId exists on this server |
| 429 | RATE_LIMITED |
The 10-requests-per-minute limit for this endpoint was exceeded |
Full list of shared error codes — Errors.
Known behavior
PATCHreplaces the window in full. This is a departure from the general partial-PATCHstandard across the Vibecode API — compare with updating a deal, where omitted fields keep their previous value. Sending only the field that changed silently zeroes out the other optional fields —enabledbecomestrue,labelandleadclear out. Build the body from the window's last known full state, not just the fields that changed.preemptibleAdvisoryCode/preemptibleAdvisoryare an advisory, not a gate. The window is updated regardless of these fields' value — on a preemptible plan the platform does not forbid a schedule, it only honestly reports that waking by the window's moment is best-effort. Localize on thepreemptibleAdvisoryCodecode, not on thepreemptibleAdvisorystring — it is a fixed English string for non-UI clients.- Window existence is checked before the other gates. A non-existent
scheduleIdreturns404 NOT_FOUNDeven if the request also violatesBLACKHOLE_ONLYor another server-mode gate.