Examples / Incident triage from any alert

Incident triage from any alert

Point any monitoring tool at a webhook URL. Murmurator normalizes the payload, has a model classify severity, opens a GitHub issue, and pages Slack only for real SEV1s.

WebhooksJavaScriptYour AI modelsGitHubSlack

What you tell the assistant

Give me a webhook our monitoring can call. Classify the alert's severity, open a GitHub issue in northwind/ops with a summary, and post to #incidents only when it's SEV1.

Why it works

  • Works with any tool that can POST JSON — no plugin required.
  • JavaScript normalizes wildly different alert formats before the model sees them.
  • Low-severity alerts are tracked without waking anyone up.
Build this workflow

What it builds

Trigger
Webhook
HTTP POST
javascript
Normalize alert
→ title, service, details
llm
Classify severity
fast · structured
tool
Open tracking issue
github.create_issue
tool
Page #incidents
slack.post_message
if classify.output.data.severity equals SEV1
View the definition
trigger:
  kind: webhook
steps:
  - key: normalize
    name: Normalize alert
    kind: javascript
    inputs: { body: "{{ trigger.body }}" }
    outputs: { title: string, service: string, details: string }
    code: |
      function main({ body }) {
        const alert = body.alert || body
        return {
          title: alert.title || alert.name || "Untitled alert",
          service: alert.service || (alert.tags || {}).service || "unknown",
          details: JSON.stringify(alert).slice(0, 4000)
        }
      }
  - key: classify
    name: Classify severity
    kind: llm
    model: fast
    prompt: "Classify this production alert as SEV1, SEV2 or SEV3 and summarize it in two sentences: {{ steps.normalize.output }}"
    schema:
      type: object
      properties:
        severity: { type: string, enum: [SEV1, SEV2, SEV3] }
        summary: { type: string }
      required: [severity, summary]
  - key: issue
    name: Open tracking issue
    kind: tool
    tool: github.create_issue
    args:
      repo: northwind/ops
      title: "[{{ steps.classify.output.data.severity }}] {{ steps.normalize.output.title }}"
      body: "{{ steps.classify.output.data.summary }}\n\nService: {{ steps.normalize.output.service }}"
      labels: [incident]
  - key: page
    name: "Page #incidents"
    kind: tool
    if: { path: steps.classify.output.data.severity, equals: SEV1 }
    tool: slack.post_message
    args:
      channel: C05INCIDENT
      text: ":fire: SEV1 on {{ steps.normalize.output.service }}: {{ steps.normalize.output.title }} — {{ steps.issue.output.html_url }}"

A sample run

What each step produces

Normalize alert javascript

succeeded
{
  "title": "p95 latency > 2s on checkout",
  "service": "checkout",
  "details": "{\"title\":\"p95 latency > 2s on checkout\",\"service\":\"checkout\",\"value\":2.43}"
}

Classify severity llm

succeeded
Using model fast (Claude Haiku 4.5, Murmurator AI)
{
  "text": "",
  "data": {
    "severity": "SEV2",
    "summary": "Checkout p95 latency crossed 2s (2.43s). Customers can still complete purchases, but conversion is likely affected."
  }
}

Open tracking issue tool

succeeded
Calling github.create_issue
{
  "number": 311,
  "html_url": "https://github.com/northwind/ops/issues/311"
}

Page #incidents tool

Skipped because its if condition was not met

skipped

Trigger payload

{
  "body": {
    "alert": {
      "title": "p95 latency > 2s on checkout",
      "service": "checkout",
      "value": 2.43
    }
  }
}

Your next automation is one sentence away.

14-day free trial with $5 of built-in AI included. Cancel anytime.