---
title: "Schedule Status Page Maintenance"
description: "Schedules maintenance for status pages and components, with announcement, reminder, start and end messages."
---

`POST /api/status-pages/maintenances`

`state` comes from the clock and is never stored: `scheduled` before `scheduledFor`, `in_progress` until `scheduledUntil`, then `completed`; `cancelled` once cancelled. The maintenance starts and ends by itself, no call is needed. While it is `in_progress` its components show `maintenance` on the public page (a worse state, such as an outage, stays), a maintenance without components shows the whole page as under maintenance.

Subscribers of the status page (or of an affected component) are notified through their channel (email, webhook, Slack, Teams) with the events `maintenance_scheduled` (when saved, and again when an upcoming start is moved), `maintenance_reminder`, `maintenance_started`, `maintenance_completed`, `maintenance_update` and `maintenance_cancelled`. The switches below decide which of them are sent; every event also appears in the page's RSS and Atom feed. Sending honours the page's subscription delay and is decided at send time: a moved or cancelled maintenance does not send its outdated messages.

Maintenance here informs the visitors of your status pages. It does not pause monitor alerts: for that create a [maintenance window](/api/maintenance-windows) in monitoring, which also appears on pages that show those monitors.

## Access

Organization `admin` and `editor`. A customer-scoped user or API token only reaches maintenance whose status pages all belong to a customer in its scope; a page without a customer (`customerId: null`) is for organization-wide roles only. Maintenance of another organization answers `404` (`statusPageMaintenanceNotFound`). Path ids take the numeric id or the `publicId`. The change is written to the organization's audit log.

## Request Body

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `title` | string | Yes | - | Shown on the page and in every message (1-200 chars). |
| `description` | string\|null | No | `null` | What happens and what visitors notice (max 5000 chars). |
| `scheduledFor` | string | Yes | - | Start, ISO 8601 with offset (`Z` or `+01:00`); stored and returned in UTC. |
| `scheduledUntil` | string | Yes | - | End, after `scheduledFor`. |
| `statusPageIds` | array | Yes | - | Status pages (id or `publicId`, 1-10) that show the maintenance. |
| `componentIds` | array | No | `[]` | Affected components (id or `publicId`, up to 100) of any source: manual, monitor or third-party. Each must belong to one of `statusPageIds`. A page without a listed component shows the maintenance page-wide. |
| `notifyOnSchedule` | boolean | No | `true` | Announce to subscribers when saved, and again when an upcoming start is moved. |
| `reminderMinutesBefore` | number\|null | No | `null` | Remind subscribers this many minutes (5-10080) before the start; `null` sends no reminder. |
| `notifyOnStart` | boolean | No | `false` | Notify subscribers when the maintenance starts. |
| `notifyOnComplete` | boolean | No | `true` | Notify subscribers when it ends. |

Unknown fields are rejected. A maintenance that lies entirely in the past is stored without an announcement.

## Example (cURL)

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

curl -X POST "$BASE_URL/api/status-pages/maintenances" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Database upgrade", "scheduledFor": "2026-11-03T23:00:00+01:00", "scheduledUntil": "2026-11-04T00:00:00+01:00", "statusPageIds": [1], "componentIds": [7], "reminderMinutesBefore": 60}'
```

## Response

`201 Created` with the maintenance:

```json
{
  "id": 12,
  "publicId": "3f1c2a9e-5b7d-4c8e-9a1f-2b3c4d5e6f70",
  "organizationId": 4,
  "title": "Database upgrade",
  "description": "Checkout may be slow for a few minutes.",
  "scheduledFor": "2026-11-03T22:00:00.000Z",
  "scheduledUntil": "2026-11-03T23:00:00.000Z",
  "state": "scheduled",
  "notifyOnSchedule": true,
  "reminderMinutesBefore": 60,
  "notifyOnStart": false,
  "notifyOnComplete": true,
  "cancelledAt": null,
  "statusPageIds": [1],
  "componentIds": [7],
  "links": [
    {
      "statusPageId": 1,
      "statusPagePublicId": "0b6f3c1e-8d2a-4f5b-9c7e-1a2b3c4d5e6f",
      "statusPageName": "Acme Status",
      "componentId": 7,
      "componentPublicId": "5a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
      "componentName": "Checkout"
    }
  ],
  "updates": [],
  "createdAt": "2026-10-28T09:00:00.000Z",
  "updatedAt": "2026-10-28T09:00:00.000Z"
}
```

## Fields

- `statusPageIds` and `componentIds` echo the request; `links` names every page and component (`componentId: null` = the whole page).
- `updates` are the public updates, oldest first (see [Post Maintenance Update](/api/status-pages/post-status-page-maintenance-update)).

## Common errors

- `400 Bad Request` (`invalidRequestBody`) when a field is missing, has the wrong type or is unknown; `data.issues` names the field
- `400 Bad Request` (`invalidDateRange`) when `scheduledUntil` is not after `scheduledFor`
- `400 Bad Request` (`invalidIdentifier`) when an id is neither a number nor a UUID
- `400 Bad Request` (`statusPageComponentNotOnPage`) when a component does not belong to one of `statusPageIds`
- `401 Unauthorized` when you are not logged in
- `403 Forbidden` (`forbidden`) when your role may not do this, or for a customer-scoped caller on a page without a customer or of another customer
- `403 Forbidden` (`statusPagesModuleDisabled`) when the status pages module is not activated
- `404 Not Found` (`statusPageNotFound`) when a status page does not exist or belongs to another organization
- `404 Not Found` (`statusPageComponentNotFound`) when a component does not exist
