Status Pages
Publish the live status of your services at a public URL — on your own domain, in your own branding — so customers check the page instead of emailing you during an incident.
What is a status page?
A status page is a public web page that shows whether your services are up, degraded or down, updated automatically from the monitors you already run in Enori. Your customers get one link to bookmark; you get fewer "is it just me?" tickets when something breaks.
Example: you run a SaaS product. You create a status page at status.acme.com with three components — "Website", "API" and "Background Jobs" — each backed by the relevant monitors. When your API goes down, the page flips that component to a major outage within a check cycle, and everyone who subscribed gets an email. Nothing to update by hand.
A status page does three things for you:
- Reflects reality automatically — each component's status is derived from your live monitors, so
the page cannot drift out of date or accidentally say "operational" during an outage.
- Communicates proactively — visitors subscribe by email, and you can add webhooks, so status
changes, incidents and planned maintenance reach people without you sending anything.
- Builds trust — a clean, branded page on your own domain reads as your product, not a
third-party tool.
When to use it
- Public-facing services — a SaaS app, an API, a marketplace, a game backend. Anywhere customers
notice when you're down.
- During incidents — a status page is the single place to point people so support and social
channels don't melt.
- Planned maintenance — declare a maintenance window and it appears on the page
as upcoming, then as in-progress, then in Past Maintenance, so nobody reports the downtime you already announced.
- Contractual transparency — pair a page with an SLO and publish target vs achieved.
When you probably don't need one
- Purely internal monitoring — if only you and your team watch the service, the Enori dashboard
already does this. A status page is for external audiences.
- A single service you check yourself — one monitor you glance at daily doesn't need a public page.
- One number in a README — that's a status badge, not a page.
How it works
Components: the core idea
A component is a named group of one or more monitors shown as a single section on your page — for example a "Payments API" component backed by three monitors. Group your monitors into components that make sense to your customers, not into raw monitor names.
You never set a component's status by hand. Enori derives it from the monitors inside it, which is what stops the page from ever saying something untrue:
| The monitors in a component | The component reads |
|---|---|
| any one of them is down | Major Outage |
| any one of them is degraded (and none down) | Degraded Performance |
| all of them are up | Operational |
| all of them are in a maintenance window | Scheduled Maintenance |
| a mix of up and in-maintenance | Operational |
| anything else — a paused monitor, or one that has never been checked | Unknown |
That last row is worth knowing: a paused monitor does not quietly drop out of the component, it makes the component read Unknown. Remove a monitor from the page if you don't want it to count.
The overall page banner is computed the same way across all components, and reads:
| Overall | Banner text |
|---|---|
| Up | All Systems Operational |
| Degraded | Some Systems Experiencing Issues |
| Down | Major System Outage |
| Maintenance | Scheduled Maintenance In Progress |
| Unknown | Status Unknown |
The banner rolls your components up exactly the way each component rolls up its monitors — the same rule, one level higher. It is a precedence order, and the order is what decides:
- Anything down wins. One component in a major outage and the banner reads Major System Outage,
whatever the other components say.
- Then anything degraded — Some Systems Experiencing Issues.
- Otherwise, if every component is operational, All Systems Operational; if every one of them is in
maintenance, Scheduled Maintenance In Progress; and a mix of operational and in-maintenance still reads All Systems Operational.
- Anything else falls through to Status Unknown.
That last line is the one worth knowing, because "anything else" is more reachable than it sounds: a single paused or never-checked monitor makes its component Unknown, and — if nothing on the page is down or degraded — that is enough to put the whole banner there. A page with no components yet reads Unknown too.
Unknown is a fallback, not an override. It never hides a real problem: if something is genuinely down while something else is merely paused, your visitors see the outage. The banner says "we don't know" only when there is nothing more specific to say — which is the point, since it is the largest text on the page and should not announce a state nobody verified.
If you don't feel like grouping, just tick the monitors you want and Enori puts them all in one default component called "Services". You can switch to named components at any time.
What visitors see
The public page (at /status/{your-slug}, or on your custom domain) shows, top to bottom:
- The overall status banner, tinted with your primary colour when everything is operational.
- An uptime chart for the last 90 days, with an overall uptime percentage — if Show Uptime % is
on and there is at least one day of history.
- Each component, with its monitors and their live status. Per monitor you can publish the last
response time, an uptime percentage, a 90-day bar strip, and SLO target vs achieved — each behind its own toggle.
- Scheduled maintenance that is upcoming or in progress.
- Past maintenance — the most recent 20 completed windows inside your history window.
- Recent incidents — the most recent 20 inside your history window, newest first. When there are
none, the page says so explicitly.
- A subscribe box, if Allow Subscriptions is on.
- A "Powered by Enori" footer, unless you are on Business and have hidden it.
A monitor inside an active maintenance window is shown as Scheduled Maintenance with the window's name, and its response time and uptime figures are hidden for the duration — the page announces the work rather than reporting an outage.
Maintenance downtime is excluded from the numbers. An announced window is removed from both sides of the uptime ratio, so a planned two-hour migration does not dent the percentage you publish. See maintenance windows.
The RSS feed and the status badge
Every public page also serves two embeddable extras, both cached for 60 seconds:
| Extra | URL | Use |
|---|---|---|
| RSS feed | https://api.enori.io/api/status-pages/public/{slug}/feed.rss | Incident history for readers and automation |
| Status badge | https://api.enori.io/api/status-pages/public/{slug}/badge.svg | A shields-style SVG for a README or site footer |
The badge has five states — operational, degraded, major outage, maintenance, unknown — in the flat style. Neither the feed nor the badge carries SLO data.
Access follows the page:
- A page with Public switched off returns 404 on both, for everyone. There is no token that
opens it.
- A password-protected page returns 401 until an unlock token is supplied — append
?t=
to the URL for an embed.
For one monitor rather than a whole page, use a status badge instead — it also documents a third embed built on the page's public uptime-history endpoint.
Setting one up
Go to Status Pages in the dashboard and click Create Status Page. The editor has up to four tabs. General and Branding are available while creating; Domain & Access and Notifications appear once the page exists (open the page and click Edit) because they manage things that need a page to exist first — a domain to verify, subscribers to manage.
1. General tab
| Field | What to enter | Notes |
|---|---|---|
| Name | Your page title, e.g. "Acme Status" | Required, up to 100 characters |
| Slug | The URL segment, e.g. acme → /status/acme | Auto-filled from the name; 3–100 characters, lowercase letters and numbers with single hyphens between them |
| Description | One line under the title (optional) | Up to 500 characters |
Then eight toggles:
| Toggle | Default | What it does |
|---|---|---|
| Public | On | Off = the page is not reachable at all, and its feed and badge return 404 |
| Show Uptime % | On | Publishes the uptime chart and the per-monitor percentage |
| Show Response Time | On | Publishes each monitor's last response time |
| Show SLO Compliance | Off | Publishes each monitor's SLO target and what it has actually achieved |
| Show Incidents | On | Publishes the recent-incidents and past-maintenance sections |
| Allow Subscriptions | On | See the warning below — this is a mute switch, not just a form toggle |
| Allow Search Indexing | On | Off asks search engines not to index the page (noindex) |
| Hide Enori Branding | Off | Removes the "Powered by Enori" footer — Business plan only |
Allow Subscriptions is not just the subscribe box. Switching it off hides the form and stops every email to the subscribers you already have — silently, with no notice to them. Turn it off when you want the page to go quiet, not when you merely want to stop taking new sign-ups. Webhooks are unaffected and keep delivering.
Show SLO Compliance is the one toggle that starts off. On, each monitor row publishes a line like Checkout latency 99.960% vs 99.900% target, green when the target is met (met at exactly the target), or "not enough data yet" when the SLO cannot be scored yet. Disabled SLOs publish nothing. See SLOs.
Then pick your monitors:
- Select Monitors (default) — tick the monitors to include. They land in one "Services" component.
- + Use Components — switch to grouped mode. Add a component by name (e.g. "API"), tick its
monitors, then add more components. Repeat for each group your customers care about.
Click Create Status Page. The page is live immediately at /status/{slug}.
You can also add monitors to an existing page straight from the Monitors list — they append to a component you pick, or create a new one.
2. Branding tab
| Field | What to enter | Availability |
|---|---|---|
| Logo URL | A public image URL shown in the page header | All plans, up to 500 characters |
| Favicon URL | A public icon URL for the browser tab | All plans, up to 500 characters |
| Primary Color | A hex colour for the banner — pick one of 8 presets or enter your own | All plans; the mini-preview updates as you type |
| Theme | Light or Dark for the public page | All plans; Light unless you change it — the mini-preview follows your choice |
| Custom CSS | Extra styling injected as a tag | Pro / Business, up to 10,000 characters |
| Custom Header HTML | Markup shown above the page | Pro / Business, up to 50,000 characters |
| Custom Footer HTML | Markup shown below the page | Pro / Business, up to 50,000 characters |
The theme is your choice, not your visitor's. Whichever you pick is what every visitor sees — the same page, the same way — whether or not they use Enori themselves, and regardless of the light/dark theme they have set in their own dashboard under Settings → Profile → Appearance. It covers the whole public page, the passcode card on a password-protected page included. Every existing page is Light, which is what it already rendered, so nothing changes appearance until you change it.
Custom CSS is not re-coloured for you. Your stylesheet is injected exactly as written, so if it hardcodes colours, write it for the theme you publish — switching the page from Light to Dark does not adjust it.
Below Pro, the three advanced-branding fields are replaced by an upgrade notice in the editor — and the API refuses them too. A Base-plan request that sends custom CSS or header/footer HTML through the REST API gets a 403: "Custom CSS and HTML on a status page require the Pro or Business plan." The plan is checked before the content is, so the answer never depends on what your stylesheet contains.
The gate applies only to adding branding. If you downgrade, you can still clear custom CSS or HTML you already have, and an unrelated edit that echoes the existing values back is not refused.
Custom CSS is checked all-or-nothing. If your stylesheet contains any of url(, image-set(, @import, expression(, javascript:, behavior:, -moz-binding,