---
title: 'Slack'
description: 'Send incident notifications to Slack via Block Kit — one timeline-style thread per incident, every lifecycle event.'
section: 'Integrations'
canonical_url: 'https://yorkermonitoring.com/docs/integrations/slack'
---

# Slack

Yorker posts incident notifications to Slack via an [Incoming Webhook](https://api.slack.com/messaging/webhooks). Slack is the **timeline** channel — by default it receives every lifecycle event, so your channel becomes a running record of the incident.

For the underlying model (lifecycle states, event types, scoped hypothesis), see [Incidents](/docs/concepts/incidents).

## Set up

1. In Slack, create an Incoming Webhook and copy the URL.
2. In Yorker, go to **Settings > Notification Channels**, click **Create Channel**, pick **Slack**, and paste the webhook URL.
3. The channel is subscribed to incidents by default. Wire it to any alert rule and it will participate in incident dispatch.

Or via the API:

```bash
curl -X POST https://yorkermonitoring.com/api/notification-channels \
  -H "Authorization: Bearer $YORKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ops-channel",
    "channel": {
      "type": "slack",
      "webhookUrl": "https://hooks.slack.com/services/T.../B.../..."
    }
  }'
```

## What gets posted

Slack receives **every** incident event by default:

- `opened`
- `alert_attached`
- `severity_changed`
- `acknowledged`
- `auto_resolved`
- `closed`
- `reopened`
- `note_added`

The `opened` event uses a rich Block Kit layout — header, severity, affected checks, locations, symptom window, shared failing domains, hypothesis, ruled-out list, and a **View in Yorker** button. Subsequent events are single-section status lines so the thread reads like a timeline.

Example `opened` payload:

```json
{
  "blocks": [
    { "type": "header", "text": { "type": "plain_text", "text": "🔴 Incident opened — Checkout API outage" } },
    { "type": "section", "text": { "type": "mrkdwn", "text": "*Severity*: `CRITICAL` · *Incident*: <https://yorkermonitoring.com/dashboard/incidents/inc_abc|inc_abc>" } },
    { "type": "section", "fields": [
      { "type": "mrkdwn", "text": "*Affected checks*\nCheckout API" },
      { "type": "mrkdwn", "text": "*Locations*\nloc_us_east_1, loc_eu_west_1" },
      { "type": "mrkdwn", "text": "*Symptom window*\n2026-04-15T09:58:00Z → ongoing" },
      { "type": "mrkdwn", "text": "*Shared failing domains*\napi.stripe.com" }
    ]},
    { "type": "section", "text": { "type": "mrkdwn", "text": "*Hypothesis*\nStripe API is returning 503/504; checkout is blocked." } },
    { "type": "section", "text": { "type": "mrkdwn", "text": "*Ruled out*\n• DNS resolution: NXDOMAIN not observed\n• TLS: handshake completes" } },
    { "type": "context", "elements": [{ "type": "mrkdwn", "text": "Scope: `external_symptoms_only` — Yorker measures external symptoms only" }] },
    { "type": "actions", "elements": [{ "type": "button", "text": { "type": "plain_text", "text": "View in Yorker" }, "url": "https://yorkermonitoring.com/dashboard/incidents/inc_abc" }] }
  ]
}
```

## Template overrides

Every event's default payload can be replaced with a Handlebars-rendered Block Kit JSON string. The template renders against the full incident event context.

### Edit in the web UI

The fastest way to author overrides is the per-channel template editor. Open **Settings > Notification Channels**, click **Templates** next to the Slack channel, and you get:

- A Handlebars editor with JSON syntax highlighting
- A live **preview** pane that renders your template against one of six canonical fixtures (single HTTP failure, multi-location burst, browser check, MCP, etc.)
- A per-event drop-down so you can author one template per lifecycle event
- A **library** sidebar with curated starter blocks and end-to-end examples (runbook-style, terse-ack, etc.) that apply with a click
- **Compare with saved** diff view before you save
- **Send test**: dispatches the current saved template to the real Slack webhook using the selected fixture (60-second cooldown per channel)
- **Reset to default** per field: clears the override and falls back to the shipping payload

Saved overrides apply immediately to the next incident dispatch for that channel.

### Edit via the API

```bash
curl -X PUT https://yorkermonitoring.com/api/notification-channels/nch_abc \
  -H "Authorization: Bearer $YORKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "incidentTemplate": {
      "channelType": "slack",
      "overrides": {
        "opened": {
          "blocks": "{\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"{{severityEmoji incident.severity}} *{{incident.title}}*\\n{{payload.hypothesis.summary}}\"}}]}"
        }
      }
    }
  }'
```

The `blocks` body must render to a JSON object with a `blocks: [...]` array. A render error or a parse error falls back to the default payload and logs a warning. A bad template never fails dispatch. Each body is capped at 32 KiB.

Use `"default"` as the event key to define a single override that applies to every event type that doesn't have its own entry.

### Available helpers

- `{{severityEmoji incident.severity}}` → `🔴 / 🟡 / 🔵`
- `{{eventEmoji eventType}}` → `🚨 / ➕ / 🔺 / 👤 / ✅ / ☑️ / 🔁 / 📝`
- `{{upperCase str}}`, `{{titleCase str}}`
- `{{join array ", "}}`
- `{{#ifHasSource "synthetic_http"}}…{{/ifHasSource}}` — `synthetic_http`, `synthetic_browser`, or `synthetic_mcp`
- `{{jsonBody payload}}` — splat a value as raw JSON (already `JSON.stringify`d). In JSON-producing channels (Slack, webhook, PagerDuty, ServiceNow) escaping is disabled, so `{{jsonBody x}}` and `{{{jsonBody x}}}` are equivalent. In email HTML templates the double-stash form is HTML-escaped by default — use triple-stash only as an explicit opt-out.

### Render context

The full context mirrors `serializeIncidentEventForExport`:

- `eventId`, `eventType`, `incidentId`, `teamId`, `occurredAt`
- `actor` — `{ type: "user" | "system", id }`
- `payload` — the full event payload (observations, hypothesis, event-specific fields)
- `incident` — `{ incidentId, title, severity, state, openedAt, triageUrl }`

## Disabling incident routing

To fall back to the legacy per-alert Slack dispatch, set `incidentSubscribed: false` on the channel:

```bash
curl -X PUT https://yorkermonitoring.com/api/notification-channels/nch_abc \
  -H "Authorization: Bearer $YORKER_API_KEY" \
  -d '{ "incidentSubscribed": false }'
```
