Notification destinations define where and how you receive alerts. You can configure them at four levels: team-wide, per monitor, per tag, or per tag group.
Example request:
$ OHDEAR_TOKEN="your API token"
$ curl https://ohdear.app/api/team-notification-destinations \
-H "Authorization: Bearer $OHDEAR_TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json'
All endpoints below follow the same authentication pattern.
Destination response fields #
Every notification destination endpoint returns an object with these fields:
{
"id": 1,
"label": "Primary alerts",
"team_id": 1,
"channel": "mail",
"destination": {
"mail": "alerts@example.com"
},
"notification_types": [
"HttpUptimeCheckFailedNotification",
"HttpUptimeCheckRecoveredNotification",
"CertificateExpiresSoonNotification"
],
"enabled": true,
"disabled_reason": null
}
id: unique identifier for the destination
label: custom label (if set)
team_id: the team ID (only present for team-level destinations)
channel: the notification channel (see supported channels)
destination: channel-specific destination configuration (see channel destination formats)
notification_types: array of notification type class names this destination receives (see available notification types)
enabled: whether the destination is currently active. A disabled destination keeps all its settings but sends no notifications (see enable or disable)
disabled_reason: when we disabled a destination automatically after repeated delivery failures, this explains why. It's null for active destinations and for destinations you disabled yourself
For tag-level destinations, the response also includes a tag object. For tag-group-level destinations, it includes a tagGroup object.
List notification destinations #
Each level has its own list endpoint:
- Team-level:
GET /api/team-notification-destinations
- Monitor-level:
GET /api/monitors/{monitorId}/notification-destinations
- Tag-level:
GET /api/tags/notification-destinations
- Tag-group-level:
GET /api/tag-groups/{tagGroupId}/notification-destinations
Each returns a list of destination objects.
Create a notification destination #
Each level has its own create endpoint:
- Team-level:
POST /api/team-notification-destinations/{teamId}
- Monitor-level:
POST /api/monitors/{monitorId}/notification-destinations
- Tag-level:
POST /api/tags/{tagId}/notification-destinations
- Tag-group-level:
POST /api/tag-groups/{tagGroupId}/notification-destinations
Request body (JSON):
channel (string, required) -- the notification channel to use (see supported channels)
destination (object, required) -- channel-specific fields (see channel destination formats)
notification_types (array, optional) -- array of notification type class names. If omitted, all available notification types for the channel are enabled
label (string, optional) -- a custom label for this destination (max 191 characters)
test (boolean, optional) -- set to true to send a test notification immediately after creation
Returns the destination object.
Update a notification destination #
Each level has its own update endpoint:
- Team-level:
PUT /api/team-notification-destinations/{teamId}/destination/{destinationId}
- Monitor-level:
PUT /api/monitors/{monitorId}/notification-destinations/{destinationId}
- Tag-level:
PUT /api/tags/{tagId}/notification-destinations/{destinationId}
- Tag-group-level:
PUT /api/tag-groups/{tagGroupId}/notification-destinations/{destinationId}
The request body accepts the same fields as creation.
Returns the updated destination object.
Enable or disable a notification destination #
Disabling a destination pauses it without deleting it: all its settings and selected notification types are kept, but no notifications are sent until you enable it again. This is handy when you want to silence a channel temporarily, or to switch one back on after Oh Dear disabled it automatically following repeated delivery failures.
Each level has its own enable and disable endpoint:
- Team-level:
POST /api/team-notification-destinations/{teamId}/destination/{destinationId}/enable and .../disable
- Monitor-level:
POST /api/monitors/{monitorId}/notification-destinations/{destinationId}/enable and .../disable
- Tag-level:
POST /api/tags/{tagId}/notification-destinations/{destinationId}/enable and .../disable
- Tag-group-level:
POST /api/tag-groups/{tagGroupId}/notification-destinations/{destinationId}/enable and .../disable
These endpoints take no request body.
$ curl -X POST https://ohdear.app/api/monitors/1/notification-destinations/123/disable \
-H "Authorization: Bearer $OHDEAR_TOKEN" \
-H 'Accept: application/json'
Both return the updated destination object. After a disable, enabled is false; after an enable, enabled is true and disabled_reason is cleared. Enabling and disabling through the API never sends an email, so you can flip the state without notifying your team.
Delete a notification destination #
Each level has its own delete endpoint:
- Team-level:
DELETE /api/team-notification-destinations/{teamId}/destination/{destinationId}
- Monitor-level:
DELETE /api/monitors/{monitorId}/notification-destinations/{destinationId}
- Tag-level:
DELETE /api/tags/{tagId}/notification-destinations/destination/{destinationId}
- Tag-group-level:
DELETE /api/tag-groups/{tagGroupId}/notification-destinations/{destinationId}
Returns 204 No Content on success.
Supported channels #
Oh Dear supports these notification channels:
| Channel |
Value |
| Email |
mail |
| Slack |
slackApi |
| Slack Webhook |
slack |
| Discord |
discord |
| Telegram |
telegram |
| Microsoft Teams |
microsoftTeamsWorkflow |
| Microsoft Teams (Legacy) |
microsoftTeams |
| Google Chat |
googleChat |
| PagerDuty |
pagerDuty |
| Opsgenie |
opsgenie |
| Pushover |
pushover |
| ntfy |
ntfy |
| SMS |
sms |
| Webhooks |
webhook |
Each channel requires specific fields in the destination object.
Email:
{ "mail": "alerts@example.com" }
Slack (API):
{ "channel": "#ops-alerts", "slack_api_token": "xoxb-..." }
Slack Webhook:
{ "url": "https://hooks.slack.com/services/..." }
The url field accepts any HTTPS webhook URL that supports the Slack message format, including services like Zulip, Mattermost, and RocketChat.
Discord:
{ "url": "https://discordapp.com/api/webhooks/..." }
Telegram:
{ "chat_id": "123456789" }
Microsoft Teams (Workflow):
{ "url": "https://..." }
Microsoft Teams (Legacy):
{ "url": "https://outlook.webhook.office.com/..." }
Google Chat:
{ "url": "https://chat.googleapis.com/v1/spaces/..." }
Opsgenie:
{ "apiKey": "...", "priority": "P3", "euEndpoint": false }
PagerDuty:
{ "apiKey": "...", "serviceId": "...", "fromEmail": "alerts@example.com" }
Webhooks:
{ "url": "https://example.com/webhook" }
SMS:
{ "to": "+1234567890", "from": "oh dear", "apiKey": "...", "apiSecret": "..." }
Pushover:
{ "userKey": "...", "apiToken": "...", "priority": "0" }
ntfy:
{
"serverUrl": "https://ntfy.sh",
"topic": "my-ohdear-alerts",
"accessToken": "tk_...",
"priority": "3"
}
serverUrl (required) -- the ntfy server URL. Use https://ntfy.sh for the hosted service, or your own server URL for self-hosted instances
topic (required) -- the topic name your devices are subscribed to. Choose something hard to guess, as topics on ntfy.sh are public
accessToken (optional) -- an access token for authenticated ntfy servers or topics
priority (optional) -- priority level from 1 (min/silent) to 5 (max/urgent). Defaults to 3 (default)
Available notification types #
You can control exactly which notifications a destination receives by passing an array of notification type class names. Here are all available types, grouped by check:
Uptime:
HttpUptimeCheckFailedNotification, HttpUptimeCheckRecoveredNotification, PingUptimeCheckFailedNotification, PingUptimeCheckRecoveredNotification, TcpUptimeCheckFailedNotification, TcpUptimeCheckRecoveredNotification
Certificate health:
CertificateExpiresSoonNotification, CertificateFixedNotification, CertificateHasChangedNotification, CertificateUnhealthyNotification
Broken links:
BrokenLinksFoundNotification, BrokenLinksFixedNotification
Mixed content:
MixedContentFoundNotification, MixedContentFixedNotification
Performance:
PerformanceThresholdExceededNotification, PerformanceThresholdRecoveredNotification, PerformanceDeltaExceededNotification
Lighthouse:
LighthouseIssuesDetectedNotification, LighthouseIssuesFixedNotification
Cron jobs:
CronNotExecutedOnTimeNotification, CronFailedNotification
Sitemap:
SitemapIssuesFoundNotification, SitemapIssuesFixedNotification
DNS:
DnsIssuesFoundNotification, DnsIssuesFixedNotification, DnsRecordsChangedNotification
DNS blocklist:
DnsBlocklistIssuesFoundNotification, DnsBlocklistIssuesFixedNotification
Application health:
ApplicationHealthClientErrorNotification, ApplicationHealthResultsTooOldNotification, ApplicationHealthProblemDetectedNotification, ApplicationHealthProblemFixedNotification
Domain:
DomainIssuesFoundNotification, DomainIssuesFixedNotification
Port scanning:
PortsCheckFailedNotification, PortsCheckRecoveredNotification
AI-powered monitoring:
AiCheckSucceededNotification, AiCheckFailedNotification
Oh Dear system:
MonitorAddedNotification
Note
The MonitorAddedNotification type is not available for the Opsgenie and PagerDuty channels.