Integrations

Slack

Send incident notifications to Slack via Block Kit: one timeline-style thread per incident, every lifecycle event.

Slack

Yorker posts incident notifications to Slack via an Incoming Webhook. 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.

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:

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:

{
  "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

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}} returns ๐Ÿ”ด / ๐ŸŸก / ๐Ÿ”ต
  • {{eventEmoji eventType}} returns ๐Ÿšจ / โž• / ๐Ÿ”บ / ๐Ÿ‘ค / โœ… / โ˜‘๏ธ / ๐Ÿ” / ๐Ÿ“
  • {{upperCase str}}, {{titleCase str}}
  • {{join array ", "}}
  • {{#ifHasSource "synthetic_http"}}โ€ฆ{{/ifHasSource}} matches synthetic_http, synthetic_browser, or synthetic_mcp
  • {{jsonBody payload}} splats a value as raw JSON (already JSON.stringifyd). 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:

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