> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devhelm.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Maintenance Windows

> Suppress DevHelm alerts during planned deploys, migrations, and scheduled downtime

A **maintenance window** tells DevHelm "I expect these monitors to fail (or look weird) for a defined period — please don't page on-call." Use them around deploys, database migrations, scheduled provider maintenance, or any time you'd rather absorb a few minutes of red than wake someone up.

Maintenance windows are a **runtime state operation**, not a piece of infrastructure. You schedule them, you cancel them, they expire — like an incident, not like a monitor. That distinction shapes which surfaces support them.

## How they work

While a maintenance window is active for a monitor:

1. **Alert suppression** — notification policies are bypassed and no channels fire (when `suppressAlerts` is true, the default).
2. **Severity tagging** — any incident that opens during the window is created at severity `MAINTENANCE` instead of `DOWN` or `DEGRADED`.
3. **Monitoring continues** — checks still run, results are still recorded, and the timeline still tells the truth. Suppression silences the noise; it does not pause the data.

When the window ends — or you cancel it — alerting resumes immediately on the next failed check.

## Surface support (v1)

Maintenance windows are imperative state. They live behind the surfaces that operate on state — not the ones that describe infrastructure.

| Surface                                                | Supports maintenance windows? | Why                                                                                   |
| ------------------------------------------------------ | ----------------------------- | ------------------------------------------------------------------------------------- |
| REST API (`/api/v1/maintenance-windows`)               | Yes                           | Source of truth                                                                       |
| Dashboard UI                                           | Yes                           | Schedule from the monitor or org-wide                                                 |
| CLI imperative (`devhelm maintenance-windows ...`)     | Yes                           | Same as `devhelm incidents create` — a state operation                                |
| Python SDK (`client.maintenance_windows`)              | Yes                           | Same as `client.incidents`                                                            |
| JS / TS SDK (`client.maintenanceWindows`)              | Yes                           | Same as `client.incidents`                                                            |
| MCP server tools (`create_maintenance_window`, …)      | Yes                           | AI agents schedule them around deploys                                                |
| **Terraform provider**                                 | **No (intentional)**          | Windows are state, not infrastructure                                                 |
| **CLI declarative (`devhelm.yml` + `devhelm deploy`)** | **No (intentional)**          | Same — `devhelm.yml` describes monitors and channels, not transient operational state |

### Why not Terraform? Why not `devhelm.yml`?

Terraform and `devhelm.yml` are **declarative**: they describe the desired long-lived state of your monitoring stack — which monitors exist, what channels are wired up, who gets paged. A maintenance window is **transient operational state**, owned by whoever is performing the maintenance:

* Putting a maintenance window in Terraform would mean every deploy that schedules a window also generates a Git commit, a PR, an apply — for something that will be gone in 30 minutes.
* Putting one in `devhelm deploy` would mean the YAML diverges from the live state the moment the window opens, and `devhelm plan` would show it as drift.
* Worst of all, removing the window from the file (after the deploy succeeds) would *not* cancel an active window — `devhelm deploy` would interpret the absence as "the window doesn't exist yet" and re-create it on the next CI run.

The right tool for "schedule a window during my deploy" is the imperative one your deploy script can call directly: the CLI, an SDK, or the MCP tool. The right tool for "describe the monitors and channels I always want to exist" is `devhelm.yml` or Terraform. They don't compete; they cover different jobs.

If you need recurring maintenance (e.g., every Sunday 02:00 UTC), the API supports it with `repeatRule` (an iCal RRULE) — no Terraform required.

## Request fields

Both create (`POST /api/v1/maintenance-windows`) and update (`PUT /api/v1/maintenance-windows/{id}`) accept the same body:

| Field            | Type     | Required | Description                                                                                            |
| ---------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `monitorId`      | UUID     | No       | Single monitor to scope the window to. Omit (or `null`) for an org-wide window covering every monitor. |
| `startsAt`       | datetime | Yes      | When the window opens. ISO 8601 with explicit timezone (UTC preferred).                                |
| `endsAt`         | datetime | Yes      | When the window closes. Must be strictly after `startsAt`.                                             |
| `repeatRule`     | string   | No       | iCal RRULE for recurring windows (max 100 chars). Omit for one-time.                                   |
| `reason`         | string   | No       | Human-readable description shown in the dashboard and audit log.                                       |
| `suppressAlerts` | boolean  | No       | Default `true`. Set `false` to record the window for audit without silencing notifications.            |

Each window covers **one monitor or the entire organization** — there is no native "this list of monitors" form. To cover several specific monitors, schedule one window per monitor (the CLI's `--monitor` flag does this for you when you pass several IDs).

## Quick examples

<CodeGroup>
  ```bash CLI theme={null}
  devhelm maintenance-windows create \
    --start "2026-05-15T14:00:00Z" \
    --end "2026-05-15T14:30:00Z" \
    --reason "Quarterly DB upgrade" \
    --monitor <monitor-id>
  ```

  ```python Python SDK theme={null}
  from devhelm import Devhelm

  client = Devhelm()  # reads DEVHELM_API_TOKEN, org/workspace headers from env

  window = client.maintenance_windows.create({
      "monitorId": "<monitor-id>",
      "startsAt": "2026-05-15T14:00:00Z",
      "endsAt": "2026-05-15T14:30:00Z",
      "reason": "Quarterly DB upgrade",
  })
  ```

  ```typescript JS / TS SDK theme={null}
  import {Devhelm} from '@devhelm/sdk'

  const client = new Devhelm({token: process.env.DEVHELM_API_TOKEN!})

  const window = await client.maintenanceWindows.create({
    monitorId: '<monitor-id>',
    startsAt: '2026-05-15T14:00:00Z',
    endsAt: '2026-05-15T14:30:00Z',
    reason: 'Quarterly DB upgrade',
  })
  ```

  ```bash REST API theme={null}
  curl -X POST https://api.devhelm.io/api/v1/maintenance-windows \
    -H "Authorization: Bearer $DEVHELM_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "monitorId": "<monitor-id>",
      "startsAt": "2026-05-15T14:00:00Z",
      "endsAt": "2026-05-15T14:30:00Z",
      "reason": "Quarterly DB upgrade",
      "suppressAlerts": true
    }'
  ```
</CodeGroup>

Omit `monitorId` (or `--monitor`) to make the window org-wide.

## Recurring windows

Use `repeatRule` with an [iCal RRULE](https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.10) for recurring schedules. The `startsAt` / `endsAt` define the *first* occurrence; the RRULE generates the rest.

```json theme={null}
{
  "startsAt": "2026-04-15T02:00:00Z",
  "endsAt":   "2026-04-15T04:00:00Z",
  "repeatRule": "FREQ=WEEKLY;BYDAY=TU",
  "reason": "Weekly infra maintenance"
}
```

Common patterns:

| RRULE                             | Schedule                |
| --------------------------------- | ----------------------- |
| `FREQ=WEEKLY;BYDAY=TU`            | Every Tuesday           |
| `FREQ=MONTHLY;BYMONTHDAY=1`       | First day of each month |
| `FREQ=WEEKLY;BYDAY=SA;INTERVAL=2` | Every other Saturday    |

## Update or cancel

If the deploy runs long, **extend** the window — don't let it expire and have alerts flood in:

```bash theme={null}
devhelm maintenance-windows update <window-id> \
  --start "2026-05-15T14:00:00Z" \
  --end   "2026-05-15T15:00:00Z" \
  --reason "Migration still running"
```

The update endpoint is a **full replacement** (`PUT`, not `PATCH`) — pass the complete intended state, not a delta. Once the deploy succeeds, cancel the window so alerting resumes:

```bash theme={null}
devhelm maintenance-windows cancel <window-id>
```

There's no "uncancel" — schedule a new window if you need to restore suppression.

## Listing

```bash theme={null}
devhelm maintenance-windows list                       # all windows
devhelm maintenance-windows list --status active       # currently in progress
devhelm maintenance-windows list --status upcoming     # scheduled, not yet open
devhelm maintenance-windows list --monitor <monitor-id>
```

The `--status` values are `active` and `upcoming`; past / cancelled windows are not returned today (omit `--status` for the broadest result).

## Maintenance windows and notification policies

Suppression takes priority over notification policies — see [Alert suppression](/alerting/suppression) for the full precedence model. The short version:

* `suppressAlerts: true` (default) → notification policies are skipped entirely for the covered monitors during the window.
* `suppressAlerts: false` → incidents still get severity `MAINTENANCE`, but notifications still fire (useful for audit-only windows).

## Next steps

<CardGroup cols={2}>
  <Card title="CLI command reference" icon="terminal" href="/cli/commands/maintenance-windows">
    Every flag for `devhelm maintenance-windows`.
  </Card>

  <Card title="Maintenance windows guide" icon="wrench" href="/guides/maintenance-windows">
    Step-by-step: deploy-time and recurring windows.
  </Card>

  <Card title="Alert suppression" icon="bell-slash" href="/alerting/suppression">
    How suppression interacts with policies and resource groups.
  </Card>

  <Card title="Incident policies" icon="sliders" href="/incidents/policies">
    Trigger rules, confirmation, and recovery behavior.
  </Card>
</CardGroup>
