Subscribers
Enable public subscriptions over email, feeds and webhooks, safely.
Public subscriptions let visitors receive incident and maintenance updates. They are disabled by default, because enabling them turns a read-only page into something that stores visitor-supplied destinations and sends outbound requests on their behalf.
Defaults to false. While false, every /subscribers* route answers
404 and the page shows no subscribe control.
Defaults to ["email", "rss"]. Duplicates are rejected.
Defaults to true. Email subscriptions use double opt-in.
The three methods
| Method | Storage | Notes |
|---|---|---|
email | a subscribers row | Needs a configured email notification channel. Double opt-in by default. |
rss | nothing | A link to /rss.xml and /atom.xml in the subscribe dialog. |
webhook | a subscribers row | Visitor-supplied HTTP(S) URL. Opt-in only; see the warning below. |
RSS is not a stored subscription — it is a URL — so it adds nothing to the database and nothing to send.
Enabling "webhook" lets anonymous visitors make your deployment
issue HTTP requests to a host they choose. Heyo Status rejects loopback,
private, link-local, carrier-grade NAT and multicast literals, credentials
in the URL, and reserved suffixes such as .local and
.internal — but URL validation cannot see through DNS. Pair it
with an egress policy if you enable it.
Email requires an email channel
Confirmation and incident mail are sent through the first configured email
notification channel, reusing its transport and from address. Without one,
POST /subscribers with type: "email" answers 503 and explains why.
The channel's own to list keeps receiving operational alerts; subscriber
mail is addressed only to the subscription.
What subscribers receive
Only public, already-published lifecycle events:
incident.created,incident.updated,incident.resolvedmaintenance.scheduled,maintenance.starting,maintenance.completed
Monitor-level events (monitor.down, monitor.recovered, ssl.expiring) are
never sent to public subscribers — those are operational signals for your
own channels.
A subscription may optionally name monitors through the API. A subscription
with monitors: null (the default) receives everything; one with a list only
receives events affecting those monitors, and global events — an incident with
an empty affectedMonitors — always go to everyone.
The subscribe dialog
When subscribers.enabled is true and no subscribeHref or onSubscribe
override is passed, <StatusPage /> renders a Subscribe button that opens
the bundled dialog lazily on first use:
The dialog shows one tab per configured method and posts to
${basePath}/subscribers. To send visitors to your own page instead:
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /subscribers | Create a subscription. 202 pending or 201 subscribed. |
GET | /subscribers/confirm?token= | Consume a single-use confirmation token. |
GET | /subscribers/:id/unsubscribe | A self-contained HTML confirm page. |
POST | /subscribers/:id/unsubscribe | Performs the removal from that page. |
DELETE | /subscribers/:id | Programmatic removal. |
Full request and response details are in the subscriber API reference, and the privacy reasoning behind the responses is in How public subscriptions work.
Operational notes
- Subscriptions are identified by destination, so repeating a request is idempotent and cannot mail an address twice.
- A pending confirmation is reused for 15 minutes before a new token is issued.
- Deliveries are isolated per destination and written to the notification log.
- A failure to list subscribers never fails an incident update.