Alerts

Getting told about a problem, on the channel you actually watch — and routing it to a human if nobody answers.

What are alerts?

An alert is Enori reaching out to you when a monitor changes state — it went down, it recovered, a certificate is about to expire. Alerts are delivered to channels you configure once and then attach to monitors.

There are two halves to it, and both have to be set up:

  1. A channel — where messages go. An email address, a Slack or Discord or Microsoft Teams webhook, your own HTTPS endpoint, or a PagerDuty service.
  2. A monitor's alert settings — when it fires and which of your channels it uses.

Example: "Create one Slack channel pointed at #ops, attach it to all 12 production monitors, and only alert after 2 consecutive failures so a single network blip doesn't wake anyone."

A monitor with no channel attached still records everything — it just never tells you. The monitor's Alerts card says so directly: "No alert channel — failures won't notify."


Alerts are not the in-app bell

Worth being blunt about, because it's the most common misunderstanding:

  • Alerts (this page) leave the product — email, Slack, Discord, Teams, webhook, PagerDuty. They're what wakes you up.
  • In-app notifications stay in the bell in the top bar. They're the record waiting for you next time you open Enori.

They're separate systems: an unread bell badge doesn't page anyone, and turning a monitor's alerts off doesn't empty the bell. See Notifications for the bell, its retention, and the full list of in-app event types. Everything below is about delivery.


The channels you can send to

ChannelWhat you supplyWhat arrives
EmailAn email addressA branded HTML email — status pill, headline, message, detected time, a View Monitor button, and action buttons
SlackAn incoming-webhook URLA coloured attachment with Monitor / Status / Message fields and link buttons
DiscordA webhook URLA coloured embed with Status / Time fields and an Actions row of links
Microsoft TeamsAn incoming-webhook URLA MessageCard with a branded header, a fact list, and action buttons
WebhookYour own HTTPS endpointA JSON POST you parse yourself — see Webhook payload
PagerDutyAn Events API v2 integration keyA PagerDuty event that opens an incident and closes it on recovery
TelegramA bot token + chat IDAn HTML-formatted message from your bot, with action links
Google ChatAn incoming-webhook URLA formatted message in the space, with action links
MattermostAn incoming-webhook URLThe same coloured attachment Slack gets, with action links in the text
PushoverYour user (or group) keyA push to your devices; high priority when something is down

Colour follows severity in every rich channel: red for a failure, amber for a warning, green for a recovery, cyan for informational.

Pushover is available — pick it from the Channel Type list like any other channel. It delivers through Enori's own registered Pushover application, so there is nothing for you to register: open your Pushover account, copy the 30-character user key from the top right of your Pushover dashboard, and paste it in. A group key works too. Your Pushover account's own terms and delivery limits are between you and Pushover; Enori doesn't change them.

SMS appears in the channel picker only when it's switched on for your account. If you don't see it in the Channel Type list, it isn't available to you yet, and trying to create one is refused with "SMS alert channels are coming soon and can't be created yet." If you do see it, follow Verifying an SMS number — an SMS channel can't deliver until its destination number is verified.


Setting up your first channel

Go to Alerts in the sidebar (/dashboard/alerts), switch to the Channels tab, and click Add Channel.

1. Channel Type — required

Pick one from the grid: Email · Webhook · Slack · Discord · Teams · PagerDuty (plus SMS if it's enabled for you). Email is preselected. The rest of the form changes based on this choice.

2. Name — required

How the channel shows up everywhere else — in the channel list, in the per-monitor picker, in alert history. Make it descriptive: "Ops Slack — #incidents", not "slack".

3. The destination — required

If you pickedFill in
EmailEmail Address — e.g. alerts@company.com
Slack / Discord / Teams / WebhookWebhook URL — must be HTTPS. URLs pointing at internal or private addresses are rejected.
PagerDutyIntegration Key — 20–64 characters, no spaces
SMSPhone Number in E.164 format — a +, country code, then the number (+15551234567)

Getting a Teams webhook: Teams channel → ⋯ menu → Connectors → Incoming Webhook → Configure.

Getting a PagerDuty key: in PagerDuty, open your service → Integrations → add an Events API v2 integration → copy its Integration Key. Enori masks it after saving — the list shows only the last four characters.

4. Assigned Monitors

Tick the monitors this channel should cover. They're grouped by monitor group, there's a search box, and Select All / Deselect All act on whatever the search is currently showing.

This step is optional in the form but not in practice — a channel with no monitors assigned never delivers anything. You can change the assignment any time by reopening the channel, and the channel card shows a "Used by N monitors" link that jumps straight there.

5. Create Channel, then Test

Click Create Channel. Back on the Channels tab, hit Test on the new card — it sends a real message through the real path, which is the only way to know the webhook URL is right. Testing is limited to 5 per minute.

A PagerDuty test is self-closing: it fires a trigger and immediately resolves it, so you get a triggered → resolved record instead of a stuck incident to clear by hand.

Verifying an SMS number

SMS is a paid, fraud-sensitive path, so Enori proves you own the number before it will ever text it.

After saving an SMS channel the modal switches straight to the verify step (an unverified channel also shows an amber Unverified · Verify button on its card). Enori texts a 6-digit code; type it in to confirm.

  • The code is valid for 10 minutes.
  • 5 wrong attempts kill the code — request a new one.
  • You can request at most 3 codes per channel per day.
  • Changing the phone number resets verification. The old confirmation doesn't carry over to a new number.

Until it's verified, the channel exists but sends nothing.


Choosing what each monitor alerts on

Channels are account-wide; when to fire is per monitor. Open a monitor, find the Alerts card in the right-hand rail, and click Edit ›.

SettingWhat it does
Alert when downNotify on failures. On by default.
Alert when recoveredNotify when it comes back. On by default. You only get a recovery notice where you got the matching down notice — see the note below.
Alert when overdueCron/heartbeat jobs only — notify when a run is late. On by default.
ChannelsWhich of your channels this monitor uses. Pick as many as you like.
Escalation PolicyOptional. None (Simple alerts only) by default — see Escalation policies.
Failures before alertImmediate · 1 · 2 · 3 · 5 consecutive failures.
Repeat alertsDon't repeat (default) · every 1 · 2 · 3 · 5 · 10 checks while it stays down.

Changes save as you make them — there's no Save button.

On "Failures before alert": this is the single most effective noise control. At 2, one failed check never produces an alert at all — Enori waits for a second consecutive failure. It also delays detection by one check interval, so it's a trade.

Why you sometimes get no "recovered" message. A recovery notice goes to a place only if the matching down notice went there. So if a monitor went down and came back before your Alert after N minutes down delay elapsed, you get nothing — no down message, and therefore no recovery message either. That is deliberate, not a missed alert: a "✅ recovered" for an outage you were never told about is confusing rather than useful, and it is the thing that would otherwise wake you at 3am to tell you something you did not know was wrong is now fine.

The same rule applies per destination, which matters if you use escalation policies. If your on-call was paged for an outage, your on-call gets the closing notice — even if you have Alert when recovered switched off, and even if they were reached only through the escalation ladder rather than your own channels. Outside maintenance windows, nobody who was woken up is left wondering whether it is over.

The one exception — a recovery inside a maintenance window. If the monitor comes back while a maintenance window is running over it, that closing notice is not sent, on any monitor type. The outage is still closed on our side — the incident resolves and the escalation ladder stops paging — but nobody who was paged before the window opened is told it ended. So if you open a window over a monitor that is already down and already paging, tell your on-call yourself: the window ends the pages, and it also ends the all-clear.

On "Repeat alerts": measured in checks, not minutes, because a monitor's interval can change. Left off, you get exactly two messages per outage — one when it goes down, one when it recovers.

The rail card summarises the result at a glance: Enabled/Disabled, channel count and first channel name, the P95 threshold, failures-to-alert, and the escalation policy.


Escalation policies

A channel tells everyone at once. An escalation policy tells one person, waits, and tells the next person if nobody answered.

Use it when "the alert went to Slack and nobody was looking at Slack" is a realistic outcome. Skip it for low-stakes monitors — a policy on a staging site just means two people get woken instead of one.

Policies belong to a team, so you need a team (Teams in the sidebar, /dashboard/teams) before you can create one. The team can be just you — you count as one of its recipients — but a policy that pages only you is doing less than a plain alert channel would. Go to Escalation Policies in the sidebar (/dashboard/escalation) → Create Policy.

1. Name — required

Up to 100 characters. "Critical Services Escalation".

2. Description — optional

Up to 500 characters.

3. Team — required

The policy's targets must be members of this team. You can move a policy to another team later from the same form — every level's recipients are re-checked against the new team, and the move is refused if a level names somebody who is not on it.

A team is also what stops you deleting a team out from under a policy: deleting a team that policies use is refused, and the message names them.

4. Escalation Levels — at least one required

Each level has three parts, one of them optional. Add Level appends another; levels are numbered automatically and must run 1, 2, 3… with no gaps.

If not acknowledged within (minutes) — how long to wait before moving to the next level. Defaults to 15; accepts 1 to 1440 (24 hours).

Read that carefully, because it is the one thing people get backwards: this is the wait after the level pages, not a delay before it. Level 1 pages as soon as the ladder starts; its timer is how long level 1 has to be acknowledged before level 2 fires.

So a policy with L1 = 15 and L2 = 30 pages twice — at T+0 and at T+15. Not at T+15 and T+45, and not three times. One pass fires each level exactly once, so two levels are two pages; the minutes only set the gaps between them. Getting a page at T+45 would take a third level.

The last level's timer still does something, though: it is the wait before the ladder either repeats or ends. Above, level 2's 30 minutes run out at T+45 — and if you have set a Repeat Count, the next pass begins one Repeat Delay after that.

Levels do not fire to the second. The waits between levels are checked by a sweep that runs about once a minute, so a level whose wait is up fires at the next sweep rather than the instant its clock runs out. A level set to N minutes pages between N and about N + 75 seconds. We measured two on production: one 44 seconds late, one 14 seconds late.

That is a fixed cost rather than a percentage, so it is invisible at 15 minutes and obvious at 1: a 1-minute level can page anywhere between 1:00 and roughly 2:15. It also carries forward instead of catching up — each level's timer starts when that level actually paged, so level 3 is late by level 2's overshoot plus its own. If you are holding a stopwatch to a 1-minute ladder, that is the mechanism you are watching. It only ever runs long; a level never pages early.

The first page is exempt — it goes out immediately when the ladder starts, not on a sweep.

Notify — one of four:

TargetWho gets pagedNeeds
Specific people (by email)The email addresses you list — all of them, every time.At least one address, each belonging to a member of the selected team.
All team membersEveryone on the team, plus its owner.Nothing. This is the default a new level starts with.
Whoever is on-call (schedule)Exactly one person: whoever the chosen on-call schedule resolves to at the moment the level fires.A schedule that belongs to the same team as the policy.
One person, taking turnsExactly one person per firing, moving to the next each time.At least two different people. Two spellings of the same account (an email and that person's user id) count as one, and are refused.

For the two that take a list of people, you type email addresses — there is no picker, so you need to know them. Everyone you list must already be a member of the team.

The rotation in "One person, taking turns" continues across incidents and survives edits to the policy: it is not reset when you change a level.

Instructions (optional) — what the people this level pages should do first: the runbook link, the one command that usually fixes it, who to call next. Up to 500 characters, and it is per level — level 1 can say "restart the pod" and level 3 "wake the DBA, the pod restart didn't hold".

Whatever you write is added to the end of the alert on every channel that level pages: email, Slack, Discord, Teams, webhook, PagerDuty, Telegram, Google Chat, Mattermost, Pushover, SMS and mobile push. It also rides the last-resort page Enori sends to the monitor's owner when nobody the level named could be reached.

Two things worth knowing before you write a long one:

  • Line breaks are removed when the alert is sent. You can type a list and it will be stored the way you typed it, but the alert itself is one paragraph — the same text has to read correctly in an email body, a Slack message and a 160-character SMS. Short sentences beat a numbered list here.
  • On SMS it costs you. The instructions are part of the message, and an SMS is billed per 160 characters. A 500-character runbook turns one SMS into four. If a level pages an SMS channel, keep it to a link.

Leave it empty and nothing changes — the alert is exactly what it was before.

Notify on — optional, and the part that makes a ladder feel like a ladder.

By default a level reaches every channel the person it pages has set up. That is fine for a one-level policy and wrong for a three-level one: the whole point of escalating is that level 3 should be harder to sleep through than level 1. Tick the channel kinds a level should use — Slack for the first nudge, SMS and PagerDuty for the one at 3am — and that level uses only those.

Some details worth knowing before you rely on it:

  • It picks kinds, not specific channels. You are choosing how to reach whoever the level pages, not which of their channels — which is what lets it work when the level pages a teammate whose channels you cannot see.
  • Leave it untouched and nothing changes. No selection means every channel, exactly as before. Existing policies are unaffected.
  • It can never silence a page. If the person a level pages has none of the kinds you picked — you chose Slack, they never connected Slack — they are paged on everything they do have rather than not at all. A preference about how to reach someone is never allowed to become a reason nobody was reached.
  • The last-resort page ignores it. If nobody a level names can be reached at all, the fallback to the monitor owner uses every channel the owner has. So does the "recovered" notice at the end of a ladder, which goes to everyone who was paged along the way.
  • Push notifications are not affected. Mobile push is not one of these kinds — it goes to your devices independently of what a level selects.

5. Repeat Configuration — optional

  • Repeat Count — how many additional passes through the whole ladder after the first one. Starts at 0, which means one pass. 2 means three passes in total (the original plus two repeats). Maximum 10.
  • Repeat Delay (minutes) — how long to wait before restarting the ladder. Starts at 5. Maximum 1440.

Repeat Count starts at 0, so unless you raise it there is no second pass and the delay never comes into play.

Setting the delay to 0 runs as 5 minutes rather than "restart immediately" — five minutes is the floor between passes, so a repeat cannot become a rapid loop. Any other number is used exactly as entered.

6. If nobody responds — optional

When the last level and every repeat have gone unanswered, the ladder can hand the alert to another policy, which then starts from its own level 1.

  • It runs once. The second policy will not hand off again, however its own fallback is configured — a chain of policies paging at 3am is a failure mode, not a feature.
  • A policy cannot fall back to itself, and two policies cannot point at each other. Both are refused when you save.
  • It needs two policies to be useful, so on Base (2 policies) you can use it exactly once.
  • Leave it on Stop escalating — the default — and the ladder simply ends.

7. Attach it to a monitor

A policy does nothing until a monitor points at it. Open the monitor → Alerts card → Edit › → Escalation Policy.

What starts a ladder is broader than "the monitor went down." Once a policy is attached, two kinds of problem escalate:

  • Downtime and its relatives — the monitor is down, a cron job is overdue or failed, a browser check is failing. These open an incident, and the ladder runs against it. Acknowledging or resolving the incident stops the ladder.
  • Serious problems that are not downtime — a certificate or TLS problem, a domain about to expire or changed at the registrar, a DNS record that no longer matches, a missing security header, slow responses or packet loss, a reputation blocklisting, a content change, an SLO burning through its error budget, a spike of failing traces. None of these open an incident. They open an episode, and the ladder runs against that instead.

Only the critical ones escalate. A problem Enori rates as a warning — a certificate expiring in three weeks, say — reaches your channels but starts no ladder. That is deliberate: a ladder that wakes someone for a work item is a ladder people learn to ignore. If that warning later becomes critical — the certificate actually expires — the ladder starts then, so you are paged when it matters rather than when it was first noticed.

There is one difference in how you stop the two. An incident ladder stops on Acknowledge or Resolve, and a snooze deliberately does not stop it. An episode ladder stops on all three, snooze included — an episode has no other way to honour a snooze, so deferring it also stops the paging.

Deleting a policy tidies up after itself: it's cleared from every monitor that used it, any escalation currently in flight is cancelled, and if another policy fell back to it that hand-off is removed (that policy's ladder will simply stop when it runs out of levels).


When many monitors go down at once

A shared dependency fails — a region, a database, a wildcard certificate expiring across fifty sites — and every monitor that depends on it goes down inside the same minute. Without grouping, that is fifty alerts, fifty pushes, and fifty escalation ladders climbing your phone tree in parallel for one problem.

Enori groups them. Here is exactly what happens, in the order you experience it.

The first two monitors alert normally. Nothing is held back, nothing is delayed, and no alert waits to see whether more will follow. If only two monitors ever fail, you get two alerts and this section never applies to you.

From the third monitor on, you get ONE alert naming them all. That page says how many monitors are down and lists them. The third monitor's own alert is not sent — the group's alert is its alert — and every monitor that joins afterwards is absorbed into the same group silently.

One escalation ladder, not fifty. If the monitors had escalation policies, the ladders that had already started are folded into a single ladder for the group. Your on-call is paged once about an outage, not once per monitor.

One recovery. When the last monitor in the group comes back, you get one "recovered" message naming the group — sent to everyone the grouped alert reached.

What counts as "at once"

Two settings decide it, and both are per-account:

Default
How many monitors before grouping kicks in3
How close together they must failwithin 2 minutes of each other

The window slides. It is measured between consecutive failures, not from the first one — so an outage that takes monitors down one every ninety seconds keeps building one group rather than being cut into several. A gap longer than the window ends the group; the next failure starts a new one.

Where you see it

On the Active tab, a grouped outage gets a card above the list: "5 monitors went down together", when it started, and the monitor names. The monitors keep their own rows below it, each marked grouped — that chip is the answer to "why didn't I get an alert for this one?".

Acknowledge all on that card does what it says: every monitor in the group that is still open is acknowledged in one click, and the group's escalation ladder stops. Monitors you had already snoozed are left alone — you set that deferral on purpose, and both a snooze and an acknowledgement stop the paging anyway.

The same button is on the alert itself, so you can stop the escalation from your email or Slack without opening Enori.

Acknowledging one monitor of a group does not stop the paging, and this is the one thing worth remembering from this page. The ladder that is climbing belongs to the group, so it keeps going until you use Acknowledge all (or every monitor in the group recovers). Acknowledging a single member still does what it always did for that monitor — it just is not what stops the phone tree during a grouped outage.

What grouping does not do

  • It does not suppress anything below the threshold. Two monitors failing together is two

alerts, exactly as before.

  • It does not delay the first alerts. Nothing is buffered waiting to see whether a storm is

forming.

  • It does not close incidents or hide monitors. Every grouped monitor still has its own alert

record, its own timeline, and its own recovery — you just are not paged for each of them separately.

  • It is per account, not per team or per monitor group. The monitors do not have to be related

to each other; failing at the same time is the whole criterion.

Grouping is being rolled out and is off by default while we measure how often real outages cluster. Until it is switched on for your account, every monitor alerts individually exactly as described in the rest of this page.


On-call schedules

An on-call schedule turns "page the on-call engineer" into something you don't have to edit every week. It rotates a list of team members on a fixed cadence, and an escalation level can target it instead of naming people.

Go to On-Call Schedules in the sidebar (/dashboard/on-call).

Creating one

FieldWhat to enter
NameRequired. Up to 100 characters in the form — "Primary on-call"
TeamThe team whose members rotate
Rotation members (in order)Tick at least one member. The tick order is the rotation order, shown as #1, #2, …
Rotation length (days)1–365. How long each person holds the pager.
First shift dateThe date the first shift begins, in the timezone below.
Handoff timeThe local time of day every handoff happens — 09:00 by default. It is read in the timezone below and labelled with it, so it means the same thing whoever is editing, wherever they are.
TimezoneAn IANA zone, e.g. Europe/Sofia. Defaults to UTC. Anything that isn't a real zone is refused.

The timezone decides when handoffs happen. A rotation advances in whole days in this zone, so a Monday 09:00 handoff stays at 09:00 local all year — it does not shift by an hour when the clocks change. Set it to the zone the people holding the pager actually live in.

Changing a schedule never moves the pager mid-shift: whoever holds it keeps it until the next handoff, then the new rotation applies. Two exceptions: removing that person from the rotation hands the pager over at once, and an active override always takes the pager regardless of who the schedule would otherwise say is holding it.

Once saved, reopen the schedule to get two extra sections:

  • Coverage preview — the handoffs in the next 14 days, up to eight of them. On a 7-day rotation that is two; on a daily rotation it is eight.
  • Overrides (cover for me) — pick a person and a start/end, read in the schedule's timezone, and they take the pager for exactly that span regardless of the rotation. The person must be on the team, and end must be after start. Remove one with the ✕. If two overrides overlap, the one that started most recently wins. You can have up to 50 live at a time; windows that closed more than 90 days ago are cleared out automatically.

Each card shows who holds the pager now and the next handoff, in the schedule's timezone.

A schedule referenced by an escalation policy must belong to the same team as the policy.

Changing a schedule's team is refused if a live override still names someone who isn't on the new team — the error names the affected override; remove it, or keep the schedule on its current team, before saving.

Deleting a schedule re-points any escalation level that paged it at the whole team, so those policies keep working and stay editable. If that is not what you want, point those levels somewhere else first.


Acting on an alert without opening Enori

Repeated fires of the same problem on the same monitor are grouped into one episode rather than sent as a fresh alert every time. Each alert message carries buttons that act on that episode directly — so the on-call can respond from their inbox or from Slack. An escalation page about an outage — the message a ladder sends when a monitor is down, a cron job is overdue or a browser check is failing — carries a one-click Acknowledge too, and that one acts on the incident itself: pressing it marks the outage as handled and stops the ladder, from the alert, without opening Enori.

ButtonWhat it does
AcknowledgeMarks the problem as "someone is on it", and stops the escalation ladder. For Down-type problems — a monitor being down, a cron job overdue, a browser check failing — it does that by also acknowledging the underlying incident, which is what the ladder is climbing against.
Snooze 1h / Snooze tomorrowDefers the episode. Deliberately not an acknowledgement — for a Down-type problem it does not stop the escalation ladder, so as of 2026-09-05 this message no longer offers it: it would look like a way to quiet the ladder and isn't. Acknowledge and Resolve are unaffected, and you can still snooze the episode from its page in Enori — that stays available, it's just not a one-click link in the message itself. For the problems that escalate as an episode instead (certificates, domains, DNS, SLO burn and the rest — see Escalation policies) the button still ships in the message, because an episode has no other way to honour a snooze, and there it does stop the ladder.
ResolveCloses the episode. Like Acknowledge, it stops the escalation ladder.
View MonitorOpens the monitor in Enori.

Email links are safe to have in your inbox: clicking one opens a confirmation page and nothing changes until you press the button on it. That's deliberate — corporate link scanners fetch every URL in an inbound message, and without the extra step a scanner would silently resolve your live incident before a human ever saw it.

Slack, Discord and Teams render these as links rather than native buttons, because real interactive buttons need a registered app rather than an incoming webhook. In email, the full URLs are also printed in small text underneath, so you can copy-paste one if your mail client mangles the link.

An outage escalation page offers Acknowledge only — no Snooze, no Resolve. That is deliberate: an incident closes by itself when the monitor recovers, so a manual Resolve would fight the automatic one, and deferring an outage is not a thing a paged person should be offered. The link goes through the same safe confirmation page as every other alert link, and the incident's timeline records the acknowledgement as coming from a one-click link.

Inside the product, episodes live at monitor → Alert episodes (/dashboard/monitors/{id}/episodes), filterable by All / Open / Acked / Snoozed, and the same action buttons appear on episode rows in the bell. The available actions follow the state: an open episode offers Ack, Snooze and Resolve; an acknowledged one offers Snooze and Resolve; a snoozed one offers Resolve only.

Snoozing an episode does not stop messages reaching you. It records that you've deferred it. To actually go quiet, use monitor Snooze (below) or a maintenance window.

Going quiet on purpose

Stops delivery?Scope
Monitor snoozeYesJust you. Teammates still get paged.
Maintenance windowYesThe monitor, for everyone.
Episode snoozeYesThis one alert, for everyone — until it expires.

Snooze a monitor from its row's ⋯ menu → Snooze → Pause alerts for… 1 hour · 2 hours · 4 hours · 8 hours · Until tomorrow · Until I resume (capped at 72 hours). Snooze keeps the in-app bell working — it quiets your channels, not your record.

Snoozing one alert

Snooze on an alert row silences that alert, and nothing else. The monitor keeps being checked, your other alerts keep coming through, and the row stays in Active with the time remaining on it.

Three things worth knowing, because they are the ones people get wrong:

  • It comes back. When the time runs out, if the condition is still failing, Enori tells you

again. A snooze is a "not now", never a dismissal — nothing quietly disappears because you looked away.

  • Getting worse still reaches you. If a snoozed alert escalates from warning to critical, that

gets through. Snooze is a promise about repeats of something you have already judged; a condition that worsened is new information.

  • Snooze is not acknowledge. Acknowledging says I am on it and stops escalation. Snoozing says

not right now and does not — if you have an escalation policy attached, it keeps running.


Active alerts

The Active tab on the Alerts page answers one question: what is wrong right now?

It lists every alert currently firing across all your monitors — newest first — whether it is still open, has been acknowledged, or is snoozed. Every monitoring alert appears here: a site that is down, an API flow that broke, an SSL certificate about to expire, a domain, a security-header grade that slipped, a cron running late. All of them can be acknowledged, snoozed and resolved the same way.

One exception worth knowing: when Enori auto-pauses an API flow after repeated failures on the same step, that notice arrives by email and does not appear here — it is telling you about the monitor's own state, not about something failing right now. Each row shows the monitor, what went wrong, how severe it is, when it started, and when it last fired, with Acknowledge / Snooze / Resolve on the row itself. Before this tab existed, an open alert was only visible on its own monitor's page, so you had to already know which monitor to open — which is exactly the thing you do not know during an incident.

Enori opens this tab for you by default whenever something is firing. If you click History or Channels, the page stays where you put it — it will not jump back under you when the next alert arrives, or when the last one clears.

The list updates live. You do not need to refresh it, and it does not poll.

One thing worth knowing: if the list cannot load, Enori says so plainly rather than showing an empty page. An empty Active tab always means nothing is firing — never that something went wrong fetching it.

If several monitors went down together, a card above the list says so and the rows it covers are marked grouped — see When many monitors go down at once.

Two that behave a little differently

Security header grades. Enori re-grades your security headers every 12 hours. When the grade slips it opens a warning, not a critical — your site is serving traffic; this is a hardening problem, not an outage, and it should not wake anyone. It closes itself when the grade recovers.

Resetting the baseline also closes it, without a "restored" message — because nothing was restored. Your headers are still whatever they were; you have just told Enori to stop comparing them to the old grade and start again from today's. The alert leaves the Active list quietly so it is not left claiming a comparison you have retired.

Cron schedule drift. When a job's p95 start time drifts past the threshold you set, that is now one alert you can acknowledge, not a reminder every hour for as long as the drift lasts. It closes itself when the schedule settles back within the threshold. Turning the drift rule off closes it too, quietly and without a "resolved" message — your job is still running exactly as late as it was, you have just stopped asking to hear about it. Same if the job stops running altogether and there is no timing left to measure.

A late cron and a dead cron are separate alerts, deliberately — you can acknowledge "yes, I know it's running late" without silencing "it stopped running at all".

Delivery rules

Each channel can carry its own rules about when Enori is allowed to use it. They are about the destination, not the alert — the incident still opens, the episode still appears in Active, and your other channels still fire. All that changes is whether this one is told.

Minimum severity. Send only warning and above to a Slack channel, only critical to your phone. An alert below the floor is held back.

Quiet hours. A daily window, in your own time zone, during which this channel stays silent. The window may cross midnight — 22:00 to 07:00 is the usual one.

Critical alerts always come through, quiet hours or not. The point of quiet hours is to sleep through a certificate expiring, not through your site going down.

Cooldown. A minimum gap between two messages to this channel.

Maximum per hour. A ceiling per clock hour. The count resets on the hour rather than sliding, so a burst either side of the boundary can exceed it briefly — it errs toward letting alerts through.

Anything held back appears in History as Suppressed, with the reason — nothing is lost, and you can always see what you did not get and why.

Two things are never held back by a cooldown or an hourly limit: recovery messages, so a channel is never left showing a problem that is already over, and Test, because you asked for that message and are watching for it. Testing a channel also does not start its cooldown.

Signed webhooks

Signing and custom headers are configured through the API today, not the dashboard — the dashboard covers severity, quiet hours, cooldown and the hourly cap. Everything below describes the API surface; the dashboard controls for it are coming.

For a Webhook channel you can turn on signing, and Enori will add a signature header to every request so your receiver can prove the call came from us:

text
X-Enori-Signature: t=1767225600,v1=5f2c...9ab1

t is a Unix timestamp and v1 is the lowercase-hex HMAC-SHA256 of the string "{t}.{raw request body}", keyed by your channel's signing secret. To verify, recompute it over the raw body you received — not a re-serialized version of the parsed JSON, or the bytes will differ and every signature will look wrong. Reject anything where t is older than a few minutes to shut down replays.

python
import hashlib, hmac, time

def verify(raw_body: bytes, header: str, secret: str, tolerance_s: int = 300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    if abs(time.time() - int(parts["t"])) > tolerance_s:
        return False
    expected = hmac.new(
        secret.encode(), f'{parts["t"]}.'.encode() + raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

The secret is shown once, when you enable signing or rotate it. After that Enori only ever displays its last four characters. Rotating issues a new secret immediately — update your receiver at the same time, or it will start rejecting valid calls.

Custom headers

A Webhook channel can also carry extra headers, which is usually how you authenticate to your own receiver. Authorization is allowed and is what most people use.

Header values are hidden once saved: Enori returns the names with the values masked. Sending a masked value back is treated as "leave this one alone", so reading a channel, changing something else and saving it will not damage a header you never touched. To CHANGE a value, send the new one in full.

A few headers cannot be set, because they control how the request itself is assembled rather than what it says: Host, Content-Length, Transfer-Encoding, Connection, and Enori's own signature header.

Alert history

The History tab on the Alerts page is the delivery log: every message Enori tried to send, and whether it landed.

Each row shows the time, the monitor, the alert type, the channel it went to, the status, and a truncated message — click a row to expand the full message, the exact send time, the destination, and the error if it failed. Above the table are counters for today, this week, and failures, plus filters for monitor, alert type, a free-text search, and a date range with Today / 7 Days / 30 Days shortcuts. Rows page 20 at a time.

Status is one of Sent, Failed, Pending, or Suppressed — suppressed meaning a snooze or maintenance window deliberately held it back.

A failed delivery is retried 3 times. If all three fail, Enori writes an "Alert delivery failed" notification to your bell — worth treating as urgent, because it means an alert you were counting on did not reach you.

Webhook payload

A generic webhook receives JSON like this:

json
{
  "event": "monitor.episode.opened",
  "timestamp": "2026-08-03T09:14:22Z",
  "monitor": { "id": "mon_...", "name": "API — production" },
  "alert": { "type": "Down", "title": "Monitor Down: API — production", "message": "..." },
  "episode": {
    "id": "epi_...",
    "cause": "availability",
    "kind": "opened",
    "severity": "critical",
    "openedAt": "2026-08-03T09:14:22Z",
    "actions": { "ack": "https://...", "snooze1h": "https://...", "resolve": "https://..." }
  }
}

event is monitor.episode.opened / .updated / .resolved. The actions map holds the same signed URLs the email buttons use, so a receiving system can build its own UI or act on them programmatically.

Setting up Telegram

  1. Message @BotFather on Telegram, send /newbot, and copy the token it hands back —

it looks like 110201543:AAHdq....

  1. Add your new bot to the group or channel that should receive alerts (or just message it

directly for personal alerts).

  1. Find the chat ID: forward any message from the chat to @userinfobot, or call

getUpdates on your bot. Group and channel IDs are negative — keep the minus sign. A public channel's @name works as-is.

  1. Create the channel in Enori with both values, then press Test.

The token is stored encrypted and shown only as its last four characters afterwards. When editing the channel, leave the token field untouched to keep the current one.

Setting up Google Chat

In the target space: space name → Apps & integrations → Webhooks → Add webhook. Paste the URL into Enori. Alerts arrive as formatted text with clickable action links.

Setting up Mattermost

Integrations → Incoming Webhooks → Add. Paste the URL into Enori. Alerts arrive with the same colour-coded attachment Slack gets; the Acknowledge / Snooze / Resolve links sit in the message text.

Opsgenie, Splunk On-Call, and anything else with an inbound API

Enori doesn't ship dedicated tiles for these, deliberately — Atlassian is sunsetting Opsgenie (sales already ended; support runs to 2027), and both tools' inbound APIs accept exactly what the generic Webhook channel sends. The recipe:

  1. In the tool, create an inbound integration and copy its endpoint URL

(Opsgenie: an API integration → https://api.opsgenie.com/v2/alerts with a GenieKey header; Splunk On-Call: the REST endpoint URL with your routing key in the path).

  1. In Enori, create a Webhook channel with that URL.
  2. Where the tool authenticates by header (Opsgenie's Authorization: GenieKey ...), add it

under Delivery rules → Custom headers — header values are stored encrypted and masked on read.

  1. Map fields on the receiving side from the webhook payload: alert.title

for the summary, episode.severity for priority, and event (.opened / .resolved) to open and close the incident.

  1. Optionally turn on signed webhooks and verify X-Enori-Signature on the receiving end.

Reference: limits and bounds

SettingAllowed values
Channel nameRequired
Webhook URLHTTPS only; internal/private addresses rejected
PagerDuty integration key20–64 characters, no spaces
Telegram bot token: exactly as @BotFather issued it
Telegram chat IDA number (negative for groups) or @channelusername
Pushover user keyExactly 30 letters and digits (group keys work too)
Phone number (SMS)E.164 — + then 7–15 digits
SMS verification code6 digits, valid 10 minutes, 5 attempts, 3 codes per channel per day
Alert channels per accountBase 5 · Pro 15 · Business unlimited
Escalation policies per accountBase 2 · Pro 10 · Business 20
On-call schedules per accountBase 1 · Pro 5 · Business 20
Policy name / description100 / 500 characters
Escalation levelsAt least 1; numbered contiguously from 1
Escalate-after (per level)1–1440 minutes in the form (the API accepts up to 10080 = 7 days)
Instructions (per level)Up to 500 characters, optional. Added to the alert on every channel; line breaks become spaces when sent
Repeat Count0–10 additional ladder passes (total passes = count + 1)
Repeat Delay0–1440 minutes, seeded at 5. 0 runs as 5 — five minutes is the floor between passes
Escalation level timingLevel 1 pages immediately; each later level pages between its configured minutes and about 75 seconds after
People in a rotation ("taking turns")At least 2, and they must be different people
Fallback policyOne hop only — the policy you hand off to will not hand off again
Rotation length1–365 days
Live on-call overrides50 per schedule; closed windows are cleared after 90 days
Failures before alertImmediate, 1, 2, 3, or 5
Repeat alertsOff, or every 1, 2, 3, 5, or 10 checks
Monitor snooze1h, 2h, 4h, 8h, until tomorrow, or until resumed (max 72h)
Test sends5 per minute
Channel / policy changes20 per hour
Delivery attempts3, then an "Alert delivery failed" notification

FAQ

Do I need a separate channel per monitor?

No — the opposite. Create a few channels that match how your team actually works (one Slack for ops, one email for the on-call, maybe PagerDuty for production), then assign each to as many monitors as you like. Channel count is capped per plan; monitor assignments are not.

Can several channels get the same alert?

Yes. Assign as many channels as you want to one monitor and every one of them is notified.

Why didn't I get an alert when my site went down?

Work through Troubleshooting below — but the two overwhelmingly common causes are no channel assigned to that monitor and failure threshold not reached.

What's the difference between an escalation policy and just adding more channels?

Channels are parallel — everyone is told at the same moment. A policy is sequential — the next person is only told if the previous one didn't acknowledge in time. Use channels for visibility, policies for accountability.

A policy also lets urgency climb: each level can pick which channel kinds it uses (see Notify on above), so the first level can be a Slack message and the third an SMS. Adding more channels to a monitor cannot express that — they all fire at once, at the same urgency.

If Repeat Count is 2, how many times am I paged?

Three full passes through the ladder: the original plus two repeats, each separated by the Repeat Delay.

Can I set quiet hours so alerts don't fire at night?

Not today. The closest equivalents are a recurring maintenance window over a period you genuinely expect to be noisy, or per-user monitor snooze when you personally need a break. Neither is a real do-not-disturb schedule, and neither is a good fit for a production monitor you actually want paged on.

Does deleting a channel break my monitors?

No. The channel is removed from every monitor that referenced it, cleanly. Those monitors keep checking — they just have one fewer place to send to, and if it was the only one, they'll show "No alert channel".

Why is my SMS channel showing "Unverified"?

Either it's new, or the phone number was changed after it was verified — changing the number always resets it. Click Unverified · Verify on the card and enter the code. It won't send alerts until you do.

Are alerts affected by maintenance windows?

Yes — that's what maintenance windows are for. Every channel on a monitor in an active window goes quiet, and nothing escalates. One deliberate exception: an incident that was already open before the window started keeps paging. Note the asymmetry: that incident keeps paging, but if it recovers inside the window, no closing notice goes out for it — see Choosing what each monitor alerts on above. See Maintenance windows.

Can I manage all this through the API?

Yes. Channels live at /api/alert-channels, escalation policies at /api/escalation-policies, on-call schedules at /api/on-call-schedules, and the delivery log at /api/alerts. API keys need the alerts:read / alerts:write scopes, and escalation:read / escalation:write for policies. See the API reference.


Troubleshooting

I never got the alert

In this order:

  1. Is a channel assigned to that monitor? Open the monitor → Alerts card. If it reads "No alert channel — failures won't notify", that's your answer. This is by far the most common cause.
  2. Is "Alert when down" on? Same card.
  3. Did it hit the failure threshold? At 3, two consecutive failures produce nothing at all.
  4. Was the monitor snoozed, or in a maintenance window? Both suppress delivery on purpose. Check the History tab — a held-back message is logged as Suppressed.
  5. Check the History tab for a Failed row. Expand it; the error message tells you what the channel returned.
  6. For SMS: confirm the channel shows Verified.

The test worked but real alerts don't arrive

The test proves the channel is reachable, not that it's wired to anything. Test only exercises the channel — it doesn't check monitor assignment, the alert toggles, or the failure threshold. Re-check steps 1–3 above.

I got "Alert delivery failed" in the bell

Enori tried three times and gave up. Open Alerts → Channels, hit Test on the suspect channel, and read the error. Usual causes: a revoked Slack or Teams webhook, a webhook endpoint returning errors, a PagerDuty key that was rotated, or a bouncing email address. Until you fix it, alerts through that channel are not reaching you.

My webhook URL is rejected

Two rules: it must be HTTPS (plain http:// is refused), and it can't resolve to an internal or private address. A localhost or 10.x endpoint won't be accepted — Enori has to be able to reach it from the public internet.

"That doesn't look like a PagerDuty Events API v2 integration key"

The key must be 20–64 characters with no spaces. A common mistake is pasting the service's API key or a URL instead of the integration key from an Events API v2 integration on the service.

I can't save my escalation policy

Check three things: the If not acknowledged within field on every level is at least 1; every level with Specific people has at least one email; and every email belongs to a member of the selected team — outside targets are refused.

"Escalation targets must be members of the selected team"

The email you entered doesn't resolve to a member of the policy's team. Invite them to the team first, or switch the level to All team members.

I'm getting too many alerts

Raise Failures before alert to 2 or 3, turn Repeat alerts off, and check you haven't attached three overlapping channels to the same monitor. For planned noise, declare a maintenance window rather than turning alerts off and forgetting to turn them back on.

I acknowledged the episode but it's still escalating

Snooze isn't an acknowledgement — it's a deferral, and for a Down-type problem it deliberately doesn't stop the ladder. Use Acknowledge or Resolve to stop escalation. (For the problems that escalate as an episode rather than an incident, snooze stops the ladder too — see Escalation policies.)


  • Notifications — the in-app bell, what lands there, and how long it's kept
  • Maintenance windows — planned downtime that suppresses alerts for everyone
  • Service Level Objectives — burn-rate alerts, which route through these same channels
  • Settings — plan limits, teams, and API key scopes
  • Audit log — who created, changed, or deleted a channel or policy
  • API reference — managing channels, policies and schedules programmatically