Skip to content

Create a maintenance window

View as Markdown

A maintenance window tells HostTracker in advance that some monitors will be down on purpose - a deploy, a server move, a database upgrade. While it runs, the covered monitors keep checking but hold back their down alerts, their downtime statistics, or both. This page walks every field of the editor and shows the same thing through the API and MCP. For the concept, see What a maintenance window is.

Maintenance windows are available on every plan, with no limit on how many windows you create or how many monitors one window covers.

Setting (UI label) API field Type / allowed values Default What it does for you
Short description (the name field) name Text, 1-255 characters, required - How you recognise the window in lists, alerts and on the status page.
Window active / Window paused enabled true / false true A paused window stays saved but suppresses nothing.
Repeat recurrence One time (recurrence absent or null) or Weekly (recurrence: {"weekDays": [...]}) One time Whether the window runs once or every week. The editor locks it after the window is created.
Days of week (Weekly only) recurrence.weekDays Array of English day names: Monday … Sunday, at least one Monday to Friday in the editor The days a weekly window repeats on. See recurring windows.
Starts / Ends (One time), From / To (Weekly, per occurrence) from + to, or from + durationSec from and to are Unix seconds; durationSec is seconds. Send to or durationSec, never both Editor: starts in one hour, lasts one hour When the window begins and how long it lasts. Minimum length 60 seconds; maximum about 10 years.
Quick add - Buttons +1m, +1h, +4h, +1d, +5d - Each button adds to the current duration; the running duration is shown beside them.
Time zone timezone An IANA zone id such as Europe/Berlin (a Windows zone name is also accepted on write and converted) UTC The wall clock the start time is read in. A weekly window keeps its local time across daylight-saving changes.
Show on status page showOnStatusPage true / false true Shows the window on any of your status pages that includes a covered monitor. Display only - it never changes suppression. See Show maintenance on your status page.
Affected Monitors monitorIds (same suppression for all) or monitors[] (per monitor) Monitor ids you own; send one form, not both - Which monitors the window covers. A new window must cover at least one.
Alerts tile (per monitor) suppress.alerts or monitors[].suppress.alerts true / false API: true when you send monitorIds without suppress; false when you send a suppress object that leaves it out Holds back down notifications for that monitor while the window runs.
Stats tile (per monitor) suppress.stats or monitors[].suppress.stats true / false API: false when you send monitorIds without suppress, or a suppress object that leaves it out Keeps the window’s downtime out of that monitor’s uptime statistics.

Each covered monitor needs at least one of Alerts or Stats turned on - a monitor that suppresses neither is refused, because the window would do nothing for it. What each one does in detail: What a maintenance window suppresses.

  1. Open Maintenance in the sidebar (/maintenance) and click Add. The editor opens as a side panel.
  2. Type a Short description - for example “Database migration”.
  3. Leave Window active on.
  4. Under Schedule, choose Repeat: One time or Weekly. This choice cannot be changed after you save.
  5. Set the Window:
    • One time: pick the Starts and Ends date and time.
    • Weekly: pick the Days of week and the From / To time of day. An end time earlier than the start time runs past midnight (22:00 to 03:00 is a five-hour night window).
    • Use Quick add to extend the length quickly; the duration updates as you go.
  6. Choose the Time zone the times are in (the default is UTC).
  7. Leave Show on status page on if visitors to your status pages should see the window, or turn it off for a purely internal window.
  8. Under Affected Monitors, find each monitor (use Search monitors…) and turn on its Alerts tile, its Stats tile, or both. Clicking a column header toggles that column for every monitor the current search shows (up to 1,000 at once).
  9. Click Save. The panel shows a “Saved” tick; the window appears in the list under ACTIVE NOW, UPCOMING - NEXT 7 DAYS, RECURRING or PAST.

The list page also shows a Next 7 days timeline strip, a search box and a Status filter (All, Active, Upcoming, Recurring, Past, Disabled). Each row has a switch to pause or activate the window, a gear to edit it and a bin to delete it.

Scopes: monitor:read to list and read, monitor:write to create, change and cancel. See API authentication.

Create - POST /maintenance:

Terminal window
curl -X POST https://api2.host-tracker.com/maintenance \
-H "Authorization: Bearer $HT_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: maint-db-migration-2026-10-03" \
-d '{
"name": "Database migration",
"from": 1790000000,
"durationSec": 7200,
"timezone": "Europe/Berlin",
"monitorIds": ["MONITOR_ID_1", "MONITOR_ID_2"],
"suppress": { "alerts": true, "stats": true }
}'

The answer is 201 Created with the full window and a Location: /maintenance/{id} header.

Different suppression per monitor uses monitors[] instead of monitorIds + suppress:

{
"name": "Web tier deploy",
"from": 1790000000,
"to": 1790001800,
"monitors": [
{ "monitorId": "WEB_MONITOR_ID", "suppress": { "alerts": true, "stats": true } },
{ "monitorId": "API_MONITOR_ID", "suppress": { "alerts": true, "stats": false } }
]
}

Other operations:

Task Operation
List windows GET /maintenance - filters state (scheduled, active, finished), monitor, from, to, updatedSince; sort=from (default) or created
Read one GET /maintenance/{id}
Windows covering one monitor GET /monitor/{monitorId}/maintenance
Change a window PATCH /maintenance/{id} - send only what changes
Pause without deleting PATCH /maintenance/{id} with {"enabled": false}
Cancel (delete) DELETE /maintenance/{id}

The window you read back carries id, name, from, to, durationSec, timezone, recurrence, enabled, state (scheduled, active or finished), overlimited, showOnStatusPage, suppress (omitted when the monitors’ suppressions differ), monitorIds, monitors[], created and updated.

MCP: create_maintenance takes name, from (Unix seconds), monitorIds (a comma-separated string of ids), and to or durationSec, plus optional timezone, suppressAlerts, suppressStats and weekDays (comma-separated day names). Send both suppression flags when you want both: with only suppressStats=true the window would not hold back alerts, because an absent flag counts as false once either is sent (with neither, the window suppresses alerts only). Example - silence alerts and exclude from statistics for 90 minutes:

create_maintenance(name="Staging deploy", from=1790632800, durationSec=5400, timezone="UTC",
monitorIds="MONITOR_ID_1,MONITOR_ID_2", suppressAlerts=true, suppressStats=true)

update_maintenance, list_maintenance and delete_maintenance cover the rest; update_maintenance cannot change the suppression flags, the weekly days or showOnStatusPage - use api_request with PATCH /maintenance/{id} for those. The MCP tools have no showOnStatusPage argument; windows they create show on status pages by default.

A window has no tag selector: it covers the explicit list of monitors you send (monitorIds or monitors[]), and that list is a snapshot. Webhooks can be scoped by tag; maintenance windows cannot. To silence “everything tagged staging”:

  1. List the monitors: GET /monitor?tag=staging&limit=500 (MCP list_monitors(tag="staging"), 50 per page). Follow nextCursor while hasMore is true and collect every id. Several tags (tag=staging,qa) match monitors that carry any of them.
  2. Create the window with those ids: POST /maintenance with "monitorIds": [...] (MCP create_maintenance with monitorIds="ID1,ID2,...").
  3. A monitor that gets the tag after the window was created is not covered, and a monitor that loses the tag stays covered. For a standing weekly window over a tag, re-run steps 1-2 and send the fresh list with PATCH /maintenance/{id} {"monitorIds": [...]} (it replaces the coverage) whenever the tagged set changes. Added ids get the suppression the window already applies to all its monitors; if its monitors differ, send suppress in the same request or it is refused (422, pointer /suppress).

In the app, Search monitors… under Affected Monitors matches monitor names and addresses, not tags. If your tagged monitors share a word in their name or address, search for it and click the Alerts or Stats column header to toggle every monitor the search shows; otherwise turn the tiles on one by one, or use the API.

  • The window takes effect by itself at its start time. HostTracker’s checking engine picks up new and changed windows within about a minute, so a window saved a minute before it starts is on time.
  • Checks keep running during the window and every result is recorded - see What a maintenance window suppresses.
  • If Show on status page is on, the window appears on your status pages as planned maintenance from 7 days before it starts.
  • When the window ends, suppression stops at once. A monitor that is still down then sends one down alert.
  • A maintenance.ended webhook event fires when the window ends on schedule or is cancelled while active. There is no “maintenance started” event.
  • Open the window from the Maintenance list (gear icon) to change its time, time zone, monitors or suppression. Changes to a window that is already running apply within about a minute.
  • An edit may remove every monitor; the editor then warns “This window covers no monitors, so it will not suppress anything.” A new window cannot be saved without a monitor.
  • In the API, a monitorIds list on PATCH replaces the coverage and keeps each remaining monitor’s own suppression. A monitors[] list replaces the whole coverage, and monitors: [] removes it.
  • Deleting (cancelling) an active window makes its monitors alert again immediately. The delete answers with a receipt: {"id": ..., "deleted": true, "type": "maintenance", "name": ..., "wasActive": ..., "cascaded": {"monitorSubscriptions": N}}.
  • The repeat type is fixed in the editor. A one-time window cannot become weekly or the other way round there; delete it and create a new one. The API can switch it with PATCH ("recurrence": null or a recurrence object).
  • Start dates in the past. The editor refuses a one-time start date before today (“Start date cannot be in the past”). The API accepts past dates, which is how you record maintenance after the fact so it shows on your status page history - see Show maintenance on your status page.
  • No tag scoping. A window covers a fixed list of monitor ids; there is no tags member. See Cover every monitor with a tag.
  • Length. At least 60 seconds (422 invalid_range, reason too_short); an end before the start is refused with reason inverted.
  • Validation refusals answer 422 validation_failed with a reason: required (a missing name, time or monitor), empty_selection (a monitor with neither alerts nor stats), conflicting_members (to and durationSec together, or monitorIds and monitors together), unknown_monitor (an id that is not yours). A bad day name is 422 unknown_enum_value; a zone that cannot be used is 422 with reason unmappable_timezone.
  • Daylight saving and one-time windows. The API computes to and state in real elapsed time, while the checking engine follows the wall clock of the window’s zone. For a one-time window that spans a clock change, the two can disagree by an hour about when suppression ends. Avoid scheduling one-time windows across a DST change, or pad them by an hour.
  • Over limit. A window marked over limit (overlimited: true) is saved but not applied because of an account-level billing restriction. Contact [email protected] if you see it.