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 application
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 application
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"). A host holds no windows at all: the schedule is declared on an app inside the galaxy, not on the host itself |
| 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 | WAKE_SCHEDULE_GALAXY_DISABLED |
The server is an app inside a galaxy (kind: "GALAXY_APP"). Such an app can hold windows, but the capability for Galaxy apps is not enabled yet. The capability is enabled separately from ordinary servers, so a kind: "STANDALONE" server never receives this code |
| 403 | INFRA_SCOPE_REQUIRED |
The key lacks the vibe:infra scope |
| 403 | INFRA_FORBIDDEN_FOR_COWORK_KEY |
The call was made with a Cowork/Code key — such a key works with data only and cannot perform write operations. To issue a key that can, see Project key for deploy |
| 403 | SERVER_ROLE_FORBIDDEN |
You are on this server's development team with the Developer role, and this operation is open to the Administrator role. error.hint carries your role, the required threshold and the list of calls that are open to you. Role breakdown — List servers |
| 404 | NOT_FOUND |
No window with that scheduleId exists on this server, or the server itself was not found, was deleted, or belongs to a different API key while you are not on its development team |
| 429 | RATE_LIMITED |
The 10-requests-per-minute limit for this endpoint was exceeded |
Full list of shared error codes — Errors.
Known specifics
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, andlabelandleadare cleared. 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' values — on a preemptible plan the platform does not forbid a schedule; it simply reports up front that waking the server in time for the window is best-effort. Localize by thepreemptibleAdvisoryCodevalue, not by 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. - Two different galaxy refusals.
GALAXY_NOT_SUPPORTEDis about the galaxy host: it holds no windows at all.WAKE_SCHEDULE_GALAXY_DISABLEDis about an app inside a galaxy: it can hold windows, but the capability for such apps is switched off for now — an already created window of such an app cannot be updated, and this code is what the update attempt returns. The first arrives with status400, the second with403.