Maintenance Windows
Maintenance Windows let you define scheduled time periods during which alerts, patching, automations, and script execution are selectively suppressed for targeted devices. This prevents false-positive alerts and unwanted automated actions during planned work such as server reboots, firmware upgrades, or infrastructure migrations.
The system supports two sources for maintenance settings. Configuration Policies are the primary mechanism, resolved through the multi-tenant hierarchy (partner, organization, site, device group, device). Standalone maintenance windows are the legacy approach that targets devices by explicit ID lists, site IDs, or group IDs. When both exist, configuration policy settings are checked first; standalone windows serve as a backward-compatible fallback.
All maintenance window operations are audit-logged, and every create, update, cancel, and delete action records the actor, resource, and change details.
A standalone maintenance window can also be created partner-wide so it applies to devices across every organization the partner manages – see Partner-wide Windows below.
Key Concepts
Section titled “Key Concepts”Window Statuses
Section titled “Window Statuses”| Status | Meaning |
|---|---|
scheduled |
The window is defined but its start time has not yet been reached |
active |
The window is currently in effect; suppression rules are being enforced |
completed |
The window’s end time has passed and normal operations have resumed |
cancelled |
The window was manually cancelled before or during execution |
Recurrence Types
Section titled “Recurrence Types”| Recurrence | Behavior |
|---|---|
once |
Runs a single time between the specified start and end times |
daily |
Repeats every N days (default interval: 1) |
weekly |
Repeats every N weeks, optionally on specific days of the week |
monthly |
Repeats every N months, optionally pinned to a specific day of the month |
custom |
Uses a custom interval; defaults to weekly cadence if no specific rule is provided |
Suppression Flags
Section titled “Suppression Flags”Each maintenance window controls four independent suppression toggles:
| Flag | Default | Effect |
|---|---|---|
suppressAlerts |
true |
Skips alert evaluation for devices in the window. Alerts that would otherwise fire are silently dropped. |
suppressPatching |
true (standalone) / false (config policy) |
Prevents patch jobs from being created or dispatched to affected devices. |
suppressAutomations |
false |
Blocks both scheduled and event-triggered automations from running on affected devices. |
suppressScripts |
false |
Prevents ad-hoc script execution on affected devices. |
Target Types
Section titled “Target Types”Standalone maintenance windows use a targetType field to determine which devices are affected:
| Target Type | Scope |
|---|---|
all |
Every device in the organization |
site |
Devices belonging to one or more specified sites (via siteIds) |
group |
Devices belonging to one or more specified device groups (via groupIds) |
device |
Specific devices by ID (via deviceIds) |
Creating a Maintenance Window
Section titled “Creating a Maintenance Window”Via Configuration Policy (Recommended)
Section titled “Via Configuration Policy (Recommended)”Configuration policies attach maintenance settings through the standard policy hierarchy. A maintenance feature link on a configuration policy carries a single settings row that defines the recurrence, duration, timezone, and suppression flags.
The configuration policy approach inherits from the hierarchy resolution system: a maintenance setting assigned at the device level overrides one at the device group level, which overrides site, organization, and partner levels. The closest (most specific) assignment wins.
The config_policy_maintenance_settings table stores:
| Field | Type | Description |
|---|---|---|
recurrence |
varchar(20) |
One of once, daily, weekly, monthly |
durationHours |
integer |
How long the window lasts from its computed start time |
timezone |
varchar(100) |
IANA timezone identifier (e.g., America/New_York). Defaults to UTC. |
windowStart |
varchar(30) |
ISO-8601 datetime for once recurrence only (e.g., 2026-03-15T02:00:00). Ignored for other recurrence types. |
suppressAlerts |
boolean |
Default: true |
suppressPatching |
boolean |
Default: false |
suppressAutomations |
boolean |
Default: false |
suppressScripts |
boolean |
Default: false |
rebootIfPending |
boolean |
Reboot devices that already have a reboot outstanding once the window opens. Default: false. See Rebooting Devices with a Pending Reboot below. |
notifyBeforeMinutes |
integer |
Minutes before the window opens to send a notification. Default: 15. |
notifyOnStart |
boolean |
Send a notification when the window becomes active. Default: true. |
notifyOnEnd |
boolean |
Send a notification when the window closes. Default: true. |
Via Standalone API (Legacy)
Section titled “Via Standalone API (Legacy)”-
Choose your targets. Decide whether the window applies to
alldevices, specificsiteIDs,groupIDs, or individualdeviceIDs. -
Define the schedule. Set the
startTimeandendTimeas ISO-8601 datetimes. TheendTimemust be afterstartTime(enforced by validation). Specify atimezonestring and arecurrencetype. -
Configure suppression. Set
suppressAlerts,suppressPatches, andsuppressAutomationsto control which actions are paused. -
Set notifications. Optionally set
notifyBefore(minutes before start),notifyOnStart, andnotifyOnEnd. -
Submit the request. POST to
/maintenance/windows. The system creates the window and auto-generates up to 10 upcoming occurrences based on the recurrence rule.
POST /maintenance/windows{ "orgId": "uuid", "name": "Weekend Server Maintenance", "description": "Routine weekend patching window", "startTime": "2026-03-01T02:00:00Z", "endTime": "2026-03-01T06:00:00Z", "timezone": "America/Chicago", "recurrence": "weekly", "recurrenceRule": { "interval": 1, "daysOfWeek": [0, 6] }, "targetType": "site", "siteIds": ["site-uuid-1", "site-uuid-2"], "suppressAlerts": true, "suppressPatches": true, "suppressAutomations": false, "notifyBefore": 30, "notifyOnStart": true, "notifyOnEnd": true}The response returns the created window object with a 201 status code.
Partner-wide Windows (All organizations)
Section titled “Partner-wide Windows (All organizations)”A standalone maintenance window is normally owned by a single organization (orgId). A partner-scoped user with access to every organization can instead create it as partner-wide, so the same window suppresses alerts, patching, automations, and scripts for devices in every organization under the partner – useful for MSP-wide work like a shared patch-management provider outage window.
To create a partner-wide window, submit "ownerScope": "partner" instead of orgId in the create request. Ownership is set at creation time only – it cannot be changed on update. Creating, updating, cancelling, or deleting a partner-wide window (and modifying its occurrences) requires partner-wide management access.
Scheduling: One-Time vs Recurring
Section titled “Scheduling: One-Time vs Recurring”One-Time Windows
Section titled “One-Time Windows”Set recurrence to once. The window runs exactly once between startTime and endTime. A single occurrence record is generated.
For configuration policy maintenance settings, set the windowStart field to the desired ISO-8601 datetime. The window lasts for durationHours from that point.
Recurring Windows
Section titled “Recurring Windows”For recurring windows, the system generates occurrence records automatically. Standalone windows pre-generate up to 10 upcoming occurrences at creation time, bounded by the optional maxOccurrences and endDate fields in the recurrence rule.
Recurrence rule fields (standalone windows):
| Field | Type | Description |
|---|---|---|
interval |
integer |
Number of periods between occurrences. Default: 1. |
daysOfWeek |
integer[] |
For weekly recurrence: array of day numbers (0=Sunday through 6=Saturday). |
dayOfMonth |
integer |
For monthly recurrence: day of the month (1-31). Clamped to the last day if the month is shorter. |
endDate |
ISO-8601 string |
Stop generating occurrences after this date. |
maxOccurrences |
integer |
Maximum number of occurrences to generate. |
Configuration policy recurrence works differently. The recurrence type determines when the window starts relative to the current time in the configured timezone:
| Recurrence | Window Start |
|---|---|
daily |
Midnight (00:00) in the configured timezone, every day |
weekly |
Midnight on the most recent Sunday in the configured timezone |
monthly |
Midnight on the 1st of the current month in the configured timezone |
The window remains active for durationHours from its computed start time.
Timezone Handling
Section titled “Timezone Handling”Both standalone windows and configuration policy settings store a timezone field as an IANA timezone identifier (e.g., America/New_York, Europe/London, Asia/Tokyo). The default is UTC.
For configuration policy maintenance, the system converts the current UTC time to the configured timezone using Intl.DateTimeFormat before computing whether the window is active. This means a daily window with timezone America/Chicago and durationHours: 4 is active from midnight to 04:00 Central time, regardless of the server’s timezone.
For standalone windows, startTime and endTime are stored as UTC timestamps. The timezone field is stored for display and informational purposes; the actual window boundaries are determined by the UTC timestamps.
Alert Suppression Behavior
Section titled “Alert Suppression Behavior”When a device is in an active maintenance window with suppressAlerts set to true, alert evaluation is skipped entirely for that device. This applies to both alert sources:
-
Configuration policy alert rules (
evaluateDeviceAlertsFromPolicy): Before evaluating any alert rules, the system resolves the device’s maintenance configuration. If a maintenance window is active withsuppressAlerts: true, the function returns immediately without creating any alerts. -
Standalone alert rules: The
isDeviceInMaintenanceservice function is called during alert processing. If it returnsactive: truewithsuppressAlerts: true, alerts are not generated.
Alerts that occur during the maintenance window are not queued or deferred – they are silently dropped. If the underlying condition persists after the window closes, the next evaluation cycle will detect it and create the alert at that time.
Automation and Patching Suppression
Section titled “Automation and Patching Suppression”Automations
Section titled “Automations”The automation worker checks maintenance status before executing any automation on a device. This check applies to both scheduled (cron-based) and event-triggered automations:
-
For scheduled automations, the worker resolves maintenance config for each target device. Devices with an active window where
suppressAutomationsistrueare excluded from the run. If all target devices are in maintenance, the job returns{ skipped: 'all_devices_in_maintenance' }. -
For event-triggered automations, each device is checked individually before queuing the automation. If the device is in an active maintenance window with automation suppression, the event-triggered automation is silently skipped for that device.
The maintenance check follows a fail-closed policy: if the maintenance status lookup fails for a device (e.g., due to a database error), the device is excluded from the automation run rather than risk executing during an unverifiable maintenance window.
Patching
Section titled “Patching”The patch job service checks checkDeviceMaintenanceWindow() before creating a patch job for a device. If the device is in an active maintenance window with suppressPatching: true, the function returns null and no patch job is created.
Rebooting Devices with a Pending Reboot
Section titled “Rebooting Devices with a Pending Reboot”Some changes – a patch install, an application update, an OS feature update – leave a device with a reboot outstanding until someone (or something) restarts it. Maintenance windows can close that gap automatically: enable Reboot if a reboot is pending on a configuration policy’s Maintenance settings (under Actions During Window), and Breeze reboots any qualifying device that’s sitting with a pending reboot once its window opens.
How it works
Section titled “How it works”A periodic check runs every 10 minutes, independent of any individual window’s start time. On each pass it looks for devices that are:
- Reporting a pending reboot – the device already needs a restart, regardless of what caused it (a patch, an app install, a policy change, etc.), and
- Currently online, and
- Inside a maintenance window whose configuration policy has Reboot if a reboot is pending enabled
Matching devices are rebooted right away – Breeze doesn’t wait for the window to close first.
Platform behavior
Section titled “Platform behavior”Breeze issues a scheduled reboot with a 15-minute grace period. The signed-in user gets a “save your work” warning about 5 minutes before the reboot fires.
Breeze schedules the reboot 15 minutes out (equivalent to running shutdown -r +15), which also warns any logged-in users.
Not supported. Breeze cannot detect a pending-reboot state on macOS, so macOS devices are never rebooted by this feature – reboot them manually or through a script instead.
Avoiding repeat reboots
Section titled “Avoiding repeat reboots”Once a reboot has been issued to a device, that device is skipped for 60 minutes, even if it still shows a pending reboot on a later check. This keeps a single outstanding reboot from being re-triggered several times in a row while the device works through it or while the window remains open.
Active Window Detection
Section titled “Active Window Detection”Per-Device Status Check
Section titled “Per-Device Status Check”Query the resolved maintenance status for a specific device:
GET /maintenance/device/:deviceId/statusThis endpoint resolves maintenance status using the unified isDeviceInMaintenance function, which checks in order:
-
Configuration Policy path: Resolves the device’s maintenance settings through the hierarchy (device > device group > site > organization > partner). If an active configuration policy maintenance window is found, its suppression flags are returned with
source: "config_policy". -
Standalone window fallback: Queries the
maintenance_windowstable for any window that isscheduledoractive, whose time range includes the current moment, and whose target (bytargetType,deviceIds,siteIds, orgroupIds) includes the device. This match includes both windows owned by the device’s own organization and any partner-wide window owned by that organization’s partner. Returns withsource: "standalone". -
No active window: Returns
active: falsewithsource: "none"and all suppression flags set tofalse.
Response:
{ "data": { "deviceId": "uuid", "active": true, "source": "config_policy", "suppressAlerts": true, "suppressPatching": false, "suppressAutomations": false, "suppressScripts": false }}Active Windows Query
Section titled “Active Windows Query”List all currently active maintenance windows for an organization, optionally filtered by a specific device, site, or group:
GET /maintenance/active?orgId=uuid&deviceId=uuidQuery parameters are all optional (except orgId for partner/system scope):
| Parameter | Description |
|---|---|
orgId |
Organization to query (required for partner and system scopes) |
deviceId |
Filter to windows affecting this specific device |
siteId |
Filter to windows affecting this specific site |
groupId |
Filter to windows affecting this specific device group |
The endpoint finds occurrences that are either explicitly active or scheduled with their time range encompassing the current moment. Results include the parent window’s suppression flags.
Device Maintenance Mode
Section titled “Device Maintenance Mode”In addition to scheduled maintenance windows, individual devices can be placed into maintenance mode manually:
POST /devices/:id/maintenance{ "enable": true, "durationHours": 4}This sets the device status to maintenance (or back to online when enable is false). The durationHours field accepts a positive integer up to 168 (one week). Decommissioned devices cannot be placed into maintenance mode.
Occurrences
Section titled “Occurrences”Standalone maintenance windows generate occurrence records that represent individual instances of the window. Each occurrence tracks its own status, actual start/end times, and optional overrides or notes.
Listing Occurrences
Section titled “Listing Occurrences”For a specific window:
GET /maintenance/windows/:id/occurrencesReturns all occurrences for the window, ordered by start time ascending.
Across all windows (calendar view):
GET /maintenance/occurrences?orgId=uuid&from=2026-03-01T00:00:00Z&to=2026-03-31T23:59:59Z| Parameter | Description |
|---|---|
orgId |
Organization to query |
status |
Filter by occurrence status (scheduled, active, completed, cancelled) |
from |
Return occurrences starting at or after this time |
to |
Return occurrences ending at or before this time |
Each occurrence in the response includes its parent window’s id, name, and targetType.
Modifying an Occurrence
Section titled “Modifying an Occurrence”Individual occurrences can be adjusted without changing the parent window:
PATCH /maintenance/occurrences/:id{ "startTime": "2026-03-01T03:00:00Z", "endTime": "2026-03-01T07:00:00Z", "notes": "Delayed by 1 hour due to vendor schedule"}Time changes are stored as overrides on the occurrence record, preserving the original schedule from the parent window.
Manual Start and End
Section titled “Manual Start and End”Start an occurrence early or end one before its scheduled time:
POST /maintenance/occurrences/:id/startSets the occurrence status to active and records the actualStartTime. The occurrence must be in scheduled status.
POST /maintenance/occurrences/:id/endSets the occurrence status to completed and records the actualEndTime. The occurrence must be in active status.
API Reference
Section titled “API Reference”All routes are mounted under /maintenance and require authentication. Scope requirements are organization, partner, or system.
Maintenance Windows
Section titled “Maintenance Windows”| Method | Path | Description |
|---|---|---|
GET |
/maintenance/windows |
List windows for an organization. Supports status and targetType query filters. |
POST |
/maintenance/windows |
Create a new maintenance window with occurrences. Set ownerScope: "partner" (instead of orgId) for a partner-wide window. (Deprecated – use configuration policies.) |
GET |
/maintenance/windows/:id |
Get window details including the next 10 upcoming occurrences. |
PATCH |
/maintenance/windows/:id |
Update window properties. (Deprecated.) |
DELETE |
/maintenance/windows/:id |
Delete a window. Future occurrences are removed; past occurrences are preserved for audit. (Deprecated.) |
POST |
/maintenance/windows/:id/cancel |
Cancel a window and all its future occurrences. Already-cancelled windows return a 400 error. (Deprecated.) |
Occurrences
Section titled “Occurrences”| Method | Path | Description |
|---|---|---|
GET |
/maintenance/windows/:id/occurrences |
List all occurrences for a specific window. |
GET |
/maintenance/occurrences |
List occurrences across all windows with date range and status filters. |
PATCH |
/maintenance/occurrences/:id |
Update an occurrence’s start time, end time, or notes. (Deprecated.) |
POST |
/maintenance/occurrences/:id/start |
Manually start a scheduled occurrence early. (Deprecated.) |
POST |
/maintenance/occurrences/:id/end |
Manually end an active occurrence early. (Deprecated.) |
Device Status
Section titled “Device Status”| Method | Path | Description |
|---|---|---|
GET |
/maintenance/device/:deviceId/status |
Resolve the current maintenance status for a device (checks config policy first, then standalone windows). |
GET |
/maintenance/active |
List currently active maintenance windows, optionally filtered by device, site, or group. |
POST |
/devices/:id/maintenance |
Toggle device-level maintenance mode (separate from maintenance windows). |
Troubleshooting
Section titled “Troubleshooting”Device shows as not in maintenance despite an active window
Section titled “Device shows as not in maintenance despite an active window”-
Check the source. Call
GET /maintenance/device/:deviceId/statusto see which source is being evaluated. Ifsourceis"none", neither configuration policy nor standalone windows matched. -
Verify the target. For standalone windows, confirm the device’s ID is in the window’s
deviceIdsarray, or its site ID is insiteIds, or one of its group memberships is ingroupIds. Windows withtargetType: "all"affect every device in the organization. -
Check the timezone. For configuration policy maintenance settings, the active window is computed in the configured timezone. A window set to
America/New_Yorkwithdailyrecurrence anddurationHours: 4is active from midnight to 04:00 ET, not UTC. -
Check hierarchy resolution. Configuration policy settings follow the standard hierarchy. A device-level assignment overrides site-level settings. Use the device status endpoint to see which policy won.
Alerts still firing during a maintenance window
Section titled “Alerts still firing during a maintenance window”- Confirm
suppressAlertsis set totrueon the maintenance window or configuration policy maintenance settings. - The
allowedAlertSeveritiesfield on standalone windows can let certain severity levels pass through even when suppression is enabled. - Alert suppression only applies to new alerts evaluated during the window. Alerts that were already open before the window started are not retroactively suppressed or resolved.
Automations running during maintenance
Section titled “Automations running during maintenance”- Verify
suppressAutomationsistrue. This flag defaults tofalse, so it must be explicitly enabled. - The automation worker uses a fail-closed policy: if the maintenance check itself fails (database error, etc.), the device is excluded from the run. Check logs for
Maintenance check failed for devicewarnings.
Patches deploying during maintenance
Section titled “Patches deploying during maintenance”- Verify
suppressPatchingistrueon the effective maintenance settings. - In configuration policies,
suppressPatchingdefaults tofalse. It must be explicitly set. - In standalone windows, the field is named
suppressPatchesin the API request body and maps tosuppressPatchingin the database.
Invalid timezone fallback
Section titled “Invalid timezone fallback”If the timezone field contains an invalid IANA timezone string, the system logs a warning (Invalid timezone "...", falling back to UTC) and evaluates the window in UTC. Correct the timezone in the maintenance settings to restore intended behavior.
Device with a pending reboot isn’t rebooting during the window
Section titled “Device with a pending reboot isn’t rebooting during the window”- Confirm Reboot if a reboot is pending is enabled on the configuration policy’s Maintenance settings – it defaults to off.
- This feature only applies to configuration-policy maintenance windows. Legacy standalone maintenance windows don’t support it.
- The device must be online and reporting a pending reboot at the time of a check. Checks run roughly every 10 minutes, so allow a few minutes after the window opens.
- macOS devices are never rebooted by this feature – see Rebooting Devices with a Pending Reboot.
- If a reboot was already issued to the device in the last 60 minutes, it’s skipped to avoid re-triggering – check the device’s command history for a recent reboot command before assuming the feature isn’t working.
- This is unrelated to the patch management
rebootPolicysetting – see the callout above for how the two differ.