Skip to main content

Set up Slack or email alerts

Goal

You'll create an alert rule that posts to Slack and/or emails a distribution list whenever a checkpoint fails.

Slack and email dispatchers are shipped (worker/.../dispatch_alert.py). Microsoft Teams (FEATURE-15), generic webhooks (FEATURE-16), PagerDuty (FEATURE-17), and the incident-management bridges (Jira / Linear, FEATURE-28) ship as separate channels — see Alerts for those.

Prereqs

For Slack

  • A Slack incoming-webhook URL (https://hooks.slack.com/services/T…/B…/…). Create one at https://api.slack.com/appsCreate appIncoming webhooks → enable + add to your #data-quality channel. Copy the URL.

For email

  • The PLACEHOLDER Cloud deployment has SMTP configured. Check that SMTP_HOST, SMTP_USER, SMTP_PASSWORD, SMTP_FROM are set in .env (see Configuration). Without these, the dispatcher will log "smtp not configured" and skip the channel.
  • A target email or comma-separated list (oncall@example.com,data-leads@example.com).

Steps

  1. Navigate to Alerts → New.

  2. Name the rule. Be specific — prod-orders-checkpoint-failure beats alert-1.

  3. Pick a scope:

    • Checkpoint — the rule fires only when this checkpoint's runs fail.
    • Workspace-wide — fires on any failure in the workspace. Use sparingly.
  4. Pick a trigger:

    • on_failure — fire when the result has success = false. The common choice.
    • on_anomaly — fire when an AnomalyEvent is written for an asset in scope.
    • on_success — fire on every successful run (useful for "data landed" confirmations).
    • always — every run, regardless of outcome.
  5. Pick a channel:

    Slack:

    • Channel = slack.
    • Webhook URL = paste the Slack incoming-webhook URL.

    Email:

    • Channel = email.
    • Recipients = comma-separated email list.
  6. Save. Optionally, click Send test — PLACEHOLDER Cloud fires a synthetic payload to the destination so you can confirm the channel works before a real failure.

Verify

  • The rule appears under Alerts with enabled = true.
  • Click Send test → the message shows up in Slack (or the test recipient's inbox) within a few seconds.
  • On the next real failure, you receive a notification with the failing expectation list and a deep link to the result detail.

Checking the fire log (dispatch history)

"Did the alert actually send?" is the first question after any incident — so every alert rule keeps a fire log of its dispatch attempts.

  • On the Alerts page, click Fire log on a rule's row. The panel lists the rule's recent dispatch attempts newest-first: when it fired, the status (Sent / Failed / Pending), the channel, and — on a failure — the error message. The empty state ("This alert hasn't fired yet.") tells you at a glance whether the rule has ever triggered.
  • A rule that's enabled but whose fire log is empty has never matched a result; a fire log full of Failed rows means deliveries are breaking (check the error — a 404 usually means a revoked webhook URL).
  • The same data is available over the API at GET /api/v1/organizations/{org_id}/workspaces/{workspace_id}/alert-rules/{id}/events (paginated, {"data": [...]}). Any secret that leaked into an error message (a webhook URL's secret path, a token) is redacted before it reaches you.
  • This is distinct from the History panel on the same row, which shows config changes (who edited the rule) rather than deliveries.

Caveats

  • Slack webhook URLs are bearer credentials. PLACEHOLDER Cloud stores them encrypted at rest via the per-tenant DEK (HARDEN-15); a legacy plaintext fallback is kept on the read path so existing rows keep working, and the dispatcher logs alert_destination_legacy_plaintext whenever it falls through that path. Per-tenant DEKs under a KMS-backed KEK are tracked in HARDEN-16.
  • The dispatcher retries up to 3 times with exponential backoff on transient failures (timeouts, 5xx). Persistent failures land as a Failed row in the rule's Fire log (see above), with the error message attached.
  • One rule, one channel. To send the same alert to Slack + email, create two rules with the same scope.

@mentioning users and groups (Slack, Teams)

When a checkpoint fires, the message lands in the channel but doesn't ping anyone by default. To target specific people or groups, fill in the Mentions field on the alert-rule form.

Slack:

  • Paste a comma-separated list of Slack member IDs (U…) or user-group IDs (S…). Find a member ID in Slack via Profile → Copy member ID; user-group IDs are in the user-group settings URL.
  • DQ Cloud wraps each one server-side into Slack's mention format (<@U…> / <!subteam^S…>) and prepends them to the outbound message text so the channel members get pinged.

Microsoft Teams:

  • Paste a comma-separated list of User Principal Names (alice@example.com). DQ Cloud wraps each one as <at>alice@example.com</at> and emits the paired msteams.entities block the Adaptive Card mention contract requires — without that block Teams would render the tag as literal text.

Other channels (email, generic webhook, PagerDuty) have no transport-level mention concept. The field is silently ignored for those rules — use the destination's own routing instead (a different to: address, a different webhook URL, a different PagerDuty service).

Routing by severity

Each alert rule carries a min_severity field (default error) that filters which validation-result severities fan the rule out. Model one rule per channel and pick the lowest severity that warrants firing it — PagerDuty at critical, Slack #warnings at warning, an email digest at info. The full grading table and worked example live in Alerts → Severity routing. Shipped in FEATURE-10 + FEATURE-18.