Uptimeify Docs
Status pages

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

FieldTypeRequiredDescription
channelstringnoemail (default), webhook, slack or teams
emailstringfor emailRecipient address
targetUrlstringfor URL channelshttps URL without credentials, publicly reachable. Slack: an incoming webhook URL. Teams: an incoming webhook or Workflows URL that accepts Adaptive Cards
componentIdsarraynoComponents of this page (numeric ID or publicId), at most 100. Omitted or empty: the whole page
localestringnode... 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) when email or targetUrl is missing for the chosen channel
  • 400 Bad Request (subscriptionTargetUrlInvalid) when targetUrl is not an https URL or carries credentials
  • 400 Bad Request (subscriptionTargetUrlRejected) when targetUrl resolves to a loopback, private, link-local or otherwise non-public address
  • 404 Not Found (statusPageComponentNotFound) when a componentIds entry is not a component of this page
  • 409 Conflict (statusPageLimitReached) when the page already has 50 webhook, Slack and Teams subscriptions
  • 429 Too Many Requests for too many signups from one IP, or for URL channels too many on one page

On this page