Skip to content

Notifications

BRIDGEPORT delivers notifications through four channels — in-app, email (SMTP), Slack, and outgoing webhooks — with per-user preferences, environment filtering, and bounce logic to keep you informed without alert fatigue.

In-app notifications work out of the box. Click the bell icon in the top navigation to see your notifications.

  1. Go to Admin > Notifications and open the Email tab.
  2. Configure your SMTP server:
    Host: smtp.example.com
    Port: 587
    Secure: true (TLS)
    Username: noreply@example.com
    Password: ••••••••
    From Address: noreply@example.com
    From Name: BRIDGEPORT
  3. Click Test Connection to verify.
  4. Click Send Test Email to your address.
  5. Enable the configuration and save.
  1. Create an Incoming Webhook in your Slack workspace.
  2. Go to Admin > Notifications and open the Slack tab.
  3. Click Add Channel and paste the webhook URL.
  4. Click Test to send a test message to the channel.
  5. Optionally set the channel as default (receives all unrouted notifications).
  6. Configure type routing to send specific notification types to specific channels.
  1. Go to Admin > Notifications and open the Webhooks tab.
  2. Click Add Webhook and enter the endpoint URL.
  3. Optionally filter by environment or notification type.
  4. BRIDGEPORT sends a POST with JSON payload to your endpoint when matching notifications fire.
flowchart TD
    EVENT[System Event] --> SEND[sendSystemNotification]
    SEND --> TYPE{Notification Type<br/>enabled?}
    TYPE -->|No| STOP[Skip]
    TYPE -->|Yes| USERS[Get all users]

    USERS --> PREF{Per-user<br/>preferences}

    PREF --> IN_APP[In-App]
    PREF --> EMAIL[Email via SMTP]

    SEND --> WEBHOOK[Outgoing Webhooks<br/>if webhook in defaultChannels]
    SEND --> SLACK[Slack<br/>via routing rules]

    IN_APP --> BELL[Bell icon + SSE push]
    EMAIL --> SMTP[SMTP delivery]
    WEBHOOK --> HTTP[HTTP POST]
    SLACK --> HOOK[Slack Incoming Webhook]

When a system event occurs (server offline, deployment failed, backup succeeded, etc.):

  1. BRIDGEPORT looks up the NotificationType by code.
  2. If the type is disabled, nothing happens.
  3. For each user, BRIDGEPORT checks their NotificationPreference:
    • In-app: Creates a Notification record and emits an SSE event for real-time bell updates.
    • Email: If the user (or type default) has email enabled, sends via SMTP.
  4. If the type’s defaultChannels includes webhook, BRIDGEPORT dispatches to all configured outgoing webhooks.
  5. Slack routing rules determine which Slack channels receive the notification.

BRIDGEPORT ships with these predefined notification types:

CodeNameDefault ChannelsSeverity
user.account_createdAccount Createdin-app, emailinfo
user.password_changedPassword Changedin-app, emailinfo
user.role_changedRole Changedin-app, emailinfo
user.api_token_createdAPI Token Createdin-appinfo
user.failed_loginFailed Login Attemptin-app, emailwarning
CodeNameDefault ChannelsSeverityBounce
system.backup_failedBackup Failedin-app, email, webhookcritical
system.backup_successBackup Succeededin-appinfo
backup.rotation_errorBackup Rotation Errorin-app, email, webhookwarning3 / 15 min
backup.policy_first_pruneRetention Policy First Prunein-appinfo
system.health_check_failedHealth Check Failedin-app, email, webhookwarning3 / 15 min
system.health_check_recoveredHealth Check Recoveredin-app, email, webhookinfo
system.deployment_successDeployment Succeededin-appinfo
system.deployment_failedDeployment Failedin-app, email, webhookcritical
system.server_offlineServer Offlinein-app, email, webhookcritical2 / 15 min
system.server_onlineServer Back Onlinein-app, email, webhookinfo
system.container_crashContainer Crashedin-app, email, webhookwarning3 / 15 min
system.container_recoveredContainer Recoveredin-appinfo
system.database_unreachableDatabase Unreachablein-app, email, webhookcritical3 / 15 min

The Bounce column shows the threshold / cooldown. See Bounce Logic below.

Each notification type has a template with {{placeholder}} variables that are filled in at send time:

PlaceholderUsed InExample Value
{{serverName}}Server offline/onlineweb-server-01
{{serviceName}}Deployment success/failedapi-backend
{{containerName}}Container crash/recoveredmyapp_web_1
{{databaseName}}Backup, database unreachableproduction-db
{{imageTag}}Deployment eventsv2.3.1
{{error}}Failure eventsConnection refused
{{resourceType}}Health check eventsService
{{resourceName}}Health check eventsapi-backend
{{oldRole}} / {{newRole}}Role changedviewer / admin
{{changedBy}}Password changed by admin@example.com
{{tokenName}}API token createdci-deploy-key
{{count}}Failed login5

Every user can customize which notification types they receive and on which channels.

Go to the Notifications page (/notifications) and click the Preferences tab.

For each notification type, toggle:

ChannelDescription
In-AppShow in the notification bell
EmailSend to the user’s email address
WebhookInclude in outgoing webhook dispatches

If a user has not set a preference for a type, the type’s defaultChannels are used.

You can restrict notifications to specific environments:

  1. In the preferences panel, click Filter Environments for a notification type.
  2. Select the environments you want to receive notifications for.
  3. Notifications from other environments will be silently skipped for that type.

This is useful when you have staging and production environments but only want critical alerts from production.

Bounce logic prevents notification storms when a resource fails repeatedly.

  1. Each failure increments a consecutiveFailures counter in the BounceTracker.
  2. When the counter reaches the bounceThreshold, a notification is sent and alertSentAt is recorded.
  3. Further failures during the bounceCooldown period are suppressed.
  4. After the cooldown expires, the next failure sends another notification.
  5. When the resource recovers (success after an alert was sent), a recovery notification is sent and the tracker resets.

Configure bounce behavior per notification type in Admin > Notifications:

SettingDescriptionDefault
bounceEnabledWhether bounce tracking appliesVaries
bounceThresholdConsecutive failures before first alert3
bounceCooldownSeconds before re-alerting900 (15 min)

Bounce settings (bounceEnabled, bounceThreshold, bounceCooldown) are configured per notification type in Admin > Notifications — they are global, not per-environment. Earlier releases had per-environment bounceThreshold / bounceCooldownMs fields on MonitoringSettings; those were silently ignored and have been removed.

You can add multiple Slack channels, each with its own Incoming Webhook URL:

  1. Default channel: Receives all notifications that do not have a specific routing rule.
  2. Additional channels: Route specific notification types to dedicated channels.

Type routing lets you send specific notification types to specific Slack channels:

  1. Go to Admin > Notifications > Slack > Type Routing.
  2. Map notification types to channels.
  3. Optionally filter by environment.

Example setup:

Notification TypeSlack ChannelEnvironment
system.deployment_failed#deploys-criticalProduction only
system.server_offline#infra-alertsAll
system.backup_failed#backup-alertsAll

If no routing matches, the notification goes to the default channel (if one is set and enabled).

Each environment can set its own Slack channel without touching the global type-routing rules:

  1. Go to Settings > Notifications in the environment.
  2. Pick a channel (or Inherit default to clear the override).
  3. Click Send Test Message to verify the chosen channel is reachable.

The override does two things, depending on how the notification type is routed globally:

  • Fan-out demultiplexer — when a type is routed to more than one channel, the override collapses that fan-out and sends only to this environment’s channel. This is how you split shared alerts per environment: route, say, system.backup_failed to both #alerts and #alerts-staging globally, then set the staging environment’s override to #alerts-staging so staging’s copy lands there alone (and you can mute that one channel without losing production alerts).
  • Default fallback — when a type matches no routing rule, the override stands in for the global default channel.

A type routed to exactly one channel is left untouched — it reaches that channel from every environment regardless of any override (e.g. Updates → #ntf-bridgeport). If the override points at a disabled or deleted channel, it is ignored (a fan-out keeps all its channels; an unrouted type falls through to the global default).

For each notification, BRIDGEPORT resolves the target channels as follows:

  1. Collect the channels whose SlackTypeRouting rule matches the type (and passes the environment filter, if any).
  2. Exactly one match → send there. The override is not consulted.
  3. More than one match → if the environment has a usable override, send only to the override channel; otherwise send to all matched channels.
  4. No match → send to the environment override if set, else the global default channel.

BRIDGEPORT sends rich Slack messages using Block Kit:

  • Color-coded sidebar (red for critical, amber for warning, green for info)
  • Header with severity emoji
  • Fields for environment, server, service, and image tag
  • Action buttons linking back to BRIDGEPORT (requires publicUrl in System Settings)

Outgoing webhooks send notification data as JSON POST requests to your endpoints.

{
"type": "system.deployment_failed",
"severity": "critical",
"title": "Deployment Failed",
"message": "Deployment of \"api-backend\" failed: Image pull error",
"data": {
"serviceName": "api-backend",
"serviceId": "svc_abc123",
"imageName": "registry.example.com/my-registry/api-backend",
"serverName": "web-server-01",
"imageTag": "v2.3.1",
"error": "Image pull error"
},
"environment": "production",
"timestamp": "2026-02-25T10:30:00.000Z"
}

The built-in Slack integration renders a compact message per notification. Recent tuning:

  • No redundant message block. The Slack Block Kit payload omits the free-text message block when the structured fields already convey the same information — the title plus context fields are enough.
  • No footer timestamp. Slack already renders the message time; the duplicate {timestamp} footer block was removed.
  • No internal type code. The Type: system.deployment_success context line was removed — the header (emoji + title + color) already tells a reader what happened, and the raw type code is only meaningful for debugging routing rules.
  • Full image reference. Deployment messages include the full image path (e.g., registry.example.com/my-registry/web-app) on its own line, so it’s clear which image was deployed, not just the tag.
  • Deployment success messages include every tag pointing to the deployed digest (e.g., v2.3.1, latest) rather than just the one that was requested, so you can see the full set of identifiers at a glance.
  • Failure reason inline. deployment_failed messages render the error (truncated to 500 chars) directly in the channel, so you can see why a deploy failed without clicking through.
  • Action buttons use serviceId to link back to the service detail page in BRIDGEPORT when publicUrl is configured. Both success and failure messages carry serviceId, so the View Service button appears consistently on either outcome.

Outgoing webhooks retry on failure based on System Settings:

SettingDefaultWhere
webhookMaxRetries3Admin > System Settings
webhookTimeoutMs10000Admin > System Settings
SettingDefaultDescription
Notification retention30 daysOld notifications are cleaned up daily

Configure these in Admin > System Settings:

SettingDefaultDescription
publicUrlBRIDGEPORT URL for Slack action buttons
webhookMaxRetries3Outgoing webhook retry count
webhookTimeoutMs10000Outgoing webhook timeout

Configured in Admin > Notifications > Email:

SettingRequiredDescription
HostYesSMTP server hostname
PortYesSMTP port (587 for TLS, 465 for SSL, 25 for plain)
SecureYesUse TLS/SSL
UsernameNoSMTP auth username
PasswordNoSMTP auth password (encrypted at rest)
From AddressYesSender email address
From NameNoSender display name (default: BRIDGEPORT)
EnabledYesKill switch for email delivery
  1. Check preferences: Go to Notifications > Preferences and verify in-app is enabled for the type.
  2. Check environment filter: If you have environment filtering set, the notification may be for a different environment.
  3. Check notification type: Go to Admin > Notifications and verify the type is enabled.
  1. SMTP configured? Go to Admin > Notifications > Email and verify the configuration.
  2. SMTP enabled? The enabled toggle must be on.
  3. Test connection: Click Test Connection to verify SMTP connectivity.
  4. Send test email: Click Send Test Email to verify delivery.
  5. Check spam folder: SMTP emails may be filtered by your email provider.
  6. Check user preference: The user must have email enabled for that notification type.
  1. Channel enabled? Verify the Slack channel is enabled in Admin > Notifications > Slack.
  2. Webhook URL valid? Click Test to send a test message.
  3. Type routing configured? If the notification type is not routed to any channel and there is no default channel, Slack notifications are silently skipped.
  4. Environment filter: Check if the routing has an environment filter that excludes the current environment.
  1. Enable bounce logic: In Admin > Notifications, enable bounce for noisy types.
  2. Increase thresholds: Set bounceThreshold higher (e.g., 5 instead of 3).
  3. Increase cooldown: Set bounceCooldown higher (e.g., 3600 for 1 hour).
  4. Disable low-priority types: Disable notification types you do not need (e.g., system.backup_success).
  5. Use environment filtering: Only receive alerts from production, not staging.
  1. Check endpoint: Verify the URL is reachable from BRIDGEPORT.
  2. Check timeout: If the endpoint is slow, increase webhookTimeoutMs in System Settings.
  3. Check retries: BRIDGEPORT retries up to webhookMaxRetries times.
  4. Check logs: Look for [Webhook] messages in BRIDGEPORT container logs.