v4.1.0

janhq/janv4.1.0Jun 13, 2026by rajnandan1

AI Summary

This release introduces a confirmation threshold feature for monitors to prevent transient status changes from affecting uptime, adds manual controls for maintenance events, enhances status page customization, and improves API functionality and database tuning.

Key Highlights

  • Confirmation Threshold (Grace Period): Monitors now require N consecutive checks to commit a status change.
  • Manual Maintenance Events: Users can now manually complete or cancel maintenance events in the UI.
  • Status Page Settings: Per-page controls for history counts, layout styles, and meta/social overrides.
  • API `~home` Token: The home page is now addressable via the REST API using `~home`.

Breaking Changes

  • Unmatched API routes now return JSON 404s instead of falling through to HTML pages.
  • Monitor deletion now explicitly cleans up alert-config rows (v2 alerts and trigger/monitor junctions).
  • Status transitions and window edits are now mutually exclusive in the v4 API.

New Features

  • Confirmation threshold (grace period) configuration for monitors.
  • Manual Complete and Cancel actions for maintenance events.
  • Last known status for 'None' monitor type.
  • Per-page status history (mobile/desktop) and layout styles.
  • Inline monitor toggles for active/visibility state.
  • DELETE /api/v4/monitors/{monitor_tag} endpoint.
  • Absolute URL fields in incident and maintenance API responses.
  • Sanitized HTML rendering for maintenance descriptions.
  • Searchable monitor picker for groups.
  • Database connection pool tuning and health checks.
  • Ukrainian localization.

Full Release Notes

## New features {#new-features}

### Confirmation Threshold (grace period) {#confirmation-threshold}

Monitors can now require **N consecutive checks** before a status change is committed, so transient blips no longer dent uptime % or the day bars.

- Set a per-monitor **Grace period** (1–60, default **1 = off**) in **Monitor → General Settings**, or via `confirmation_threshold` on the v4 monitor create/update API.
- Damping happens once in the scheduled-check write path. A new `monitoring_data.raw_status` column records what each check actually observed, while `status` holds the confirmed side.
- On the Nth consecutive opposite observation the status flips and the pending window is **retroactively backfilled** — a confirmed outage reads as down from its first failing check, and recovery is symmetric.
- Everything downstream — uptime %, day bars, badges, alert evaluation, group scoring — inherits the damped `status` automatically. Alerts compose by `max(grace period, failure threshold)`.

See [Grace Period](https://kener.ing/docs/v4/monitors/grace-period) for full details.

### Manual maintenance event transitions {#maintenance-manual-transitions}

Individual maintenance events can now be **manually completed or cancelled** from the maintenance management UI, letting the recorded timeline reflect what actually happened.

- New **Complete** and **Cancel** actions move an event to a terminal `COMPLETED` or `CANCELLED` status and adjust `end_date_time` accordingly.
- Terminal statuses are final — a completed or cancelled event can't be edited further.
- The v4 API supports status transitions alongside window edits, with the two enforced as mutually exclusive.
- Subscribers are notified of the transition.

See [Maintenance Events](https://kener.ing/docs/v4/maintenances/events).

### Last known status for "None" monitors {#none-last-known-status}

The **None** monitor type can now optionally reuse the **last known status** (status, latency, and source) instead of reporting no data when no value is pushed. Enable it with the new checkbox in the monitor configuration UI.

### Page settings {#page-settings}

Status pages gained per-page presentation controls, configurable in the manage UI and over the v4 pages API:

- **Per-page status history** — separate day counts for **mobile** (default 30) and **desktop** (default 90), each bounded to 1–365.
- **Monitor layout styles** — choose between `default-list`, `default-grid`, `compact-list`, and `compact-grid`.
- **Meta / social overrides** — per-page title, description, and preview image.

Page settings accept deep-merge `PATCH` payloads over the API, and invalid payloads are now rejected with validation errors.

### Inline monitor toggles {#inline-monitor-toggles}

The **Manage → Monitors** list now lets you flip a monitor's **active/inactive** state and **visibility** inline, without opening the full edit page for a one-bit change.

### API: address the home page with `~home` {#api-home-token}

The home page is stored with an empty path and previously couldn't be addressed over the REST API. `GET`/`PATCH`/`DELETE /api/v4/pages/~home` now targets it, and list and single-page responses render its `page_path` as `~home` so what you read is exactly what you can address. `PATCH` accepts every field except the (fixed) home page path, and `DELETE` is rejected with a 400. Unmatched `/api/` routes now return JSON 404s instead of falling through to an HTML page.

### API: absolute `url` on incident and maintenance responses {#api-absolute-url}

v4 API responses now carry an absolute `url` field so consumers link to the right page instead of concatenating ids onto paths:

| Response                            | `url`                                        |
| :---------------------------------- | :------------------------------------------- |
| Incident                            | `<site>/incidents/<id>`                      |
| Maintenance (list/get/create/update) | `<site>/maintenances/<id>?type=maintenance`  |
| Maintenance event                   | `<site>/maintenances/<event_id>`             |

The URL is built from the configured Site URL plus base path.

### API: delete a monitor by tag {#api-delete-monitor}

A new **`DELETE /api/v4/monitors/{monitor_tag}`** endpoint removes a monitor through the same path the manage UI uses. Monitor deletion now also explicitly cleans up alert-config rows (v2 alerts and the trigger/monitor junctions), fixing orphaned rows left behind on SQLite — which never enforced the `ON DELETE CASCADE` foreign keys. Shared alert configs survive until their last monitor is detached.

## Improvements {#improvements}

### Rich maintenance descriptions on list views {#maintenance-html-descriptions}

Maintenance descriptions now render as **sanitized HTML** on list views — the home page, custom pages, monitor pages, events pages, and embeds — matching the detail page. HTML formatting and line breaks display correctly instead of showing literal tags, with sanitization kept since these render to anonymous visitors.

### Searchable monitor picker for groups {#group-monitor-search}

The group monitor picker now has a **search bar**, making it practical to find and add monitors on instances with hundreds of them instead of scrolling a flat list.

### Database connection pool tuning and health checks {#db-pool-tuning}

The database layer now tunes connection-pool sizing, clamps the pool bounds to safe values, guards the Redis probe, and hardens the error page. The configured database type is logged at startup for clearer diagnostics.

### Broader alert evaluation {#alert-evaluation}

Consecutive status and latency checks now count **all alert-visible sample types**, improving alert reliability, and manually submitted data triggers a best-effort alert re-evaluation after updates.

### Localization {#localization}

- Added a **Ukrainian** translation.
- Fixed syntax errors in the **French** locale strings.
- Updated the default v4 **alert body** description, which still referenced pre-v4 template variables.

## Bug fixes {#bug-fixes}

- **Overall status now follows worst-wins ordering** (`DOWN > DEGRADED > MAINTENANCE > UP`) consistently across components, so an active maintenance no longer masks a real outage in the aggregated status.
- **Social preview images use absolute URLs** — `og:image` and `twitter:image` meta tags now prepend the Site URL, fixing previews that failed because of relative paths.
- **Fixed overlapping header sections** on the public page by adding a single frosted backdrop behind the fixed nav and the sticky theme bar, so page content no longer shows through while scrolling.