Quick answer: Connect your crash reporting tool to Discord, Slack, or other channels via webhooks to get instant notifications when new crashes appear or crash rates spike. Configure notification thresholds carefully to avoid alert fatigue — notify on new crash signatures and rate spikes, not every individual crash.

A crash reporting dashboard is only useful if someone is looking at it. In practice, your team is busy writing code, designing levels, and fixing other bugs — they’re not refreshing the crash dashboard every hour. Webhook notifications bring crash alerts to where your team already is: Discord, Slack, or whatever communication tool your studio uses. When a new crash type appears or crash rates spike after an update, the right people find out immediately.

Setting Up Discord Webhooks

Discord is the most common communication tool for indie game studios, and setting up crash webhooks is straightforward. In your Discord server, go to Server Settings > Integrations > Webhooks, click “New Webhook,” choose the channel where you want crash notifications to appear, and copy the webhook URL.

The webhook URL looks like https://discord.com/api/webhooks/1234567890/abcdef.... Keep this URL secret — anyone with the URL can post messages to your channel. Store it as an environment variable or in your crash reporting tool’s settings, never in source code.

Discord webhooks accept JSON payloads with rich embed formatting. Here’s a well-structured crash notification payload:

// Discord webhook payload for a crash notification
{
  "username": "Bugnet Crash Reporter",
  "embeds": [{
    "title": "New Crash Detected",
    "color": 15158332,
    "fields": [
      {
        "name": "Crash Signature",
        "value": "`NullRef in InventoryManager.EquipItem`",
        "inline": false
      },
      {
        "name": "Affected Users",
        "value": "47",
        "inline": true
      },
      {
        "name": "Platform",
        "value": "Windows (89%), Linux (11%)",
        "inline": true
      },
      {
        "name": "Version",
        "value": "v1.2.1",
        "inline": true
      },
      {
        "name": "First Seen",
        "value": "10 minutes ago",
        "inline": true
      }
    ],
    "footer": {
      "text": "View full report in Bugnet"
    },
    "url": "https://bugnet.io/app/bugs/crash-12345",
    "timestamp": "2026-04-07T14:30:00Z"
  }]
}

The color field uses decimal color values. Use red (15158332) for critical crashes, orange (16744448) for warnings, and green (5763719) for resolved notifications. Including a direct link to the full crash report in the url field lets your team jump straight from the notification to the investigation.

Setting Up Slack Webhooks

For studios using Slack, the setup process is similar. Go to the Slack App Directory, search for “Incoming WebHooks,” and add it to your workspace. Choose a channel and copy the webhook URL. Slack’s payload format differs slightly from Discord’s:

// Slack webhook payload for a crash notification
{
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "New Crash Detected"
      }
    },
    {
      "type": "section",
      "fields": [
        {
          "type": "mrkdwn",
          "text": "*Signature:*\n`NullRef in InventoryManager.EquipItem`"
        },
        {
          "type": "mrkdwn",
          "text": "*Affected Users:*\n47"
        },
        {
          "type": "mrkdwn",
          "text": "*Platform:*\nWindows (89%), Linux (11%)"
        },
        {
          "type": "mrkdwn",
          "text": "*Version:*\nv1.2.1"
        }
      ]
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "View Crash Report"
          },
          "url": "https://bugnet.io/app/bugs/crash-12345"
        }
      ]
    }
  ]
}

Slack uses Block Kit for rich message formatting. The actions block adds a clickable button that links directly to the crash report. You can test your payload formatting using Slack’s Block Kit Builder before integrating it into your pipeline.

Choosing What to Notify On

The most important decision is what events trigger a notification. Sending a message for every individual crash report will flood your channel within hours of launch — a game with 10,000 DAU and a 1% crash rate generates 100 crash reports per day, which is too many individual notifications.

Instead, notify on these events:

Building the Notification Pipeline

If you’re using a crash reporting tool like Bugnet that has built-in webhook support, configuration is just a matter of entering your webhook URL and selecting your notification preferences. If you’re building your own pipeline, here’s the architecture:

Your crash ingestion service receives crash reports and groups them by signature. A background job runs periodically (every minute for spike detection, daily for summaries) and compares current crash rates to historical baselines. When a threshold is crossed, the job constructs a webhook payload and sends it to the configured URLs.

// Go example: sending a Discord webhook notification
func sendDiscordWebhook(webhookURL string, crash CrashSummary) error {
    payload := map[string]interface{}{
        "username": "Crash Reporter",
        "embeds": []map[string]interface{}{
            {
                "title": "New Crash: " + crash.Signature,
                "color": 15158332,
                "fields": []map[string]interface{}{
                    {"name": "Users Affected", "value": fmt.Sprintf("%d", crash.UserCount), "inline": true},
                    {"name": "Platform", "value": crash.Platform, "inline": true},
                    {"name": "Version", "value": crash.Version, "inline": true},
                },
                "url":       fmt.Sprintf("https://bugnet.io/app/bugs/%s", crash.ID),
                "timestamp": time.Now().Format(time.RFC3339),
            },
        },
    }

    body, _ := json.Marshal(payload)
    resp, err := http.Post(webhookURL, "application/json", bytes.NewReader(body))
    if err != nil {
        return fmt.Errorf("webhook request failed: %w", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode == 429 {
        // Discord rate limit: retry after the specified delay
        retryAfter := resp.Header.Get("Retry-After")
        slog.Warn("discord rate limited", "retry_after", retryAfter)
    }

    return nil
}

Handle rate limits gracefully. Discord allows 30 requests per minute per webhook URL. Slack allows 1 request per second per webhook. If your crash rate is high enough to hit these limits, batch multiple crashes into a single notification or increase your notification threshold.

Avoiding Alert Fatigue

Alert fatigue is the enemy of any notification system. When your crash channel sends 50 messages a day, people stop reading them. When they stop reading them, they miss the one message that matters. Keep your crash notification channel high-signal by following these principles:

Set a cooldown period for each crash signature. After sending a notification for a new crash, don’t send another notification for the same signature for at least 1 hour, even if more occurrences come in. Include the growing count in an updated message if your platform supports message editing (Slack does, Discord webhooks do not).

Use a separate channel for daily summaries versus urgent alerts. The summary channel is where your team checks game health each morning. The urgent channel is for immediate-action items only — new crashes and rate spikes. Keep the urgent channel quiet enough that every message demands attention.

Review your notification rules monthly. If you find that certain notifications are consistently ignored or don’t lead to action, either remove them or adjust their thresholds. A notification system that evolves with your team’s needs stays useful; one that never changes becomes noise.

The best crash notification is one that saves you from a 1-star review.