Reference ›
Changelog
Changelog
What changed for users in 1.8.0, and since 1.1.
1.8.0
Destinations: as many as a workspace needs
- A workspace can send alerts to more than one place. A destination is a Slack incoming webhook or any HTTP endpoint, created in Workspace → Settings → Destinations, with a name, an address, an optional Slack channel and a switch. See Destinations.
- On upgrade, the webhook URL you had becomes a destination named
Default, enabled and marked as the workspace default. Alerting continues unchanged; the single Webhook URL field is gone from workspace settings. - One destination is the workspace default — what a subject sends to when it has chosen nothing of its own. The first one added becomes it; a workspace is allowed to have none, and deleting the default promotes nobody. A switched-off destination cannot be made the default.
- Send test posts one real message through the same render, transport and log a real alert uses, and reports what the far end said.
- Disable stops a destination without losing its address or the subjects pointing at it.
- The address is treated as a credential: the list shows it shortened, the edit form leaves it blank with a redacted placeholder, and delivery records never store it.
Alert delivery: the subject decides
- Each subject chooses which destinations it tells, and about what — Problems & reminders, No data, Recoveries — in an Alert delivery block on its own page. The marketing site telling nobody no longer stops the payments API paging the on-call. See Alert delivery.
- An empty table means one of two things, and the block says which: with a workspace default, alerts go there; with none, nothing is sent for that subject.
- A subject with rows of its own does not also send to the default — the table replaces the fallback rather than adding to it.
- Reminders ride with Problems & reminders: a destination that hears about problems hears the four-hour reminders too.
Transformations: what a destination receives
- Name a template and a destination gets that shape instead of the built-in message — a
PagerDuty event, your own JSON, a line of text.
{{ field }}placeholders over a published vocabulary of eleven fields. See Transformations. - A template is stored only once it renders all three messages — problem, no data, recovery. There is no force: a refusal names the sample that broke, and a broken edit leaves the stored template exactly as it was.
- JSON is escaped for you. A template starting with
{or[is treated as JSON: values are escaped as they are substituted and the result has to parse, so a quoted error cannot break the document. The content type follows the same reading. - Preview renders against all three samples without storing anything.
- A destination with no transformation gets Uptimer’s built-in Slack-shaped body, unchanged.
Delivery log
- What was actually sent, and what the far end said — payload, status and time, per destination, with an Undelivered filter. Open it from a destination’s More → View delivery. See Delivery log.
- Records are kept 30 days, then removed automatically. The period is fixed.
- A record keeps the destination’s name and type as they were at the attempt, so a rename or a delete later leaves the row still saying where the message went. The URL is never recorded.
- It is a read: nothing on the page sends, resends or changes a destination, and there is no retry.
API
- All of the above is scriptable.
/v2/notifications/destinations,/v2/notifications/transformations(withsamplesandpreview),/v2/notifications/deliveries, and a subject’s delivery table on the collection that owns it —/v2/subjects/{subject}/deliveryfor Custom,/v2/monitoring/websites/{id}/deliveryfor Website monitors. See the REST reference. - Same model as the screens: a destination created over the API is the row the dashboard lists, a test send is a real send, and the all-samples save rule applies to both.
- Reading these routes needs
EditWorkspace, not just membership — they carry webhook URLs and sent bodies. The transformation samples are the one open route. - Python SDK 1.8.0 wraps all of it — destinations, transformations, a subject’s delivery table
and the delivery log — and adds Custom signal and rule authoring.
pip install "uptimer-python-sdk>=1.8.0"; see Python SDK.
1.7.0
Acknowledging an incident
- Acknowledge an open incident from the subject’s page — where you land from Monitoring — or from a rule page. The timeline records who acknowledged it and when, so the next person to look can see somebody is already on it. See Monitors & incidents.
- One incident per press. A subject page acts on the worst of its open incidents, by the same order its status reads by, and names the rule on a Custom subject. It never acknowledges the rest.
- Monitoring shows who is on it. A subject’s row carries a small Acknowledged icon in its own column beside the status, with the acknowledger — and, on a Custom subject, the rule — in its tooltip. It follows the same open incident the subject page acts on, in every state, and goes when that incident closes.
- Find a custom subject’s open incidents over the API.
GET /v2/subjects/{subject}/incidentslists them with the ids acknowledgement takes, the rule each belongs to and whether somebody is already on it.GET /v2/incidentsis unchanged and stays the website path. - Acknowledge over the API.
POST /v1/rules/{uid}/incidents/{incident}/acknowledgefor a website monitor,POST /v2/subjects/{subject}/incidents/{incident}/acknowledgefor a custom subject — each kind of monitoring through its own API, no body, and one exact incident per call. See the REST reference. - It changes nothing about the incident. The verdict, the evidence and the locations are untouched, the close wait carries on, and recovery and closure happen as they would have. The one thing it changes about alerting is the four-hour reminders below, which stop for that incident; nothing else is silenced.
- Recorded once. The first acknowledgement is the one that is kept — pressing it again adds no second row and does not replace the original name or time. Acknowledging requires edit access, and a closed incident cannot be newly acknowledged.
Signals
- A signal’s page carries the signal, not just its log. Opening a signal now shows what it is and when it last accepted something, then Edit and Delete where they apply, then the request that sends an observation, and then its observation history — the same filter, day picker and paging as before. A website check’s platform HTTP signal shows its history without gaining those actions: its probe stays on the check form. See Signals & rules.
Maintenance windows
- Silence one subject while you work on it. Start a window on the subject’s page, choose when it ends, and its problem notifications wait until then — including for incidents that were already open. Recoveries are still sent, monitoring and the timeline are untouched, and the window survives a restart. End it early with End now. Monitoring flags the row while it runs. The control is two words and a button — no maintenance and Set — and Set opens two selects, days and hours, in the same row. A running window says ends after 1 day, 4 hours in the maintenance colour and offers End maintenance and Edit, where Edit is the same two selects filled in with what is left and moves the end of the same window, silently. See Maintenance and the REST API.
The subject page
- Acknowledgement and maintenance live in one block. A subject page now opens with Incident controls — the two things you do to a subject that is misbehaving — instead of spreading them through a header row shared with Edit, Add signal and Delete. Both work exactly as before.
- The maintenance row is quiet until you ask. It says no maintenance, or how long is left, with the buttons that act on it; the form — two selects, days and hours — takes the same row when Set or Edit opens it. Nothing floats over the page, nothing asks you to type a timestamp, and on a narrow screen the row wraps.
- A Custom subject’s signals are listed on its own page. The Signals block is a table — name, kind, when each last accepted something, and a View into the signal — with Add signal in its header. Signals (N) on the Monitoring list opens the subject page, and the dedicated Signals screen is one hop further in, for editing and deleting.
- Add rule sits with the rules. The Rules block carries Add rule beside View rules, and the page header holds neither Add. Add rule still waits until the subject has a signal for a rule to read; a Website subject has neither block.
- The Monitoring row opens View, not “Timeline”: the subject page is its incident controls, its signals, its rules and its timeline. Same page, same link.
Reminders
- A confirmed problem that nobody has answered repeats every four hours, through the same workspace webhook as the first notification, until it is acknowledged or it recovers. One reminder per incident, not per signal. See Reminders.
- Acknowledging stops them, recovery cancels them, and an active maintenance window pauses them. The incident’s state is re-read at the moment of sending, so a problem that recovered or was acknowledged in the meantime sends nothing.
- Nothing is ever replayed. A maintenance window ending, or a service that was down for a day, does not produce the reminders that were missed — the incident rejoins the ordinary cadence.
- The schedule is stored, so it survives a restart, and one due reminder is one message however many workers are running.
- Four hours is a fixed product default in this release: there is no reminder setting, screen or API, and no escalation or routing.
Reliability
- Server services survive a database outage. A server that cannot reach its database now
waits and retries — immediately, then after 5s, 15s, 30s, and every 60s after that — instead
of exiting on the first refusal, and picks up again when the database returns without a
restart. Availability checks pause for the outage rather than piling up, and a stop is still
immediate.
uptimer migrateis deliberately unchanged: it still fails immediately, so a rollout gated on it fails rather than hangs.
1.6.0
Custom checks
- Add Custom check creates a monitoring subject of your own, with nothing under it — no URL, no probe, no interval. It sits in the Monitoring list beside your website checks, and each row now says which kind it is. See Signals & rules.
- Add custom heartbeat and event signals to a Custom subject (Monitoring → the subject → Signals → Add signal). A heartbeat reports on a schedule and its silence can become no data; an event reports only when something happens and its silence means nothing.
- A Website check keeps its own shape. Its HTTP signal and its Reachability rule are created and rewritten by the check form, so it has no Add signal and no Add rule — you change it by editing the check. Custom signals and custom rules live on Custom subjects.
- Report observations over the API:
POST /v2/subjects/{subject}/signals/{signal}/observations, with a Bearer token. Astatusofokorproblem, plus an optional number, error text and your own labels. Retries replace rather than double-count. See Report an observation. - Platform HTTP signals do not accept posted observations. That stream is Uptimer’s own probe, and a posted claim is never mixed in with a measurement.
- A signal a rule reads cannot be deleted — the page names the rules and links to them.
The rules editor
- Add and edit rules on a Custom subject (Monitoring → the subject → Rules). A rule combines that subject’s signals and other rules of the same subject; cross-subject inputs are not possible.
- Choose what counts as a problem per input: Status, or Latest value compared with
<or>against one threshold. - Select observations by label — free-text keys and values, where
*matches any value of a key. - Quorum gains “At least N” beside Any, Majority and All, and Confirm after, Close after and per-input No data after are editable.
- Reachability is not edited here. A website check’s rule stays owned by the check form: its inputs are the locations it watches and its quorum is Locations Required to Fail, so it is changed by editing the check. It can be read, and it still cannot be deleted.
- A rule shows its policy in plain language on the rule page and in the rules list.
Monitoring list
- Each row is labelled Website or Custom. A Custom row links to that subject’s Signals (N) and Rules (N) and offers View rules; a Website row keeps Edit, which opens the website monitoring form.
- Delete removes a subject and its history, of either kind.
API and SDK
- A whole Custom subject can be built over the API.
/v2/subjectslists, fetches and creates Custom subjects;/v2/subjects/{subject}/signalsand/v2/subjects/{subject}/rulesadd, read, change and remove the signals and the rules under one;/v2/subjects/{subject}/signals/{signal}/observationsreports the readings. The API offers what the Custom screens offer. See the v2 reference. - The API is split by subject kind. Website monitoring is
/v1/rulesand its/v2/monitoring/websitesalias; custom monitoring is/v2/subjects. Neither serves the other’s subjects: a website subject is refused on every/v2/subjectsroute, and a subject being maintained by hand leaves the website listing and refuses website writes. Ordinary website monitors are unaffected, and v1 is otherwise unchanged and still frozen. See The API is split by subject kind. - Subjects created before 1.6.0 are classified once, on upgrade: one that already carried a hand-made signal or rule is Custom; everything else is Website.
- Python SDK 1.6.0 adds
client.v2.subjects.all(...)/.get(...)/.create(...)andclient.v2.subjects(subject).signals(signal).observations.create(...), with typed request/response models. Authoring signals and rules over the API is not in the SDK yet — call those routes directly. See Python SDK.
1.5.0
Monitoring is the one list
- Monitoring replaces the checks list as the workspace home. Each row is a monitoring subject with the status of its rules, filtered by All or With incidents, and links straight into that subject’s Timeline.
- The old checks list and the per-rule history page are gone.
/checksredirects to Monitoring, so existing links still land. Removed with them, and not yet replaced: the uptime history strip and sorting by name, status or up-since.
Adding a website
- The form is now Website monitoring. Saving it creates a monitoring subject with one built-in HTTP signal and one Reachability rule — you no longer create those separately.
- Locations Required to Fail gains “All locations”, alongside Majority of locations and At least one location. Each location you select becomes one input on the rule. See How many locations must fail.
- Creating signals and rules by hand, and custom ingest, are not in this release. The Add signal and Add rule actions are visible but marked coming soon.
Seeing why
- Timeline — what happened to a subject, newest first, with how long a closed incident lasted.
- Observation log — every report each location sent, with a day picker and paging. An Unaccepted filter shows rows that were stored but not used for a verdict, and why. This is what answers “the workers are running but the rule says no data”.
- Rule page — one input per selected location, what each is reporting, the agreement in force, and the confirm/close holds.
Alerts
- Slack alerts now link to the subject timeline instead of a rule’s history.
- Monitoring warns when the workspace has no Slack webhook: incidents are still detected and recorded, but nobody is notified until one is added.
API and SDK
- API v2 speaks the product’s language — locations,
website monitoring, incidents — and is self-contained: a v2 client never needs a v1 route.
GET /v2/incidentsanswers “what is wrong right now”. API v1 is unchanged and supported — every v1 route, field andkindstill behaves exactly as it did. - A website monitor can now set its location agreement over the API — the
agreementfield (any,majority,all). API v1 has no such field and keeps usingmajority. - Python SDK 1.5.0 targets v2 only:
client.v2.workspaces,client.v2.locations,client.v2.incidentsandclient.v2.monitoring.websitesreplace theclient.v1namespace — the version stays visible, as it did in 0.4.x. Its types are versioned with it:from uptimer.models.v2 import …, not the flatuptimer.models. Its version now tracks the server it talks to, andclient.check_compatibility()refuses a server that predates v2 with a message naming the fix. Staying on v1? Pinuptimer-python-sdk<1— 0.4.x keeps working against a 1.5.0 server.
API keys
- A token is shown once, when you create it, and can be copied from that screen. It cannot be viewed again afterwards and there is no regenerate — if you lose it, delete the key and create another. Previously the key’s page re-issued and displayed a working token on every visit.
- Keys take an optional description, so you can tell them apart once the value is hidden.
- The list shows when each token expires, and badges a key Expired once it is past. Keys created before 1.5.0 show no expiry: the page this replaces issued a fresh 180-day token every time it was opened, so the expiry of the token you hold is not recoverable.
- Rotating without downtime is unchanged and still the way to do it: create the new key, switch your client over, then delete the old one. Keys are independent, and deleting one stops its token immediately.
Identifiers
- The new Monitoring URLs use opaque ids, and so does the
idon an API incident — a database number is never exposed. Identifiers on existing pages are unchanged. The ids are derived fromserver.sqids_salt, so changing that value invalidates existing Monitoring links.
Fixed
- Success and error notifications could disappear before they could be read.
- Workspace notification help no longer implies a per-rule notification setting that does not exist: notifications are configured per workspace, and once a webhook is set everything in that workspace alerts.
- Security: a workspace member could read another workspace’s monitor configuration, or delete it, by using its identifier directly. Deleting it also removed its subject, signal, rule and history. All identifier-addressed routes are now scoped to the workspace in the URL.
1.4.0
Incident-based monitoring
- A monitor’s status is now decided across all of its locations, not by the newest check to arrive. The form gains Locations Required to Fail — Majority of locations (default) or At least one location. A location that never reports counts as unknown and stays inside the decision, so a half-silent monitor reads No Data instead of trusting whichever location answered. See Monitors & incidents.
- A problem must last 2 minutes before it is confirmed and alerted, and a recovery must last 2 minutes before the incident closes. Short blips no longer page you, though they do show up in the history.
- History is now a timeline of incidents — pending, problem, no data, recovering, closed — with the failing and silent locations on each event and the error they reported, replacing the old list of individual check results.
- The monitor list gains two badges — Pending and Recovering — shown while a monitor is inside one of the 2-minute holds.
- Slack alerts were rewritten. Each one now says how many locations are failing and which, quotes the error the check returned, and says how long the problem ran before the alert or how long the outage lasted. The monitor’s URL left the title, and the no-data alert is amber.
Checks identify themselves
- HTTP(S) checks now send
Uptimer/<version> (+https://uptimer.myuptime.info)instead ofGo-http-client/1.1, so you can recognise and filter monitoring traffic in logs and analytics. The value carries no workspace, worker or location, and is not configurable.
Logging out ends the provider session
- Signing out now also ends the session at your OIDC provider, so the next login no longer signs
the same person straight back in. Providers that advertise
end_session_endpointneed no configuration; for the rest, setserver.auth.oidc.end_session_endpointand, if it renames the return-URL parameter,server.auth.oidc.post_logout_redirect_param. See Authentication.
Workers no longer need a database
- A worker keeps its rules in memory and receives them over gRPC.
worker.db.dsnandUPTIMER__WORKER__DB__DSNare no longer read — still accepted and ignored, so existing configurations keep working. You can delete the setting and drop the seconduptimer_workerdatabase. A worker still needs its/datavolume forworker.uuidandworker.pem.
Security & reliability
- Patched vulnerable dependencies:
golang.org/x/textandgoogle.golang.org/grpc. - The worker is now a stateless library shared by every build, which removes a class of drift between how self-hosted and hosted workers behave.
- Fixed missing icons on the debug page.
Earlier highlights (1.1 → 1.3.0)
Packaging
- The image moved to GitHub Container Registry —
ghcr.io/myuptime-info/uptimer. Pull a pinned:X.Y.Ztag (or:edgefor pre-releases). The old Docker Hub image is retired.
Deployment & database
- New
uptimer migratecommand plusserver.db.boot_migrate— run schema migrations as a one-shot job and gate rollouts on a fully-migrated database. - PostgreSQL migrations are now versioned (with data backfills) and upgrade-safe; SQLite stays auto-migrated for dev. See Choosing a database.
Running Uptimer
server --services …replaces the oldruncommand — select services with--services api,ui,grpc,availabilities.- New
server.sqids_saltsetting (give it a unique value in production).
Monitoring
- Worker-regions management in the dashboard (still being refined).
- Assign regions when creating or updating a rule over the API — the rule payload takes a
regionsfield (region names), so a headless/SDK workflow can create a rule that actually runs instead of sitting at “No Data”. - New
grpc_request_duration_secondsmetric on/metrics.
Extensibility
- A pluggable architecture (job registry + route/gRPC extension seams) lets a build add services and routes without forking core.
Fixes & UI
- Smaller CSS payload and a faster dashboard.
- Correct paging on the availability-history view.
- UTF-8 characters render correctly in notifications.