# Maintenance Windows

Maintenance windows let you suppress notifications during planned downtime. You can start maintenance immediately, schedule it for later, or set up recurring windows for regular deployment slots.

You'll need a [monitor ID](/docs/api/monitors.md) for most of these endpoints. All timestamps are in your team's timezone -- both when you send them and when we return them.

**Example request:**

```bash
$ OHDEAR_TOKEN="your API token"
$ curl "https://ohdear.app/api/monitors/1/maintenance-periods?filter[started_at]=20240101000000&filter[ended_at]=20241231235959" \
    -H "Authorization: Bearer $OHDEAR_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json'
```

All endpoints below follow the same [authentication](/docs/api/introduction.md#authenticate-against-the-api) pattern.

## Maintenance periods

### Maintenance period response fields
<!-- toc: Response fields -->

Each maintenance period includes the following fields:

```json
{
  "id": 45,
  "monitor_id": 1,
  "name": "Deployment",
  "starts_at": "2026-02-12 14:30:00",
  "ends_at": "2026-02-12 15:00:00"
}
```

- `id`: unique identifier
- `monitor_id`: the [monitor](/docs/api/monitors.md) this maintenance period belongs to
- `name`: optional label, or `null`
- `starts_at`: start time in your team's timezone
- `ends_at`: end time in your team's timezone

### Starting maintenance immediately
<!-- toc: Starting maintenance -->

<pre>POST /api/monitors/{monitorId}/start-maintenance</pre>

Starts maintenance for a monitor right now. We'll suppress notifications until the window ends.

**Request body (JSON):**

- `stop_maintenance_after_seconds` (integer, optional) -- how long the window lasts in seconds. Minimum `5`, default `3600`
- `name` (string, optional) -- a label for this maintenance window

Returns the [maintenance period object](#maintenance-period-response-fields).

### Stopping active maintenance
<!-- toc: Stopping maintenance -->

<pre>POST /api/monitors/{monitorId}/stop-maintenance</pre>

Ends active maintenance for a monitor. Notifications resume immediately, or after a delay if you specify one.

**Request body (JSON):**

- `delay_seconds` (integer, optional) -- seconds to wait before resuming notifications. Minimum `1`

Returns `204 No Content` on success.

### Creating a scheduled maintenance period
<!-- toc: Scheduling maintenance -->

<pre>POST /api/maintenance-periods</pre>

Schedule a future maintenance window. We'll suppress notifications during the specified period.

**Request body (JSON):**

- `monitor_id` (integer, required) -- the [monitor](/docs/api/monitors.md) to schedule maintenance for
- `starts_at` (string, required) -- start time in `Y-m-d H:i` format, in your team's timezone
- `ends_at` (string, required) -- end time in `Y-m-d H:i` format, must be after `starts_at`
- `name` (string, optional) -- a label for this maintenance window

Returns the [maintenance period object](#maintenance-period-response-fields).

### Updating a scheduled maintenance period
<!-- toc: Updating -->

<pre>PUT /api/maintenance-periods/{maintenancePeriodId}</pre>

Update the times or name of a scheduled maintenance period that hasn't started yet.

**Request body (JSON):**

- `starts_at` (string, required) -- start time in `Y-m-d H:i` format, in your team's timezone
- `ends_at` (string, required) -- end time in `Y-m-d H:i` format, must be after `starts_at`
- `name` (string, optional) -- a label for this maintenance window

Returns the updated [maintenance period object](#maintenance-period-response-fields).

### Deleting a maintenance period
<!-- toc: Deleting -->

<pre>DELETE /api/maintenance-periods/{maintenancePeriodId}</pre>

Returns `204 No Content` on success.

### Retrieving maintenance periods
<!-- toc: Retrieving -->

<pre>GET /api/monitors/{monitorId}/maintenance-periods</pre>

Returns a paginated list of maintenance periods for a monitor. Each item follows the same [maintenance period shape](#maintenance-period-response-fields) above.

**Query parameters:**

- `filter[started_at]` (string, optional) -- timestamp in `YmdHis` format
- `filter[ended_at]` (string, optional) -- timestamp in `YmdHis` format

## Recurring maintenance periods

Recurring maintenance periods automate regular maintenance windows -- perfect for weekly deployment slots or nightly processing windows.

### Recurring maintenance period response fields
<!-- toc: Recurring response fields -->

Each recurring maintenance period includes the following fields:

```json
{
  "id": 1,
  "monitor_id": 1,
  "name": "Weekly deployment window",
  "recurrence_type": "weekly",
  "days_of_week": [2, 4],
  "day_of_month": null,
  "start_time": "02:00",
  "end_time": "03:00",
  "human_readable_schedule": "Every Tuesday and Thursday from 02:00 to 03:00",
  "last_generated_until": "2026-02-19",
  "created_at": "2026-01-15T10:00:00+00:00",
  "updated_at": "2026-01-15T10:00:00+00:00"
}
```

- `id`: unique identifier
- `monitor_id`: the [monitor](/docs/api/monitors.md) this recurring period belongs to
- `name`: label for this recurring window, or `null`
- `recurrence_type`: schedule type -- Possible values: `daily`, `weekly`, `monthly`
- `days_of_week`: for weekly: array of day numbers `0`-`6` where `0` is Sunday, or `null`
- `day_of_month`: for monthly: day `1`-`31`, or `null`
- `start_time`: `HH:MM` format, in your team's timezone
- `end_time`: `HH:MM` format, in your team's timezone. If before `start_time`, the window spans overnight
- `human_readable_schedule`: human-friendly description of the schedule
- `last_generated_until`: the date (`Y-m-d`) up to which periods have been generated, or `null`
- `created_at`: ISO 8601 timestamp
- `updated_at`: ISO 8601 timestamp

### Get a recurring maintenance period
<!-- toc: Get one -->

<pre>GET /api/recurring-maintenance-periods/{recurringMaintenancePeriodId}</pre>

Returns a single recurring maintenance period by its ID. The response follows the [recurring maintenance period shape](#recurring-maintenance-period-response-fields) above.

### List recurring maintenance periods
<!-- toc: List all -->

<pre>GET /api/monitors/{monitorId}/recurring-maintenance-periods</pre>

Returns all recurring maintenance periods for a monitor. Each item follows the same [recurring maintenance period shape](#recurring-maintenance-period-response-fields) above.

### Create a recurring maintenance period
<!-- toc: Creating -->

<pre>POST /api/recurring-maintenance-periods</pre>

Set up a recurring maintenance window that automatically generates maintenance periods on a daily, weekly, or monthly schedule.

**Request body (JSON):**

- `monitor_id` (integer, required) -- the [monitor](/docs/api/monitors.md) to create the recurring window for
- `name` (string, required) -- a label for this recurring window
- `recurrence_type` (string, required) -- `daily`, `weekly`, or `monthly`
- `start_time` (string, required) -- start time in `HH:MM` format, in your team's timezone
- `end_time` (string, required) -- end time in `HH:MM` format, must differ from `start_time`
- `days_of_week` (array of integers, required for `weekly`) -- values `0`-`6` where `0` is Sunday
- `day_of_month` (integer, required for `monthly`) -- values `1`-`31`
- `generate_now` (boolean, optional) -- immediately generates maintenance periods for the next 7 days. Default `true`

Returns the [recurring maintenance period object](#recurring-maintenance-period-response-fields).

### Update a recurring maintenance period
<!-- toc: Updating -->

<pre>PUT /api/recurring-maintenance-periods/{recurringMaintenancePeriodId}</pre>

All fields are optional -- only include what you want to change.

**Request body (JSON):**

- `name` (string, optional)
- `recurrence_type` (string, optional) -- `daily`, `weekly`, or `monthly`
- `start_time` (string, optional) -- `HH:MM` format, in your team's timezone
- `end_time` (string, optional) -- `HH:MM` format
- `days_of_week` (array of integers, optional)
- `day_of_month` (integer, optional)
- `regenerate_future_periods` (boolean, optional) -- deletes and regenerates future periods with the new schedule. Default `true`

Returns the updated [recurring maintenance period object](#recurring-maintenance-period-response-fields).

### Delete a recurring maintenance period
<!-- toc: Deleting -->

<pre>DELETE /api/recurring-maintenance-periods/{recurringMaintenancePeriodId}</pre>

Returns `204 No Content` on success.

**Query parameter:**

- `delete_future_periods` (boolean, optional) -- also removes future periods generated from this recurring definition. Past periods are always preserved
