---
title: Maintenance Windows
description: Schedule and manage maintenance windows. Suppress alerts during planned downtime.
section:
  title: API Resources
  order: 7
order: 9
lastUpdated: 2026-09-05
---

Maintenance windows allow you to schedule planned downtime for your monitors. During a maintenance window, alerts can be suppressed and the status page can display a maintenance notice.

## Scope

`monitorType` and `monitorId` are the window's scope, and together they mean one of three things:

- Neither — every monitor the team has, of every kind.
- `monitorType` alone — every monitor of that kind, including ones created later.
- `monitorType` and `monitorId` — that one monitor, looked up in that kind's monitors.

A `monitorId` sent on its own is read as an HTTP monitor, which is what it has always meant, so clients written before the other monitor kinds arrived keep working untouched.

A `monitorId` that does not belong to the team, or that belongs to a different kind of monitor than `monitorType` names, answers a `404` `not-found` problem with "Monitor not found" — the window is never quietly widened to the whole team instead.

## GET /api/v1/maintenance

Returns the maintenance windows for your team. This endpoint is paginated; see [Pagination](/docs/api/pagination) for how to page through the full list.

**Required scope:** `maintenance:read`

### Errors

| Status | Type | Description |
| --- | --- | --- |
| 400 | `bad-request` | The request is malformed |
| 401 | `unauthorized` | The API key is missing or invalid |
| 403 | `forbidden` | The API key lacks the required scope |

### Response Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"data": {
			"type": "object",
			"properties": {
				"maintenanceWindows": {
					"type": "array",
					"items": {
						"$ref": "#/$defs/MaintenanceWindow"
					}
				}
			},
			"required": [
				"maintenanceWindows"
			]
		},
		"meta": {
			"type": "object",
			"properties": {
				"requestId": {
					"type": "string",
					"format": "uuid"
				},
				"timestamp": {
					"type": "string",
					"format": "date-time"
				},
				"pagination": {
					"$ref": "#/$defs/Pagination"
				}
			},
			"required": [
				"requestId",
				"timestamp",
				"pagination"
			]
		}
	},
	"required": [
		"data",
		"meta"
	],
	"$defs": {
		"MaintenanceWindow": {
			"type": "object",
			"properties": {
				"id": {
					"type": "string",
					"pattern": "^mnt_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"teamId": {
					"type": "string",
					"pattern": "^team_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"monitorType": {
					"type": [
						"string",
						"null"
					],
					"enum": [
						"http",
						"dns",
						"tcp",
						"cron",
						"flow",
						null
					],
					"description": "Monitor type the window covers; null covers every type"
				},
				"monitorId": {
					"type": [
						"string",
						"null"
					],
					"description": "The one monitor the window covers; null covers the whole type"
				},
				"name": {
					"type": "string"
				},
				"startsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endedEarlyAt": {
					"type": [
						"integer",
						"null"
					],
					"description": "When the window was ended early; null while it runs its course"
				},
				"suppressAlerts": {
					"type": "boolean"
				},
				"showOnStatusPage": {
					"type": "boolean"
				},
				"createdAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"updatedAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				}
			},
			"required": [
				"id",
				"teamId",
				"monitorType",
				"monitorId",
				"name",
				"startsAt",
				"endsAt",
				"endedEarlyAt",
				"suppressAlerts",
				"showOnStatusPage",
				"createdAt",
				"updatedAt"
			]
		},
		"Pagination": {
			"type": "object",
			"properties": {
				"next": {
					"type": [
						"string",
						"null"
					],
					"description": "Cursor of the following page"
				},
				"prev": {
					"type": [
						"string",
						"null"
					],
					"description": "Cursor of the preceding page"
				},
				"perPage": {
					"type": "integer"
				},
				"total": {
					"type": "integer"
				}
			},
			"required": [
				"next",
				"prev",
				"perPage"
			]
		}
	}
}
```

### Query Parameters

| Parameter | Type    | Required | Description                               |
| --------- | ------- | -------- | ----------------------------------------- |
| `perPage` | integer | No       | Results per page, 1-200 (default: 50)     |
| `cursor`  | string  | No       | Page to fetch, taken from a `Link` header |

### Example Request

#### cURL

```bash
curl "https://uptime.sergiodxa.com/api/v1/maintenance?perPage=25" \
  -H "Authorization: Bearer uptime_your_api_key"
```

### Response

```json
{
	"data": {
		"maintenanceWindows": [
			{
				"id": "mnt_abc123",
				"teamId": "team_xyz789",
				"monitorType": "http",
				"monitorId": "mon_def456",
				"name": "Database Migration",
				"startsAt": 1771120800000,
				"endsAt": 1771128000000,
				"endedEarlyAt": null,
				"suppressAlerts": true,
				"showOnStatusPage": true,
				"createdAt": 1771070400000,
				"updatedAt": 1771070400000
			}
		]
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z",
		"pagination": {
			"next": "eyJkIjoiYWZ0ZXIi",
			"prev": null,
			"perPage": 25,
			"total": 31
		}
	}
}
```

The cursors for this page arrive in `meta.pagination`:

| Field                     | Type           | Description                                        |
| ------------------------- | -------------- | -------------------------------------------------- |
| `meta.pagination.next`    | string \| null | Cursor for the following page, `null` on the last  |
| `meta.pagination.prev`    | string \| null | Cursor for the preceding page, `null` on the first |
| `meta.pagination.perPage` | integer        | Results this page was built with                   |
| `meta.pagination.total`   | integer        | Maintenance windows matching, across every page    |

## POST /api/v1/maintenance

Creates a new maintenance window and answers `201 Created`.

**Required scope:** `maintenance:write`

### Errors

| Status | Type | Description |
| --- | --- | --- |
| 400 | `validation-error` | The request failed validation |
| 400 | `idempotency-key-invalid` | The Idempotency-Key header is not valid |
| 401 | `unauthorized` | The API key is missing or invalid |
| 403 | `forbidden` | The API key lacks the required scope |
| 404 | `not-found` | The resource does not exist |
| 409 | `idempotency-key-in-use` | A request with this idempotency key is still being processed |
| 422 | `idempotency-key-reused` | This idempotency key was already used for a different request |

### Request Body Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"name": {
			"type": "string",
			"description": "At least one character"
		},
		"monitorType": {
			"type": "string",
			"enum": [
				"http",
				"dns",
				"tcp",
				"cron",
				"flow"
			],
			"description": "Defaults to `http` beside a `monitorId`"
		},
		"monitorId": {
			"type": [
				"string",
				"null"
			]
		},
		"startsAt": {
			"type": "string",
			"format": "date-time"
		},
		"endsAt": {
			"type": "string",
			"format": "date-time",
			"description": "Must follow `startsAt`"
		},
		"suppressAlerts": {
			"type": "boolean",
			"default": true
		},
		"showOnStatusPage": {
			"type": "boolean",
			"default": true
		}
	},
	"required": [
		"name",
		"startsAt",
		"endsAt"
	]
}
```

### Response Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"data": {
			"type": "object",
			"properties": {
				"maintenanceWindow": {
					"$ref": "#/$defs/MaintenanceWindow"
				}
			},
			"required": [
				"maintenanceWindow"
			]
		},
		"meta": {
			"type": "object",
			"properties": {
				"requestId": {
					"type": "string",
					"format": "uuid"
				},
				"timestamp": {
					"type": "string",
					"format": "date-time"
				}
			},
			"required": [
				"requestId",
				"timestamp"
			]
		}
	},
	"required": [
		"data",
		"meta"
	],
	"$defs": {
		"MaintenanceWindow": {
			"type": "object",
			"properties": {
				"id": {
					"type": "string",
					"pattern": "^mnt_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"teamId": {
					"type": "string",
					"pattern": "^team_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"monitorType": {
					"type": [
						"string",
						"null"
					],
					"enum": [
						"http",
						"dns",
						"tcp",
						"cron",
						"flow",
						null
					],
					"description": "Monitor type the window covers; null covers every type"
				},
				"monitorId": {
					"type": [
						"string",
						"null"
					],
					"description": "The one monitor the window covers; null covers the whole type"
				},
				"name": {
					"type": "string"
				},
				"startsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endedEarlyAt": {
					"type": [
						"integer",
						"null"
					],
					"description": "When the window was ended early; null while it runs its course"
				},
				"suppressAlerts": {
					"type": "boolean"
				},
				"showOnStatusPage": {
					"type": "boolean"
				},
				"createdAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"updatedAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				}
			},
			"required": [
				"id",
				"teamId",
				"monitorType",
				"monitorId",
				"name",
				"startsAt",
				"endsAt",
				"endedEarlyAt",
				"suppressAlerts",
				"showOnStatusPage",
				"createdAt",
				"updatedAt"
			]
		}
	}
}
```

### Request Body

| Field              | Type           | Required | Description                                                                                                                                                                                                                        |
| ------------------ | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`             | string         | Yes      | Name of the maintenance window (at least 1 character)                                                                                                                                                                              |
| `startsAt`         | string         | Yes      | Start time in ISO 8601 format                                                                                                                                                                                                      |
| `endsAt`           | string         | Yes      | End time in ISO 8601 format (must be after `startsAt`)                                                                                                                                                                             |
| `monitorType`      | string         | No       | Limit the window to one kind of monitor: `http`, `dns`, `tcp`, `cron` or `flow`. Sent on its own, the window covers every monitor of that kind, including ones created later.                                                      |
| `monitorId`        | string \| null | No       | Limit the window to a single monitor, or `null` for all monitors. Sent together with `monitorType`, the id is looked up in that kind's monitors; sent on its own it is read as an HTTP monitor, which is what it has always meant. |
| `suppressAlerts`   | boolean        | No       | Whether to suppress alerts during maintenance (default: `true`)                                                                                                                                                                    |
| `showOnStatusPage` | boolean        | No       | Whether to show maintenance on status page (default: `true`)                                                                                                                                                                       |

### Example Request

#### cURL

```bash
curl -X POST https://uptime.sergiodxa.com/api/v1/maintenance \
  -H "Authorization: Bearer uptime_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Database Migration",
    "startsAt": "2026-02-15T02:00:00Z",
    "endsAt": "2026-02-15T04:00:00Z",
    "monitorType": "http",
    "monitorId": "mon_def456",
    "suppressAlerts": true,
    "showOnStatusPage": true
  }'
```

### Response

```json
{
	"data": {
		"maintenanceWindow": {
			"id": "mnt_abc123",
			"teamId": "team_xyz789",
			"monitorType": "http",
			"monitorId": "mon_def456",
			"name": "Database Migration",
			"startsAt": 1771120800000,
			"endsAt": 1771128000000,
			"endedEarlyAt": null,
			"suppressAlerts": true,
			"showOnStatusPage": true,
			"createdAt": 1771063200000,
			"updatedAt": 1771063200000
		}
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z"
	}
}
```

## GET /api/v1/maintenance/:id

Returns a single maintenance window by ID.

**Required scope:** `maintenance:read`

### Errors

| Status | Type | Description |
| --- | --- | --- |
| 400 | `validation-error` | The request failed validation |
| 401 | `unauthorized` | The API key is missing or invalid |
| 403 | `forbidden` | The API key lacks the required scope |
| 404 | `not-found` | The resource does not exist |

### Response Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"data": {
			"type": "object",
			"properties": {
				"maintenanceWindow": {
					"$ref": "#/$defs/MaintenanceWindow"
				}
			},
			"required": [
				"maintenanceWindow"
			]
		},
		"meta": {
			"type": "object",
			"properties": {
				"requestId": {
					"type": "string",
					"format": "uuid"
				},
				"timestamp": {
					"type": "string",
					"format": "date-time"
				}
			},
			"required": [
				"requestId",
				"timestamp"
			]
		}
	},
	"required": [
		"data",
		"meta"
	],
	"$defs": {
		"MaintenanceWindow": {
			"type": "object",
			"properties": {
				"id": {
					"type": "string",
					"pattern": "^mnt_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"teamId": {
					"type": "string",
					"pattern": "^team_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"monitorType": {
					"type": [
						"string",
						"null"
					],
					"enum": [
						"http",
						"dns",
						"tcp",
						"cron",
						"flow",
						null
					],
					"description": "Monitor type the window covers; null covers every type"
				},
				"monitorId": {
					"type": [
						"string",
						"null"
					],
					"description": "The one monitor the window covers; null covers the whole type"
				},
				"name": {
					"type": "string"
				},
				"startsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endedEarlyAt": {
					"type": [
						"integer",
						"null"
					],
					"description": "When the window was ended early; null while it runs its course"
				},
				"suppressAlerts": {
					"type": "boolean"
				},
				"showOnStatusPage": {
					"type": "boolean"
				},
				"createdAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"updatedAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				}
			},
			"required": [
				"id",
				"teamId",
				"monitorType",
				"monitorId",
				"name",
				"startsAt",
				"endsAt",
				"endedEarlyAt",
				"suppressAlerts",
				"showOnStatusPage",
				"createdAt",
				"updatedAt"
			]
		}
	}
}
```

### Example Request

#### cURL

```bash
curl https://uptime.sergiodxa.com/api/v1/maintenance/mnt_abc123 \
  -H "Authorization: Bearer uptime_your_api_key"
```

### Response

```json
{
	"data": {
		"maintenanceWindow": {
			"id": "mnt_abc123",
			"teamId": "team_xyz789",
			"monitorType": "http",
			"monitorId": "mon_def456",
			"name": "Database Migration",
			"startsAt": 1771120800000,
			"endsAt": 1771128000000,
			"endedEarlyAt": null,
			"suppressAlerts": true,
			"showOnStatusPage": true,
			"createdAt": 1771063200000,
			"updatedAt": 1771063200000
		}
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z"
	}
}
```

## PATCH /api/v1/maintenance/:id

Updates an existing maintenance window with a [JSON merge patch](/docs/api/overview#updating-resources).

**Required scope:** `maintenance:write`

### Errors

| Status | Type | Description |
| --- | --- | --- |
| 400 | `validation-error` | The request failed validation |
| 401 | `unauthorized` | The API key is missing or invalid |
| 403 | `forbidden` | The API key lacks the required scope |
| 404 | `not-found` | The resource does not exist |
| 415 | `unsupported-media-type` | The request body's media type is not accepted |

### Response Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"data": {
			"type": "object",
			"properties": {
				"maintenanceWindow": {
					"$ref": "#/$defs/MaintenanceWindow"
				}
			},
			"required": [
				"maintenanceWindow"
			]
		},
		"meta": {
			"type": "object",
			"properties": {
				"requestId": {
					"type": "string",
					"format": "uuid"
				},
				"timestamp": {
					"type": "string",
					"format": "date-time"
				}
			},
			"required": [
				"requestId",
				"timestamp"
			]
		}
	},
	"required": [
		"data",
		"meta"
	],
	"$defs": {
		"MaintenanceWindow": {
			"type": "object",
			"properties": {
				"id": {
					"type": "string",
					"pattern": "^mnt_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"teamId": {
					"type": "string",
					"pattern": "^team_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"monitorType": {
					"type": [
						"string",
						"null"
					],
					"enum": [
						"http",
						"dns",
						"tcp",
						"cron",
						"flow",
						null
					],
					"description": "Monitor type the window covers; null covers every type"
				},
				"monitorId": {
					"type": [
						"string",
						"null"
					],
					"description": "The one monitor the window covers; null covers the whole type"
				},
				"name": {
					"type": "string"
				},
				"startsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endedEarlyAt": {
					"type": [
						"integer",
						"null"
					],
					"description": "When the window was ended early; null while it runs its course"
				},
				"suppressAlerts": {
					"type": "boolean"
				},
				"showOnStatusPage": {
					"type": "boolean"
				},
				"createdAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"updatedAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				}
			},
			"required": [
				"id",
				"teamId",
				"monitorType",
				"monitorId",
				"name",
				"startsAt",
				"endsAt",
				"endedEarlyAt",
				"suppressAlerts",
				"showOnStatusPage",
				"createdAt",
				"updatedAt"
			]
		}
	}
}
```

### Request Body

Include only the fields you want to change. `null` clears the scope and resets `suppressAlerts` and `showOnStatusPage` to `true`; `name`, `startsAt` and `endsAt` cannot be removed.

| Field              | Type            | Required | Description                                                                          |
| ------------------ | --------------- | -------- | ------------------------------------------------------------------------------------ |
| `name`             | string          | No       | Name of the maintenance window (at least 1 character)                                |
| `startsAt`         | string          | No       | Start time in ISO 8601 format                                                        |
| `endsAt`           | string          | No       | End time in ISO 8601 format (must be after the window's start, sent or stored)       |
| `monitorType`      | string \| null  | No       | The kind of monitor the window is limited to: `http`, `dns`, `tcp`, `cron` or `flow` |
| `monitorId`        | string \| null  | No       | The single monitor the window is limited to, or `null` for all monitors              |
| `suppressAlerts`   | boolean \| null | No       | Whether to suppress alerts during maintenance; `null` resets it to `true`            |
| `showOnStatusPage` | boolean \| null | No       | Whether to show maintenance on status page; `null` resets it to `true`               |

`monitorType` and `monitorId` are the window's scope, and they move as a pair: change either one and both are rewritten, so narrowing a window to a whole kind of monitor cannot leave the previous monitor's id behind it. Mention neither and the scope is left exactly as it is.

- `{"monitorType": "dns"}` — every DNS monitor
- `{"monitorType": "dns", "monitorId": "..."}` — that one DNS monitor
- `{"monitorId": null}` or `{"monitorType": null}` — back to team-wide
- `{"monitorId": "..."}` — that one HTTP monitor

A `monitorId` that does not belong to the team, or that belongs to a different kind of monitor than `monitorType` names, answers a `404` `not-found` problem.

### Example Request

#### cURL

```bash
curl -X PATCH https://uptime.sergiodxa.com/api/v1/maintenance/mnt_abc123 \
  -H "Authorization: Bearer uptime_your_api_key" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
    "name": "Extended Database Migration",
    "endsAt": "2026-02-15T06:00:00Z"
  }'
```

### Response

```json
{
	"data": {
		"maintenanceWindow": {
			"id": "mnt_abc123",
			"teamId": "team_xyz789",
			"monitorType": "http",
			"monitorId": "mon_def456",
			"name": "Extended Database Migration",
			"startsAt": 1771120800000,
			"endsAt": 1771135200000,
			"endedEarlyAt": null,
			"suppressAlerts": true,
			"showOnStatusPage": true,
			"createdAt": 1771063200000,
			"updatedAt": 1771068600000
		}
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z"
	}
}
```

### Update With PUT

`PUT /api/v1/maintenance/:id` takes the same fields, for integrations written before `PATCH` existed. A field you leave out keeps its value, and `null` is refused everywhere except `monitorId`, where it widens the window back to team-wide. Sending either scope field rewrites both, and the window's `endsAt` must still follow its `startsAt`.

**Required scope:** `maintenance:write`

### Errors

| Status | Type | Description |
| --- | --- | --- |
| 400 | `validation-error` | The request failed validation |
| 401 | `unauthorized` | The API key is missing or invalid |
| 403 | `forbidden` | The API key lacks the required scope |
| 404 | `not-found` | The resource does not exist |

### Request Body Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"name": {
			"type": "string",
			"description": "At least one character"
		},
		"monitorType": {
			"type": "string",
			"enum": [
				"http",
				"dns",
				"tcp",
				"cron",
				"flow"
			]
		},
		"monitorId": {
			"type": [
				"string",
				"null"
			]
		},
		"startsAt": {
			"type": "string",
			"format": "date-time"
		},
		"endsAt": {
			"type": "string",
			"format": "date-time"
		},
		"suppressAlerts": {
			"type": "boolean"
		},
		"showOnStatusPage": {
			"type": "boolean"
		}
	}
}
```

### Response Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"data": {
			"type": "object",
			"properties": {
				"maintenanceWindow": {
					"$ref": "#/$defs/MaintenanceWindow"
				}
			},
			"required": [
				"maintenanceWindow"
			]
		},
		"meta": {
			"type": "object",
			"properties": {
				"requestId": {
					"type": "string",
					"format": "uuid"
				},
				"timestamp": {
					"type": "string",
					"format": "date-time"
				}
			},
			"required": [
				"requestId",
				"timestamp"
			]
		}
	},
	"required": [
		"data",
		"meta"
	],
	"$defs": {
		"MaintenanceWindow": {
			"type": "object",
			"properties": {
				"id": {
					"type": "string",
					"pattern": "^mnt_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"teamId": {
					"type": "string",
					"pattern": "^team_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"monitorType": {
					"type": [
						"string",
						"null"
					],
					"enum": [
						"http",
						"dns",
						"tcp",
						"cron",
						"flow",
						null
					],
					"description": "Monitor type the window covers; null covers every type"
				},
				"monitorId": {
					"type": [
						"string",
						"null"
					],
					"description": "The one monitor the window covers; null covers the whole type"
				},
				"name": {
					"type": "string"
				},
				"startsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endedEarlyAt": {
					"type": [
						"integer",
						"null"
					],
					"description": "When the window was ended early; null while it runs its course"
				},
				"suppressAlerts": {
					"type": "boolean"
				},
				"showOnStatusPage": {
					"type": "boolean"
				},
				"createdAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"updatedAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				}
			},
			"required": [
				"id",
				"teamId",
				"monitorType",
				"monitorId",
				"name",
				"startsAt",
				"endsAt",
				"endedEarlyAt",
				"suppressAlerts",
				"showOnStatusPage",
				"createdAt",
				"updatedAt"
			]
		}
	}
}
```

## DELETE /api/v1/maintenance/:id

Deletes a maintenance window.

**Required scope:** `maintenance:write`

### Errors

| Status | Type | Description |
| --- | --- | --- |
| 400 | `validation-error` | The request failed validation |
| 401 | `unauthorized` | The API key is missing or invalid |
| 403 | `forbidden` | The API key lacks the required scope |
| 404 | `not-found` | The resource does not exist |

### Response Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"data": {
			"type": "object",
			"properties": {
				"deleted": {
					"type": "boolean",
					"const": true
				}
			},
			"required": [
				"deleted"
			]
		},
		"meta": {
			"type": "object",
			"properties": {
				"requestId": {
					"type": "string",
					"format": "uuid"
				},
				"timestamp": {
					"type": "string",
					"format": "date-time"
				}
			},
			"required": [
				"requestId",
				"timestamp"
			]
		}
	},
	"required": [
		"data",
		"meta"
	]
}
```

### Example Request

#### cURL

```bash
curl -X DELETE https://uptime.sergiodxa.com/api/v1/maintenance/mnt_abc123 \
  -H "Authorization: Bearer uptime_your_api_key"
```

### Response

```json
{
	"data": {
		"deleted": true
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z"
	}
}
```

## POST /api/v1/maintenance/:id/end

Ends a maintenance window early. Sets the `endedEarlyAt` timestamp to the current time.

**Required scope:** `maintenance:write`

### Errors

| Status | Type | Description |
| --- | --- | --- |
| 400 | `validation-error` | The request failed validation |
| 401 | `unauthorized` | The API key is missing or invalid |
| 403 | `forbidden` | The API key lacks the required scope |
| 404 | `not-found` | The resource does not exist |

### Response Schema

```json
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"type": "object",
	"properties": {
		"data": {
			"type": "object",
			"properties": {
				"maintenanceWindow": {
					"$ref": "#/$defs/MaintenanceWindow"
				}
			},
			"required": [
				"maintenanceWindow"
			]
		},
		"meta": {
			"type": "object",
			"properties": {
				"requestId": {
					"type": "string",
					"format": "uuid"
				},
				"timestamp": {
					"type": "string",
					"format": "date-time"
				}
			},
			"required": [
				"requestId",
				"timestamp"
			]
		}
	},
	"required": [
		"data",
		"meta"
	],
	"$defs": {
		"MaintenanceWindow": {
			"type": "object",
			"properties": {
				"id": {
					"type": "string",
					"pattern": "^mnt_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"teamId": {
					"type": "string",
					"pattern": "^team_[0-7][0-9a-hjkmnp-tv-z]{25}$"
				},
				"monitorType": {
					"type": [
						"string",
						"null"
					],
					"enum": [
						"http",
						"dns",
						"tcp",
						"cron",
						"flow",
						null
					],
					"description": "Monitor type the window covers; null covers every type"
				},
				"monitorId": {
					"type": [
						"string",
						"null"
					],
					"description": "The one monitor the window covers; null covers the whole type"
				},
				"name": {
					"type": "string"
				},
				"startsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endsAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"endedEarlyAt": {
					"type": [
						"integer",
						"null"
					],
					"description": "When the window was ended early; null while it runs its course"
				},
				"suppressAlerts": {
					"type": "boolean"
				},
				"showOnStatusPage": {
					"type": "boolean"
				},
				"createdAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				},
				"updatedAt": {
					"type": "integer",
					"description": "Epoch milliseconds"
				}
			},
			"required": [
				"id",
				"teamId",
				"monitorType",
				"monitorId",
				"name",
				"startsAt",
				"endsAt",
				"endedEarlyAt",
				"suppressAlerts",
				"showOnStatusPage",
				"createdAt",
				"updatedAt"
			]
		}
	}
}
```

### Example Request

#### cURL

```bash
curl -X POST https://uptime.sergiodxa.com/api/v1/maintenance/mnt_abc123/end \
  -H "Authorization: Bearer uptime_your_api_key"
```

### Response

```json
{
	"data": {
		"maintenanceWindow": {
			"id": "mnt_abc123",
			"teamId": "team_xyz789",
			"monitorType": "http",
			"monitorId": "mon_def456",
			"name": "Database Migration",
			"startsAt": 1771120800000,
			"endsAt": 1771128000000,
			"endedEarlyAt": 1771125300000,
			"suppressAlerts": true,
			"showOnStatusPage": true,
			"createdAt": 1771063200000,
			"updatedAt": 1771125300000
		}
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z"
	}
}
```

## Response Fields

| Field              | Type            | Description                                                                     |
| ------------------ | --------------- | ------------------------------------------------------------------------------- |
| `id`               | string          | Unique maintenance window identifier                                            |
| `teamId`           | string          | Team that owns this maintenance window                                          |
| `monitorType`      | string \| null  | Kind of monitor the window is limited to, or `null` if it applies to every kind |
| `monitorId`        | string \| null  | Associated monitor ID, or `null` if applies to all monitors                     |
| `name`             | string          | Display name of the maintenance window                                          |
| `startsAt`         | integer         | Scheduled start time as a Unix timestamp in milliseconds                        |
| `endsAt`           | integer         | Scheduled end time as a Unix timestamp in milliseconds                          |
| `endedEarlyAt`     | integer \| null | When maintenance was ended early, in milliseconds, or `null`                    |
| `suppressAlerts`   | boolean         | Whether alerts are suppressed during maintenance                                |
| `showOnStatusPage` | boolean         | Whether maintenance is displayed on the status page                             |
| `createdAt`        | integer         | Creation time as a Unix timestamp in milliseconds                               |
| `updatedAt`        | integer         | Last update time as a Unix timestamp in milliseconds                            |
