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:
- A channel — where messages go. An email address, a Slack or Discord or Microsoft Teams webhook, your own HTTPS endpoint, or a PagerDuty service.
- 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
| Channel | What you supply | What arrives |
|---|---|---|
| An email address | A branded HTML email — status pill, headline, message, detected time, a View Monitor button, and action buttons | |
| Slack | An incoming-webhook URL | A coloured attachment with Monitor / Status / Message fields and link buttons |
| Discord | A webhook URL | A coloured embed with Status / Time fields and an Actions row of links |
| Microsoft Teams | An incoming-webhook URL | A MessageCard with a branded header, a fact list, and action buttons |
| Webhook | Your own HTTPS endpoint | A JSON POST you parse yourself — see Webhook payload |
| PagerDuty | An Events API v2 integration key | A PagerDuty event that opens an incident and closes it on recovery |
Colour follows severity in every rich channel: red for a failure, amber for a warning, green for a recovery, cyan for informational.
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 picked | Fill in |
|---|---|
Email Address — e.g. alerts@company.com | |
| Slack / Discord / Teams / Webhook | Webhook URL — must be HTTPS. URLs pointing at internal or private addresses are rejected. |
| PagerDuty | Integration Key — 20–64 characters, no spaces |
| SMS | Phone 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 ›.
| Setting | What it does |
|---|---|
| Alert when down | Notify on failures. On by default. |
| Alert when recovered | Notify when it comes back. On by default. |
| Alert when overdue | Cron/heartbeat jobs only — notify when a run is late. On by default. |
| Channels | Which of your channels this monitor uses. Pick as many as you like. |
| Escalation Policy | Optional. None (Simple alerts only) by default — see Escalation policies. |
| Failures before alert | Immediate · 1 · 2 · 3 · 5 consecutive failures. |
| Repeat alerts | Don'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.
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 with members before you can create one. 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.
4. Escalation Levels — at least one required
Each level has two parts. 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).
Notify — one of three:
| Target | Who gets paged |
|---|---|
| Specific people (by email) | The email addresses you list. Each must belong to a member of the selected team. |
| All team members | Everyone on the team. |
| Whoever is on-call (schedule) | The person the chosen on-call schedule resolves to right now. |
Level 1 is notified immediately when the monitor goes down. Every later level fires only if the previous one wasn't acknowledged in time.
5. Repeat Configuration — optional
Both fields start at 0.
- Repeat Count — how many additional passes through the whole ladder after the first one.
0means one pass.2means three passes in total (the original plus two repeats). Maximum 10. - Repeat Delay (minutes) — how long to wait before restarting the ladder. Maximum 1440.
6. Attach it to a monitor
A policy does nothing until a monitor points at it. Open the monitor → Alerts card → Edit › → Escalation Policy. Once set, a monitor going down opens an incident and the ladder runs against it.
Deleting a policy is safe: it's cleared from every monitor that used it, and any escalation currently in flight is cancelled.
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
| Field | What to enter |
|---|---|
| Name | Up to 100 characters — "Primary on-call" |
| Team | The 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. |
| Handoff start | The date and time the first rotation begins |
| Timezone (for display) | An IANA zone, e.g. Europe/Sofia. Defaults to UTC. |
Once saved, reopen the schedule to get two extra sections:
- Coverage preview — the next eight handoffs, so you can sanity-check the rotation before it matters.
- Overrides (cover for me) — pick a person and a start/end, and they take the pager for exactly that span regardless of the rotation. End must be after start. Remove one with the ✕.
A schedule referenced by an escalation policy must belong to the same team as the policy.
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.
| Button | What it does |
|---|---|
| Acknowledge | Marks the problem as "someone is on it". For Down-type problems — a monitor being down, a cron job overdue, a browser check failing — this also acknowledges the underlying incident, which stops the escalation ladder. |
| Snooze 1h / Snooze tomorrow | Defers the episode. Deliberately not an acknowledgement: it does not stop escalation. |
| Resolve | Closes the episode. Like Acknowledge, it stops escalation on Down-type problems. |
| View Monitor | Opens 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.
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 snooze | Yes | Just you. Teammates still get paged. |
| Maintenance window | Yes | The monitor, for everyone. |
| Episode snooze | No | A status marker on the episode. |
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.
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:
{
"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.
Reference: limits and bounds
| Setting | Allowed values |
|---|---|
| Channel name | Required |
| Webhook URL | HTTPS only; internal/private addresses rejected |
| PagerDuty integration key | 20–64 characters, no spaces |
| Phone number (SMS) | E.164 — + then 7–15 digits |
| SMS verification code | 6 digits, valid 10 minutes, 5 attempts, 3 codes per channel per day |
| Alert channels per account | Base 5 · Pro 15 · Business unlimited |
| Escalation policies per account | Base 2 · Pro 10 · Business 20 |
| On-call schedules per account | Base 1 · Pro 5 · Business 20 |
| Policy name / description | 100 / 500 characters |
| Escalation levels | At least 1; numbered contiguously from 1 |
| Escalate-after (per level) | 1–1440 minutes in the form (the API accepts up to 10080 = 7 days) |
| Repeat Count | 0–10 additional ladder passes (total passes = count + 1) |
| Repeat Delay | 0–1440 minutes |
| Rotation length | 1–365 days |
| Failures before alert | Immediate, 1, 2, 3, or 5 |
| Repeat alerts | Off, or every 1, 2, 3, 5, or 10 checks |
| Monitor snooze | 1h, 2h, 4h, 8h, until tomorrow, or until resumed (max 72h) |
| Test sends | 5 per minute |
| Channel / policy changes | 20 per hour |
| Delivery attempts | 3, 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.
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. 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:
- 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.
- Is "Alert when down" on? Same card.
- Did it hit the failure threshold? At
3, two consecutive failures produce nothing at all. - 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.
- Check the History tab for a Failed row. Expand it; the error message tells you what the channel returned.
- 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 it deliberately doesn't stop the ladder. Use Acknowledge or Resolve to stop escalation.
Related documentation
- 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