---
title: "Preview Maintenance Occurrences"
description: "Computes the upcoming occurrences of a (not-yet-saved) recurrence pattern, without creating a window."
---

`POST /api/maintenance-windows/preview-occurrences`

Pure computation: this endpoint never touches the database. It runs the same zone-aware
recurrence engine the alert-suppression path uses (`occurrencesInRange`), so the preview can
never drift from what a saved window with the same `startTime`/`endTime`/`recurrencePattern`/
`timezone` will actually suppress. Useful for showing "what does this pattern mean" before
submitting [Create Maintenance Window](/docs/api/maintenance-windows/create) or
[Update Maintenance Window](/docs/api/maintenance-windows/update).

## Body

```json
{
  "startTime": "2026-08-10T02:00:00.000Z",
  "endTime": "2026-08-10T03:00:00.000Z",
  "isRecurring": true,
  "recurrencePattern": {
    "frequency": "weekly",
    "interval": 1,
    "daysOfWeek": [1, 3]
  },
  "timezone": "Europe/Berlin"
}
```

### Fields

| Field | Type | Description |
|-------|------|-------------|
| `startTime` | ISO 8601 datetime | Required. Start of the first occurrence. |
| `endTime` | ISO 8601 datetime | Required. End of the first occurrence. Must be after `startTime`. |
| `isRecurring` | boolean | Required. When `false`, the response contains only the single anchor occurrence. |
| `recurrencePattern` | object | Required when `isRecurring` is `true`. Same shape as [Create Maintenance Window](/docs/api/maintenance-windows/create#recurrence). |
| `timezone` | string | Default `"UTC"`. The IANA zone the pattern is interpreted in, same validation and canonicalization as the `timezone` field on create/update. |

The response returns at most 5 upcoming occurrences, looking forward up to 5 years from the
current time.

## Example (cURL)

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

curl -X POST "$BASE_URL/api/maintenance-windows/preview-occurrences" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startTime": "2026-08-10T02:00:00.000Z",
    "endTime": "2026-08-10T03:00:00.000Z",
    "isRecurring": true,
    "recurrencePattern": { "frequency": "weekly", "interval": 1, "daysOfWeek": [1, 3] },
    "timezone": "Europe/Berlin"
  }'
```

## Response

```json
{
  "occurrences": [
    { "start": "2026-08-10T00:00:00.000Z", "end": "2026-08-10T01:00:00.000Z" },
    { "start": "2026-08-12T00:00:00.000Z", "end": "2026-08-12T01:00:00.000Z" },
    { "start": "2026-08-17T00:00:00.000Z", "end": "2026-08-17T01:00:00.000Z" }
  ]
}
```

`occurrences` may be an empty array (e.g. a recurrence pattern whose `endRecurrenceDate` has
already passed relative to the preview horizon).

Sending `isRecurring: true` without a `recurrencePattern` is not an error. The window is treated
as non-recurring and the response contains only the single occurrence described by `startTime`
and `endTime`, the same fallback the recurrence engine applies to a malformed pattern.

## Common errors

| Status | Description |
|--------|-------------|
| `400` (validation) | `timezone` is a raw UTC offset or not a zone name the runtime recognizes. Standard Zod validation error body, not `{ data: { code } }`. |
| `400` `{ data: { code: "invalidWindow" } }` | `endTime` is not after `startTime`. |
| `401 Unauthorized` | Not logged in. |
