Skip to main content

what shipped, when.

One dated entry per change that reaches you. Also posted to GitHub Discussions and as an Atom feed.

Markdown in incident and maintenance text

Format what you write. Incident updates, maintenance descriptions and maintenance updates, and a postmortem's summary, root cause and impact now take Markdown: **bold**, _italic_, [links](https://…), bullet and numbered lists, and code. It shows formatted on the status page, the incident page, the console, the RSS feed and in the emails subscribers get. The console forms say so under the text box.

Plain text keeps working. Every line break you type still shows as a break, so text written before reads as it did. HTML is not markup here: a tag shows as typed rather than disappearing. A heading reads as a plain paragraph, an image as its description, and a link needs a full web or mail address.

Where it stays plain. History rows, the dashboard banner and the inbox preview line show the words without the markup, and a history row opens to the formatted version. The REST API, the MCP server and subscriber webhooks return the text exactly as written.

Docs: formatting.

Monitor groups that alert as one

One incident for many failures. Turn on alert as one for a group, and the first member failure opens one group incident that pages the group's channels or escalation policy. Members that fail later join it, and their own channels stay quiet. A DNS move that breaks the NS and A records sends one page, one set of reminders and one recovery.

A provider outage stays readable. The first message names every member that is down. Later failures arrive in at most one message a minute, so a hundred members failing together send one or two messages. Turn alert again off to keep later failures on the incident's timeline only.

Groups get their own settings. A group used to be a label. It now has a settings page: rename it, pick its channels, reminder, escalation policy (Team plan) and tags, see each member's own channels marked muted, or delete it. Open it from the ⋯ menu on the group's header in the monitors list. Switching alert as one on or off changes only failures that start afterwards.

On a status page. Add a group to a page as a live section: a heading with the members' combined state, and each member as its own row. Monitors that join or leave the group join or leave the page.

API, MCP and Terraform. The REST API has /api/v1/groups and section endpoints on status pages. The MCP server adds list_monitor_groups and update_monitor_group. Terraform provider 0.19.0 adds uptimepage_monitor_group and uptimepage_status_page_section, and group_name keeps working.

Docs: monitor groups.

Bogotá and Santiago probe regions

Monitors can now be checked from Bogotá and Santiago. With São Paulo, that makes three probe regions in South America: Bogotá is closest to Colombia and the north of the continent, Santiago to Chile and the Pacific coast. The hosted service now checks from thirteen regions.

Opt-in. New monitors still start in New York, Frankfurt and Helsinki. Tick Bogotá or Santiago on the monitor form, or pass sa-co or sa-cl in regions through the REST API. Existing monitors keep their regions until you add one.

Plans. Standard runs a monitor from up to three regions and Founding from up to five, any you choose. Pro and Team have no region cap.

Docs: probe regions.

Five new probe regions

Monitors can now be checked from five more places: Johannesburg, Sydney, Tokyo, London and Dallas. Johannesburg is our first probe region in Africa and Sydney our first in Oceania. Tokyo gives Japan and Korea a nearer vantage point than Singapore, London covers the UK, and Dallas fills the middle of the US between San Jose and New York. With them the hosted service checks from eleven regions.

Opt-in. New monitors still start in New York, Frankfurt and Helsinki. Tick a new region on the monitor form, or pass its id in regions through the REST API: af-za, apac-au, apac-jp, eu-london or us-central. Existing monitors keep their regions until you add one.

Plans. Standard runs a monitor from up to three regions and Founding from up to five, any you choose. Pro and Team have no region cap. Past your plan's count, adding a new region means unticking another.

Docs: probe regions.

HTTP checks keep cookies across redirects

Cookies carry across redirects. Some sites answer the first visit with a cookie and a redirect back to the same address, and serve the real page only once the cookie comes back. HTTP checks dropped that cookie between hops, so every run of such a monitor ended in "too many redirects" and its real status never showed. A check now sends cookies a redirect sets on the later hops of the same run, as a browser would. Each cookie goes only where its domain and path allow, a Secure one only over HTTPS, and no cookie can cover a whole public suffix such as co.uk. The cookies are dropped when the check ends, so every run starts with none, and their values never appear in probe output or errors.

Redirect loops are named. When a check runs out of hops on a redirect that would repeat a request it already sent, the error now says "redirect loop" instead of "too many redirects". That covers an address that keeps redirecting to itself with the same cookies, and two addresses bouncing between each other, such as http and https or www and the bare domain. A long chain across different addresses still says "too many redirects".

Configured cookies go out as one header. A monitor with Cookie header rows whose names differ only in case, such as Cookie and cookie, sent them as two Cookie headers, though a request should carry only one. They now go out as one header, together with any cookies a redirect set, and a configured cookie wins over one a redirect sets with the same name. A configured cookie is still left off a redirect to another origin.

More on what our checks send: our bot.

Status page subscribers get one mail per outage

One outage, two mails. Monitors on a status page that fail together now reach an email subscriber as one outage instead of one mail per monitor. The first mail goes a minute after the first failure and lists every component affected by then, each linking to its incident. The second goes once every component is back and the page has stayed quiet for 5 minutes, and says how long each was down. Five monitors down for two minutes send each subscriber two mails instead of ten. Updates someone writes still go out one by one, as written, and webhook subscribers still get every incident update.

Every subscriber gets the mail. All mail now goes out at one shared pace that stays under the mail provider's limit, so a burst of incidents no longer loses subscriber mail to rate limits. A rate limit, a quota or an outage at the provider makes a mail wait and never gives it up. Anything still unsent a day after the event is dropped as no longer news.

Webhooks are retried on the receiver's terms. A 429 or 503 with Retry-After is honoured, up to an hour later, without using one of the 8 tries. 410 Gone ends the delivery. Other failures are retried from 30 seconds apart, doubling up to 30 minutes.

Self-hosting. Every instance books its sends in one Postgres row, and together they stay under the mail provider's limit per second, which the email configuration sets. Sign-in links and alerts go ahead of subscriber mail. Two new metrics follow subscriber delivery: settled deliveries by status, and how long the oldest due one has waited.

Docs: subscriptions, metrics.

Monitors down for days are checked every 15 minutes

Checked less often after 3 days down. A monitor that has failed every check from every region for 3 days, with its incident open as long, is now checked every 15 minutes from each region instead of on its own interval. It is usually a test server that was switched off or a site that moved, and probing it every minute only confirms the same failure.

Back to full speed when it recovers. It goes back to its own interval when its incident closes or a maintenance window covering it starts, and at once when you edit, pause or resume it. After a fix, run a check from its page: a passing result puts it back straight away.

The outage stays on record. The incident stays open, uptime counts the whole stretch as down, and status pages are unchanged. The stored interval never changes, so Terraform sees no drift.

One email, and a mark in the app. The monitor's owner, or the organization's first owner when it names none, gets one email asking whether they still need it, with a link to its page to pause or delete it. The monitor page shows the slower rate and since when, the monitors list marks the row, and the API and MCP tools return slowed_at.

Docs: long-down monitors.

São Paulo probe region

Monitors can now be checked from São Paulo, Brazil. It is our first probe region in South America, alongside San Jose, New York, Frankfurt, Helsinki and Singapore.

Opt-in. New monitors still start in New York, Frankfurt and Helsinki. Tick São Paulo on the monitor form to add it, or pass sa-br in regions through the REST API. Existing monitors keep their regions until you add it.

Plans. Standard runs a monitor from up to three regions and Founding from up to five, any you choose. Pro and Team have no region cap. Past your plan's count, adding São Paulo means unticking another.

History. Results from São Paulo are stored per region like every other, so the per-region latency chart and the region filter on the monitor page pick it up straight away.

Docs: probe regions.

Certificate, DNS and domain checks show what they read

What the last check read. A passing certificate, DNS or domain check kept nothing of what it read, so its monitor page showed little more than a latency chart. The monitor page now shows the reading. A certificate monitor shows the days left, the date, who it is issued to and by whom. A domain monitor shows the days left and the registrar. A DNS monitor shows the records each region got, with an unexpected one marked + and an expected one that is missing struck through. When regions read different things, the worst reading comes first, so a stale certificate on one edge or a region that gets other answers stands out. raw json shows each region's reading as it is stored.

What failed, in the check log. A failing check's line in the check log now names the values: A records −192.0.2.10 +198.51.100.7 · example.com, or the issuer of a certificate about to run out. Open the line to see every record. On a share link the line keeps its short sentence, without the values.

DNS failures in words. A failing DNS check used to read "check failed". It now says what went wrong: no records of the type you asked for, a record set that changed with how many records are missing and unexpected, or no record holding the value you expect.

Through the API. A certificate, DNS or domain result that read something carries details, passing ones included. A failing result keeps its error text, except that DNS answers in it are now sorted, so an answer that only changed order reads the same.

Fixes.

  • A DNS monitor on a wildcard name such as *.example.com was refused. It is accepted now; a * anywhere but the leftmost label still is not.
  • A certificate that stores its names in an old string type, common on certificates issued years ago, was named <no CN> in alerts and the check log. Its subject and issuer read correctly now.
  • After a domain monitor's domain was changed, a failed lookup could report the old domain's expiry. It reports the failure until the new domain's first good lookup.
  • The subscribe form on a status page answered 403 to someone also signed in to the console in the same browser. It works now.
  • Self-host: builds from this one on start on a database a newer build has already migrated, so rolling back to them works when the newer migrations only add to the schema.

Docs: certificate monitors, domain monitors, DNS monitors, results through the API.

Recently shipped: IPv4 or IPv6, longer intervals, bulk edits

IPv4 or IPv6. HTTP, TCP and certificate checks raced IPv6 against IPv4 and kept whichever connected, so a broken AAAA record or an IPv6 firewall stayed hidden while IPv4 worked. A monitor can now be pinned to one of them. It asks DNS for that family's addresses only and dials nothing else, and a host with no address of that family fails the check instead of falling back to the other. To watch both, create one monitor for each. Set it on the monitor form, as ip_version through the API, or in Terraform provider 0.17.0.

Longer intervals. The monitor form offers 6, 12 and 24 hours for HTTP, TCP, ping, DNS and flow monitors. The API and Terraform already took them.

Bulk edits. Select monitors in the list to change their check interval or their notification channels in one go: add a channel, remove one, or replace them all. A monitor that cannot take the interval keeps its own, and the reply says which and why.

Where a failed check went. After a hostname moves, resolvers keep the old record until it expires, so probes keep reaching the old server and the failure looks like a fault on the new one. A failed HTTP check now shows the server address that answered, the addresses it tried, and what the probe's resolver answers for the host and for how long. An incident's page lists the addresses behind its failed checks with the regions that reached each. Share links, status pages and notifications never show them.

Resolve from an alert. A channel can carry a Resolve button next to Acknowledge, off until you turn it on. It shows on every channel that carries Acknowledge except ntfy, and a press closes the incident only for a signed-in member, or in a chat app for an account a member linked, so the incident always closes under a name.

Incidents without a monitor reach their pages. A declared incident with no monitor said it was published but showed on no page. It now names the status pages it goes on, from the declare form, the incident page, the API and MCP.

Deleting a monitor keeps its incidents. Deleting a monitor used to delete its incidents and the alerts sent for them. They now stay, under the monitor's name. An incident the monitor opened closes with a note that monitoring was removed, and the channels it paged are told; one a person declared stays open for someone to resolve.

Docs: IP version, intervals, acknowledging and resolving, publishing an incident.

A page password for private status pages

One password, shared. A private page now has two ways in, the emailed code and a page password, and either one lets a visitor in. The password suits readers an email list fits badly: people on personal addresses, a partner's NOC, a wall screen. Turn it on in the access tab, type one or press generate for a 20-character one, and copy it before you save. It is stored as a hash, so it can be replaced but never shown again.

Changing it shuts everyone out. Password visitors are anonymous, so there is nobody to block one by one. A new password, or turning it off, signs out every device that came in with it. Turning it off keeps it, and turning it on again brings the same one back. Sign them all out ends the open sessions and leaves the password as it is.

Guessing is slow. Ten wrong tries in 15 minutes from one network, then the sign-in screen says how long that network waits. The page itself never locks, so wrong tries from one place cannot keep everyone else out.

Subscribing. Someone signed in with the password subscribes by email and confirms the address first, as on a public page. Those subscriptions are marked via password and end when the password changes.

API, MCP and Terraform. access.password in the REST API sets the password (write only, never read back), and access.session_days now applies to both ways in. The MCP tools turn a stored password on or off but never take one. Provider 0.18.0 adds a write-only password to uptimepage_status_page and moves session_days to match.

Docs: who can open a page, status pages through the API, Terraform.

Maintenance updates, and finished maintenance in the history

Status updates. A maintenance window now takes updates, like an incident: a reminder before it starts, a line when the work runs late, how it went once it ends. Post one from the window's new page in the console, through POST /api/v1/maintenance/{id}/updates, or with the MCP tool post_maintenance_update. The status page shows the newest one under the window, and email and webhook subscribers get each one (type maintenance_update). A completed window still takes updates, so you can add a closing note.

Maintenance days. On the 90-day strip, a day a window touched shows as maintenance, and time inside a window no longer counts against the uptime figure. An outage outside the window on the same day still counts. Hover over a maintenance day, or tap it, to open the window in the archive. A monitor added to a running window counts from when it was added, and one dropped from it counts until it was dropped.

Finished maintenance in the history. Ended windows now sit in the page history next to past incidents, newest first, with All, Incidents and Maintenance tabs on the page and in the 90-day archive. A row opens to the window's description and every update. The history section shows on a quiet page too, and always links the archive. GET /api/public/v1/maintenance/past lists ended windows, and /api/public/v1/status carries recent_maintenance.

A page keeps what it showed. An incident or a started window stays in the page history, under the name the page gave the monitor, when that monitor is removed from the page, deleted, or dropped from a running window.

Upcoming windows. The page lists windows up to 30 days ahead, and every window time names its zone.

Date and time picker. A window's start and end, and an on-call handoff, are now picked in the console's own date and time picker, with a 24-hour clock.

Updates post once. The update routes for incidents and for maintenance accept an Idempotency-Key, and the console sends one, so a retried or double-clicked update is posted once.

Docs: scheduling maintenance, status updates, what the page shows, idempotency. Guide: how to announce scheduled maintenance.

Private status pages for the people you list

Private pages. A status page can be public, private or off. A private page opens only for the email addresses and domains on its access list: example.com lets in everyone at that domain, and an address lets in one person, up to 500 entries. Pick private under who can open it in the page editor and fill in the list on the new access tab. Private pages come with the Team plan, and with every self-hosted install.

Signing in. A visitor sees a sign-in screen in the page's branding and language, enters their email and gets a 6-character code and a sign-in link. Every address gets the same answer, so the screen never tells anyone who is on the list. After the first code, a viewer can save a passkey and skip the email next time. You choose how long a sign-in lasts (until sign-out, or 7, 30 or 90 days) and whether passkeys are offered.

Everything sits behind the sign-in. The page, the incident history and detail pages, the JSON API, the badge and the RSS feed answer only a signed-in viewer, and none of it is cached or indexed. A viewer's feed reader gets a personal link that stops working when they lose access.

Subscribers. Making a page private removes its webhook subscribers and the email subscribers the list does not cover. A signed-in viewer subscribes as themselves, with no confirmation mail.

Viewers. The access tab lists who signed in, when they last visited and their history for the past year. Block signs someone out at once and keeps them out whatever the list says.

API, MCP and Terraform. The access field of a status page sets the list and the sign-in options through the REST API and the MCP tools. Provider 0.16.0 adds an access block to uptimepage_status_page.

Off pages stay quiet. A page that is off no longer sends mail or webhook calls to its subscribers, and nothing is sent for an organization that was deleted.

Docs: who can open a page, status pages through the API, Terraform.

DNS monitors can expect an exact record set

An exact record set. A DNS monitor used to pass when an answer contained a piece of text. It can now list every record the answer must hold, one per line, and goes down when a record is added, removed or changed: a stray MX, a dropped A record, an edited SPF line. Pick exact set under the answer match in the monitor form, or send expected_records through the API or the MCP tools. Up to 50 records.

How records compare. Order and repeats do not matter. Names compare without case or the trailing dot, and numbers and addresses by value, so 10 Mail.Example.com matches 10 mail.example.com. and 2001:0db8::1 matches 2001:db8::1. TXT and CAA values compare as written, case included. Write a record the way the result's answers show it, or in zone file form. A value the record type could never answer with is refused when you save, so a typo cannot leave a monitor down for good.

See what changed. When the set differs, the result lists the records that are missing and the ones that are unexpected. Answers now hold only the record type you asked for; a CNAME chain the resolver followed shows under aliases. A contains match still searches the chain, so existing monitors judge as before.

Underscore names. Names such as _dmarc.example.com, s1._domainkey.example.com and _sip._tcp.example.com were refused when you created the monitor. DNS monitors accept them now.

PTR on an IP address. A PTR monitor on an IP address sent a forward lookup and failed on every check. It now looks up the address's reverse name. The other record types refuse an IP address when you save, since they could never pass.

Terraform. Provider 0.15.0 adds expected_records to the dns block of uptimepage_target and accepts underscore names.

Docs: DNS monitors, DNS through the API, Terraform.

Duplicate a monitor into many

Duplicate a monitor. Pick duplicate in the menu on a monitor's row or page. Each copy runs with every setting of the source and gets its own name and, if you like, its own URL, host or domain. Paste a list of addresses into one box to add a row for each. Up to 100 copies go in one batch, and the batch is created entirely or not at all.

Everything carries over. The old copy filled in the create form in your browser, so it dropped credentials set through the API, the regions and the escalation policy. Duplicate copies the saved monitor instead: the check with its credentials, the interval, the paused or running state, tags, group, alert channels and regions. The escalation policy comes along when you could attach it yourself, as the org owner on a plan with on-call. You own the copies, and a heartbeat copy gets its own ping URL. History, incidents, status page components and share links stay with the source.

Through the API. POST /api/v1/targets/{id}/duplicate takes a list of copies, each with a name and an optional address. It counts against the bulk rate limit and accepts an Idempotency-Key header.

Also fixed.

  • A retry with the same Idempotency-Key used to get the first answer back for 24 hours, even when that answer was a 429 or a 5xx. Only a success is kept now, so a retry gets a fresh answer.
  • A bulk create with a very large response could create every monitor and then answer 500, inviting a retry that made each one twice. It now answers with the monitors.
  • Creating a heartbeat could answer with an error after the monitor was saved, so a client or agent that retried got two. The create now succeeds whenever the monitor is saved.

Docs: duplicating through the API, idempotency.

Passkeys work in Bitwarden and other password managers

Passkeys from password managers. Sign-in never asks for your address first, so it can only use a passkey kept on the authenticator itself. Registration asked for one without requiring it. Phones, laptops and security keys kept one anyway, but password managers that do exactly what they are asked, such as the Bitwarden browser extension, saved a kind sign-in cannot use, and adding the passkey failed. Registration now requires a passkey kept on the authenticator, so these password managers save one you can sign in with.

Left over from a failed try. A passkey from an attempt that failed never reached your account. Delete it from your password manager, then use add a passkey on your account page again.

Docs: passkeys.

A System theme that follows your OS

System follows your OS. The new System theme shows the Dark theme when your operating system is set to dark, and the light Default look otherwise. It checks once per page load, so a chart never changes colour while you read it. Pick it, or any of the other 13 themes, under appearance on your account page.

Default moves to System. System is now the theme a new account starts on, unless you picked a mode on the website first. Accounts that were on Default have moved to it, so if your OS is dark, the app is dark now too. Pick Default again to keep the light look. Any other theme you chose stays as it was.

Native controls match. Dark themes now tell the browser they are dark, so scrollbars, date pickers and other native controls render dark instead of white. The Dark theme draws its accent buttons in white with dark text instead of pink. The legal pages on the app follow your theme too.

Pick before you sign up. The website has a light and dark switch in its header, or in its menu on a phone. Use it before you sign up and your new account starts in that mode: Default for light, Dark for dark. After that the switch changes only the website, never your account's theme.

Docs: the web UI.

Calmer status pages, and a recovery period for flapping

Day colours follow downtime. A day on the 90-day strip used to take the colour of the worst thing that happened, so a four-minute blip painted it as red as a lost afternoon. The colour now follows how long the component was down, weighted the way Atlassian Statuspage weighs it: a partial outage counts for 30% of its length, and degraded performance does not count as downtime. Under 20 minutes reads yellow, 20 to 60 orange, an hour or more red. Hovering a day lists the time it spent in each state.

Uptime weighs downtime the same way. The uptime figures on the status page, the dashboard, the monitor list and page, the uptime API and the MCP tools now count a partial outage at 30% of its length and leave degraded performance out, so the number beside a strip agrees with its colours.

Past incidents fold. The past-incidents list was a card per incident, so a service that flapped for an hour filled the page. Incidents on one component less than an hour apart, and incidents on different components that began together, now fold into one row that opens to the incidents inside it. An incident you posted an update to keeps its own row with your words; the lines the platform writes for you are left out. The last week is open and older incidents sit behind one toggle. The archive lists each month the same way.

A recovery period for flapping monitors. A monitor can now wait out its recovery before its incident closes: set Close incident after in the monitor's detection settings, or recovery_period_secs through the API and MCP tools. A failure that confirms inside the window keeps the same incident open, so a service that keeps falling over is one incident and one set of alerts. The end is still dated to when the last recovery began, so the wait is not counted as downtime, and while it waits the monitor reads as back up: paging pauses, the status page shows it operational with the incident as Monitoring, and the console marks it recovering. If it falls over again inside the wait, the minutes it was back up still do not count as downtime. HTTP, TCP, ping, DNS and flow monitors, existing ones included, wait three minutes unless you pick another hold; choose at once to close as soon as the checks pass again. Heartbeat, manual and expiry monitors still close at once, since their next check can be hours away.

Recovery is judged per region. A region now counts as recovered only after as many passing checks in a row as it took failing ones to count as down, and a region that never failed is no longer evidence that the others recovered. A stray failed check no longer moves an incident's end.

Docs: public status page, incidents, API.

Status pages in German

Each status page now has a language. English stays the default, and German is the first one added. Set it under Language in the page editor, or as public_locale on the page through the REST API.

What changes. Everything the page writes itself: status labels and headings, the subscribe dialog, dates and durations, the title of an incident you never named, the status badge, and the confirmation, incident and maintenance emails your subscribers get. A German page formats dates the German way in every browser and sends Content-Language: de.

What stays. Text you write appears as written: page, component and group names, the about text, incident titles and updates, and maintenance windows. Email times stay in UTC.

One language per page. A page with two audiences is two pages, each with its own subscribers.

Terraform. Provider 0.14.0 sets the page language with locale on uptimepage_status_page. Leave it out to choose the language in the console instead. Removing the line keeps the language it set, so set en to switch back.

Docs: public status page, per-org status pages, Terraform.

Manual monitors for services no probe can check

Some services can only be judged by the people running them: a SIP trunk, a carrier interconnect, a partner's back office. A manual monitor puts them on your status page next to everything else. It has no probe, and its state is whatever someone last set.

Set the state. A manual monitor starts up. Set it to up, degraded or down from the monitor page, with PUT /api/v1/targets/{id}/state, or with the MCP set_monitor_state tool. An optional note of one line, up to 200 characters, becomes the incident's cause, so write it for whoever gets paged.

Like any other monitor. Down or degraded opens an incident within about 30 seconds and pages its channels, unless a maintenance window holds paging. Status pages show a major outage or degraded performance, and up closes the incident. There is no confirmation count to wait out, because the person who set the state already confirmed it. Downtime counts against uptime, and the monitor counts toward your monitor limit.

Who and when. The monitor page shows when the current state was set and which member set it. Every change is recorded with who made it, and setting the same state with the same note again changes nothing. A manual monitor that is paused, or that your plan no longer covers, keeps the state you set and reports it once it runs again.

Access. Reading the state needs targets:read and setting it needs targets:write, so existing tokens and MCP connections with those scopes can use it now.

Terraform. Provider 0.13.0 declares one as check = { type = "manual" } on uptimepage_target, with interval = 60. The state is not configuration, so a set in the app never shows as drift.

For every monitor. An incident that opened as degraded is now raised to an outage once its monitor is confirmed down, so its status pages show an outage instead of degraded performance. It used to keep the impact it opened with.

Docs: manual monitors, REST API, MCP server, Terraform.

Schedule maintenance windows from your AI assistant

The MCP server can now manage maintenance windows, the same ones the console and the API schedule.

Read. list_maintenance lists windows by status (active, upcoming or past), and get_maintenance reads one, with the monitors it covers and whether it holds their paging.

Schedule. create_maintenance takes a title, a start and an end, and the monitors the work touches. Paging for those monitors is held while the window runs unless you turn that off, and the checks keep running, so it is the gentler choice than pausing a monitor. The confirmation names the monitors, says whether paging is held, and says which of them sit on a published status page, because that page's subscribers are told about the window.

Edit, end, cancel. update_maintenance changes an upcoming or running window and shows the old and new value of each field. Its end_now flag ends a running window at once. cancel_maintenance withdraws a window that has not ended and keeps it under past as a record. A completed window is history and is refused.

Access. The read tools need maintenance:read, now part of the read only grant. The write tools need maintenance:write or maintenance:delete, which come with the Manage monitors level on the consent screen. A connection keeps the scopes it was granted, so reconnect to add these.

Docs: MCP server, scheduling maintenance.

Schedule maintenance windows from the console

Maintenance windows used to be API only. The console now has a Maintenance page for them.

Schedule. Pick the monitors, a start and an end in your own timezone, and an optional description. Readers see the window on your status page, and subscribers get a notice when you schedule it and another when it ends. A monitor that is not on a status page is flagged in the picker, because readers cannot see it there.

Hold paging. On by default. A monitor inside a running window still opens incidents, but its channels stay quiet, and an incident still open when the window ends pages then. Turn it off to keep paging live. An incident you declare by hand always pages.

Edit, end, cancel. An upcoming window can be edited or cancelled. A running one can be edited or ended now. Cancelled windows stay under Past with who cancelled them and when, and every change is written to the organization audit log.

Quota. Only windows that have not ended count toward the limit. Completed and cancelled ones are history.

API: a PATCH that sets ends_at to now or earlier on a running window ends it at the server's clock, status=upcoming now lists the soonest first, and a window can no longer be created or edited to end in the past otherwise.

Docs: scheduling maintenance, REST API.

Acknowledge from chat and email alerts, and see who did

You can now acknowledge an incident from its chat and email alerts, and the incident shows who acknowledged it.

Who acknowledged. Any member can acknowledge, on call or not. The dashboard banner, the console and the incident page list who acknowledged, in order. The first keeps the credit: they stay the acknowledger on record, and their time is what MTTA measures. Once you have acknowledged in your own name, the button there goes away for you, and a reopened incident starts a new list.

From chat and email alerts. Slack, Discord, Microsoft Teams, Google Chat and email alerts carry an Acknowledge button, and Mattermost alerts end with an Acknowledge link. It opens the incident's acknowledge page, where you sign in and take it in your own name. Opening the page changes nothing, so a link preview or a mail scanner cannot acknowledge for you, and an alert from an earlier outage takes nothing once the incident has come back.

Inside Slack and Discord. A channel connected with add to Slack or add to Discord from now on carries an Acknowledge button that works in the chat itself. A press acknowledges at once. Until you link your Slack or Discord account, it is recorded as coming from Slack or Discord, and the reply, which only you see, brings a link: open it, sign in, and later presses carry your name. The chat also gets a reply under the alert naming who took it, without mentioning anyone. A channel whose webhook was pasted, or one connected before this change, keeps the page link.

Telegram and Pushover. A page from the Uptimepage Telegram bot now carries an Acknowledge button, and a Pushover emergency acknowledgement reports who took it. Link Telegram from your account settings. Pushover links itself: acknowledge an emergency page from an account nobody has linked, and it brings you a one-time link, at most once a week. A name is never guessed from where a page was sent, since a shared chat or a Pushover group reaches more than one person.

Turning the button off. Every channel that carries the button has an Acknowledge button switch, on by default. Turn it off for a room shared with a customer or an open ntfy topic, and the buttons already sent stop working too. The API takes it as acknowledge_button.

On a self-hosted install, the buttons inside Slack and Discord need your own Slack and Discord apps, and the Telegram button needs a central Telegram bot, each set up as the configuration docs describe. Without the Slack and Discord apps, those channels keep the page link.

Docs: acknowledging from the notification, the incident console, Slack and Discord app setup.

On-call schedules and escalation policies

An incident on a monitor can now page whoever is on call. On the hosted service this is part of the Team plan, and a self-hosted install always has it.

Schedules. A schedule is one or more rotations, called layers. People hand off daily or weekly at the same local time, even across daylight saving, or on an interval you set. A layer can be on call at all hours or only in the hours you give it, such as Monday to Friday 09:00 to 17:00. The first layer on call at a moment is the one that pages, so working hours on one rotation and nights and weekends on another fit in one schedule.

Calendar and overrides. A saved schedule's page shows a calendar of who is on call each day. Click a start day and an end day, then pick who covers, to hand a holiday or a swap to someone else without touching the rotation.

Your shifts. Each person picks the channels that page them on the on-call page. Until they do, a page on their shift reaches no one, and the page says so. The same page lists their next shifts in the organization and offers a private link that Google Calendar, Apple Calendar or Outlook can subscribe to.

Escalation. A policy is a ladder of levels. Level 1 pages when an incident opens, and each level waits before the next one pages. A level can page notification channels, on-call schedules, or both. Bind a policy to a monitor, or make it the default for every monitor without its own. A monitor with a policy pages the policy's levels instead of its own channels, so put those channels on level 1 to keep them. Acknowledging or resolving the incident stops the escalation.

Docs: on-call schedules, paging and escalation.

Alert mail over a fresh connection, and probe errors that say why

Alert emails go out over a fresh connection. On the morning of 21 September about half of alert emails failed their first send and arrived minutes late on a retry; a handful were dropped after the retries ran out. The sends were reusing a connection to the mail provider that had gone dead. Every alert mail now opens a fresh connection, and a retry can no longer race a first attempt that is still in flight, so an alert is sent once.

Mail comes from hello@uptimepage.dev. Alerts, sign-in links and invitations used to come from a no-reply address. Replies to hello@ reach a person.

Pages with large headers are up again. A site that answers with more than 16 KiB of response headers, such as finance pages with long preload lists, was recorded as down with a "transport error" while it was serving fine. The probe now accepts up to 256 KiB of headers over HTTP/2 and 1024 header lines over HTTP/1.1. Sorry to everyone who was paged for a healthy site. A test check's header preview now cuts a value over 512 bytes, and a cut body snippet ends in "…".

Probe errors say what happened. A request the server dropped after the TLS handshake used to show a bare "transport error". The monitor, the API and the MCP server now say "server reset the connection before responding", "server closed the connection before responding", "server sent an invalid HTTP response", or the HTTP/2 reason the server gave. When the probe itself refuses a response, the error says so instead of blaming the server.

A new account's org gets its owner's email channel. A signup through a magic link got an org with no notification channel, so its monitors paged nobody until one was added by hand; GitHub and Google signups already had the owner's address seeded. Every org a sign-in opens now gets it. An org created from the console is unchanged: add a channel to it yourself.

Self-host. The [email] block is checked at boot: from_address must be a bare user@domain and is required under resend, provider must be resend or log, and a no-reply sender is warned about. A half-configured mail setup now refuses to start instead of failing on every send. See configuration.

One uptime figure, and subscribers hear the start

One uptime number. The dashboard and the monitor page counted confirmed incident downtime; the monitors list counted failed checks. The same monitor read 99.99% on one screen and 99.76% on the next. The list now uses the confirmed figure too.

Status page uptime is time-based. It used to be days without an incident over days with data, so a four-minute outage in ten days of history read 90.00%. It now reads 99.97%: confirmed downtime over the time the component has been probed. uptime_pct is on the public API as well.

Status page cards use the strip's words. The history strip said "Partial outage" while the incident card said "Major". Cards now carry the measured impact (Degraded, Partial outage, Major outage) for monitor-opened incidents and the declared severity's impact for declared ones. The public API adds impact beside severity.

Subscribers hear the outage start. A monitor-opened incident on a status page posted only its closing update, so subscribers received one mail, "Resolved", after the fact. The writer now posts an opening update too, and the mail is titled the way the page titles the incident instead of "Status update".

Console. The dashboard incident count is labelled with the range you picked. The monitors list offers ping, heartbeat and flow in the type filter, its heading count follows the filters, and the URL it pushes survives a reload.

A monitor's type is fixed after creation

The edit form never offered it, but PATCH /api/v1/targets/{id} accepted a check of a different type: an http monitor rewritten as a heartbeat, or back. The monitor kept its id, so both kinds' results landed in one history and uptime was computed across them.

The API now refuses it with 400 CHECK_KIND_IMMUTABLE. Change any other field of the check freely; to watch something of another kind, create a new monitor. The same rule holds at the database row, so no other writer can slip past it.

If you manage monitors with the Terraform provider, version 0.12.0 plans a type change as a replacement: the old monitor is destroyed and a new one created. Older provider versions fail at apply.

Docs: REST API.

Fixes from September worth knowing about

Heartbeat monitors. Heartbeats created through the first version of the form were judged hours apart, so a missed ping was noticed late and a manual resolve reopened the same outage. Existing intervals were corrected to a tenth of the window, between one and five minutes, and the API now refuses a coarser one. If you have heartbeats, they page faster now.

Telegram supergroups. When a group is upgraded to a supergroup, Telegram gives it a new chat id and the old one dies. The channel now follows the move on the first failed send and saves the new id. Bring-your-own bots are covered too.

Incident region breakdown. With majority quorum the last region is usually one check behind when the incident opens, and alerts named it under "up". It is now "not confirmed", and the breakdown widens as regions confirm instead of staying frozen at the snapshot taken at open.

Self-host. A region can be opted out of new monitors' defaults with regions.default_selected. It stays pickable on the form, just starts unchecked. See multi-region probes.

MCP: set up a whole org from your AI client

The MCP server now covers the setup path, not just reads. 16 read tools and 15 write tools, every write behind a confirmation in the client.

  • create_status_page, update_status_page, add_status_page_components and update_status_page_component. Owner-gated, same bar as the REST API.
  • create_monitors puts a batch behind one confirmation instead of one prompt per monitor.
  • HTTP checks take request headers and a body. A credential is referenced as Bearer {{ key }} from your org variables, never pasted. A pasted literal is refused.
  • Monitor create takes regions and binds notification channels, so a monitor made from a client pages someone from the first check.
  • get_org_usage tells you which org the token is bound to. Scope and org refusals say how to rebind.

One setup page per client, each with the exact config for that client: Claude, Cursor, VS Code, Grok. Hub: /mcp-server.

Reference: MCP server docs.

Status page: noindex, link to your site, powered-by toggle

Three small status page controls.

Hide from search engines. The page, its incidents and the archive carry noindex. The URL keeps working for anyone who has it. For a page you share with customers by link but do not want indexed.

Header link. With a website set, the logo or display name in the header links to your own site, so a reader has a way back other than the browser button. Every plan gets the link; on hosted it carries rel="nofollow" unless the plan includes white-label, so an open signup cannot be farmed for backlinks.

Powered-by toggle is in the page editor. It used to be API-only, and saving the editor cleared it. Honoured on plans with white-label; elsewhere the badge always shows.

Also fixed: a grouped page now keeps the component order you dragged it into.

Docs: public status page.

Mattermost and Gotify channels, and acknowledging from the phone

Two new notification channels.

Mattermost. Incoming webhook, works on Mattermost Cloud or your own server. Mentions use the server's own username rules, so directory-synced handles like svc.oncall.emea work.

Gotify. Point a channel at your Gotify server with an application token. Priority follows the client scale: 8 for a high-urgency open, 5 for other opens, 3 for a resolve. The incident link is the notification's click URL.

Acknowledging from the notification itself. An ntfy page carries an Acknowledge button, and acknowledging a Pushover emergency page in the Pushover app acknowledges the incident here too. That stops the repeats still going out on other channels. The link is signed, expires after a week, and is tied to the exact episode it was sent for, so a stale alert on a phone cannot silence a later outage.

Docs: notifications.

Three new free tools: SSL checker, domain expiry, redirect chain

No account needed, no email capture.

  • SSL certificate checker: chain, issuer, expiry, days left.
  • Domain expiry checker: registrar expiry for the domain, the thing that takes a site down with no warning.
  • HTTP header and redirect chain checker: every hop with its raw Location, the final status, and the full header set. Names the failures the last status code hides: a loop, a hop limit, a chain that leaves the host and drops cookies, a chain ending on plain HTTP.

All tools: /tools.

Organizations are managed from the console now

Until now there was no way to create a second organization in the app. The API existed, the button did not.

/settings/organizations covers create, rename, delete and restore. /settings/team is only about people.

  • Deleting an org asks you to type its name back.
  • A deleted org's slug is held for the whole restore window, so nobody can grab it in between.
  • If an org blocks your account deletion because you are its only owner, you can hand it a second owner instead of deleting it.
  • Sessions pointed at a deleted org are moved, not stranded on a login loop.

Docs: organizations.