---
title: "Create Maintenance Window"
description: "Creates a new maintenance window."
---

`POST /api/maintenance-windows`

Important: You must provide **exactly one** target ID (e.g. `websiteId` *or* `icmpMonitorId`, `smtpMonitorId`, `sshMonitorId`, `ftpMonitorId`, `imapPopMonitorId`). All target IDs and `customerId` accept either the internal numeric ID or the matching public UUID.

## Authentication

Requires a valid session or API token.

- Header: `Authorization: Bearer <token>`

Note: Global supporter users are not allowed to create maintenance windows (`403`). Read-only users are allowed.

## Request Body

```json
{
 "websiteId": "521e3338-4597-4d1d-8eeb-dc56d271e71c",
 "name": "Server Upgrade",
 "description": "Planned downtime",
 "startTime": "2026-02-25T02:00:00.000Z",
 "endTime": "2026-02-25T04:00:00.000Z",
 "isRecurring": true,
 "recurrencePattern": {
  "frequency": "weekly",
  "interval": 1,
  "daysOfWeek": [1]
 },
 "isActive": true
}
```

### Fields

Target (exactly one required):

- `websiteId` (number|string)
- `icmpMonitorId` (number|string)
- `smtpMonitorId` (number|string)
- `sshMonitorId` (number|string)
- `ftpMonitorId` (number|string)
- `imapPopMonitorId` (number|string)
- `customerId` (number|string, optional)

Identifier rule:
Internal numeric IDs or public UUIDs are accepted.

Other fields:

- `name` (string, required)
- `description` (string, optional)
  - Max length: 2000
  - If omitted (or empty), it is stored as `null`.
- `startTime` (string/date, required)
- `endTime` (string/date, required)
  - Must be after `startTime`.
- `isRecurring` (boolean, optional)
  - Default: `false`
- `recurrencePattern` (object, optional)
  - Stored as JSON.
  - Typical keys include `frequency`, `interval`, `daysOfWeek`, `dayOfMonth`, `endRecurrenceDate`.
- `isActive` (boolean, optional)
  - Default: `true`
- `timezone` (string, optional)
  - Default: `"UTC"`
  - The IANA zone (e.g. `"Europe/Berlin"`) the recurrence pattern is interpreted in.
  - Case-insensitive spellings and legacy IANA link names (e.g. `"gmt"`, `"Zulu"`) are accepted and stored under the runtime's canonical name, `"utc"` and `"Zulu"` are both stored as `"UTC"`.
  - A raw UTC offset (e.g. `"+05:00"`) is rejected: it carries no daylight-saving rule, so it cannot express what a zone name does.

## Example (cURL)

```bash
BASE_URL="https://uptimeify.io"
TOKEN="<your-api-token>"

curl -X POST \
 "$BASE_URL/api/maintenance-windows" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{"websiteId":"521e3338-4597-4d1d-8eeb-dc56d271e71c","name":"Server Upgrade","description":"Planned downtime","startTime":"2026-02-25T02:00:00.000Z","endTime":"2026-02-25T04:00:00.000Z","isRecurring":true,"recurrencePattern":{"frequency":"weekly","interval":1,"daysOfWeek":[1]},"isActive":true}'
```

## Example Response

```json
{
 "id": 5,
 "websiteId": 101,
 "icmpMonitorId": null,
 "smtpMonitorId": null,
 "sshMonitorId": null,
 "ftpMonitorId": null,
 "imapPopMonitorId": null,
 "customerId": 12,
 "name": "Server Upgrade",
 "description": "Planned downtime",
 "startTime": "2026-02-25T02:00:00.000Z",
 "endTime": "2026-02-25T04:00:00.000Z",
 "isRecurring": true,
 "recurrencePattern": {
  "frequency": "weekly",
  "interval": 1,
  "daysOfWeek": [1]
 },
 "isActive": true,
 "timezone": "UTC",
 "createdBy": "<user-id>",
 "createdAt": "2026-02-20T10:00:00.000Z",
 "updatedAt": "2026-02-20T10:00:00.000Z"
}
```

## Common Errors

- `400 Exactly one target ID must be provided` if no or multiple target IDs are sent
- `400 Invalid Website identifier` or the corresponding target error if an identifier is neither an integer ID nor a UUID
- `400 End time must be after start time` if `endTime <= startTime`
- `400` (validation) if `timezone` is a raw UTC offset or not a zone name the runtime recognizes
- `401 Unauthorized` if you are not authenticated
- `403 Forbidden` if you do not have access (or are a global supporter)

