---
title: "Subscribe to a Status Page"
description: "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)

```bash
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`

```json
{ "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:

```json
{
  "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
