Subscribe to a Status Page
Public endpoint behind the subscribe form: email, webhook, Slack or Microsoft Teams, for the whole page or selected components. Double opt-in for every channel.
POST /api/status-pages/public/:slug/subscribe
No authentication. This is the endpoint the subscribe form on a public status page posts to. Every subscription starts as pending and becomes active only after the confirmation link was opened and confirmed: by mail for email, as a first message posted to the target for webhook, slack and teams. Every message carries an unsubscribe link.
The page must be published, public, have subscriptions switched on, and its organization must have the status page module enabled and not be suspended. Otherwise the endpoint answers the same { "ok": true } and stores nothing.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
channel | string | no | email (default), webhook, slack or teams |
email | string | for email | Recipient address |
targetUrl | string | for URL channels | https URL without credentials, publicly reachable. Slack: an incoming webhook URL. Teams: an incoming webhook or Workflows URL that accepts Adaptive Cards |
componentIds | array | no | Components of this page (numeric ID or publicId), at most 100. Omitted or empty: the whole page |
locale | string | no | de... for German, da... for Danish messages, anything else English |
A URL subscription is stored encrypted. Its target is never returned in full, the subscriber list shows its origin only.
Example (cURL)
curl -X POST "https://uptimeify.io/api/status-pages/public/acme/subscribe" \
-H "Content-Type: application/json" \
-d '{"channel":"webhook","targetUrl":"https://example.com/hooks/status","componentIds":[12]}'Response
200 OK
{ "ok": true }For email the answer is always this, also for an unknown page, an address that is already confirmed, or a rate-limited address, so the endpoint does not reveal whether an address or page exists.
Webhook payload
Every message to a webhook target is a POST with Content-Type: application/json and this fixed shape:
{
"event": "incident_open",
"page": { "slug": "acme", "name": "Acme Status", "url": "https://uptimeify.io/status/acme" },
"incident": {
"title": "Payments degraded",
"body": "We are investigating.",
"severity": "major",
"monitorName": null,
"occurredAt": "2026-10-27T10:00:00.000Z"
},
"components": [{ "id": 12, "name": "Payments" }],
"url": "https://uptimeify.io/status/acme",
"unsubscribeUrl": "https://uptimeify.io/status/<page>/unsubscribe?token=<token>"
}event is one of subscription_confirmation, incident_open, incident_update, incident_resolved, maintenance_scheduled, maintenance_completed, im_override_set, im_override_cleared. For maintenance and status notices incident carries the notice. components lists the affected components of the page; an empty list means the whole page. The confirmation message has incident: null and an additional confirmUrl. Slack receives the same content as Block Kit, Teams as an Adaptive Card.
Delivery: one attempt per event, 10 second timeout, redirects are followed only to public addresses, the response body is ignored. After 5 failed deliveries in a row the subscription is switched off (status: disabled in the subscriber list); the subscriber can sign up again.
Common errors
400 Bad Request(invalidRequestBody) whenemailortargetUrlis missing for the chosen channel400 Bad Request(subscriptionTargetUrlInvalid) whentargetUrlis not anhttpsURL or carries credentials400 Bad Request(subscriptionTargetUrlRejected) whentargetUrlresolves to a loopback, private, link-local or otherwise non-public address404 Not Found(statusPageComponentNotFound) when acomponentIdsentry is not a component of this page409 Conflict(statusPageLimitReached) when the page already has 50 webhook, Slack and Teams subscriptions429 Too Many Requestsfor too many signups from one IP, or for URL channels too many on one page