Skip to main content

Notification channels

A channel is a delivery target owned by a project. Every alert rule in the project (uptime rules, error alert rules) points at one channel, so you set up Slack or PagerDuty once and reuse it.

Creating a channel​

Dashboard: Monitor → project → Channels. Pick a type, give it a name and fill in the fields. The list has Test, Rename, enable/disable and delete.

API: through the kamuhub front door with an access key that has the status.manage capability.

curl -X POST https://app.kamuhub.com/api/status/projects/<project-id>/channels \
-H "Authorization: Bearer $KAMU_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Ops Slack", "type": "slack",
"config": {"webhookUrl": "https://hooks.slack.com/services/..."}}'

PATCH /api/status/channels/<id> changes name, config (replaced whole) or enabled; DELETE removes it. There are no kamu CLI commands for channels.

The API checks the type, not the config. A missing field only shows up when the first alert fails to send, so press Test after creating a channel. Test sends a real message for Slack, Discord, Google Chat, ntfy, Telegram and webhook channels. For the other types it only answers "configured correctly" without contacting the service.

Channel types​

Fourteen types. The dashboard form covers eleven; matrix, twilio_sms and twilio_call are API-only. Optional fields in the table are API-only as well; the dashboard sends only the required ones.

typeRequired configOptional configSends
emailaddresses (array of strings)One mail per address, subject [kamustatus] <name> - DOWN or - UP
slackwebhookUrl (incoming webhook){"text": message}
discordwebhookUrl{"content": message}
telegrambotToken, chatIdBot API sendMessage, parse_mode: HTML
teamswebhookUrlAdaptive Card with the message as one text block
google_chatwebhookUrl{"text": message}
pagerdutyroutingKey (Events API v2)severity (default critical)trigger on down, resolve on up
opsgenieapiKeypriority (default P1)Creates an alert on down, closes it on up
pushoveruserKey, appTokenpriority (default 1)Message with sound siren
ntfytopicserverUrl (default https://ntfy.sh), priority (default 4)POST to <serverUrl>/<topic>, title = monitor name
matrixhomeserver, roomId, accessTokenm.text message to the room
twilio_smsaccountSid, authToken, from, toSMS with the message
twilio_callaccountSid, authToken, from, toVoice call reading out <name> is down. or is up.
webhookurlmethod (default POST), headers (object)JSON payload below

PagerDuty and OpsGenie dedupe on kamustatus-<monitorId>, so a recovery resolves the incident the outage opened. For error alerts the id is error:<ruleId>, one incident per rule.

Telegram parses the text as HTML, so a monitor name containing < or & can make Telegram reject the message.

Message text​

All chat, SMS and push types send one line of text:

EventText
Monitor down[DOWN] <monitor>: <error> (<region>)
Monitor recovered[UP] <monitor> is back online (<region>)
Certificate expiring[SSL] <monitor>: certificate expires in N day(s)
Domain expiring[DOMAIN] <monitor>: registration expires in N day(s)
Error alertText built by the rule, see error alert rules

Webhook payload​

A webhook channel receives Content-Type: application/json plus any configured headers:

{
"monitor": "API",
"monitorId": "V1StGXR8_Z5jdHi6B-myT",
"status": "down",
"error": "Timeout",
"region": "arn",
"timestamp": "2026-10-27T08:30:00.000Z"
}
  • status is down or up.

  • error and region are left out when unknown. A recovery has no error, and a heartbeat alert has no region.

  • Certificate and domain expiry warnings also arrive as status: "down" with no error. The webhook body does not carry the warning text. Use another channel type if you need to tell them apart.

  • Error alerts add three fields. monitor is the property name and monitorId is error:<ruleId>:

    {
    "monitor": "myapp",
    "monitorId": "error:abc123",
    "status": "down",
    "timestamp": "2026-10-27T08:30:00.000Z",
    "propertyId": "p_123",
    "property": "myapp",
    "message": "..."
    }

A test send from the dashboard posts {"test": true, "message": "This is a test notification from kamustatus"} instead.

Delivery​

  • Each send is recorded in the monitor's Alert history with status triggered, resolved, cert_expiring, domain_expiring or failed.
  • A send counts as failed only when the request itself fails (DNS, connection, timeout) or a required field is missing. An HTTP error status from the receiver is not checked. Failed sends are not retried. While the monitor stays down the rule notifies again every 10 minutes.
  • Expiry warnings go out at most once a day per rule.
  • Disabling a channel in the dashboard does not stop rules from using it. Remove or disable the alert rules instead.