Incident Ingest

Prometheus AlertManager + Alert24 Integration

Forward Prometheus AlertManager alert notifications to Alert24 as incidents. Covers webhook adapter, severity mapping, and AlertManager configuration.

Prometheus AlertManager supports a webhook_config receiver that POSTs alerts to any URL. Alert24's incidents API is compatible with a simple template — no middleware required.

Before you start

You'll need:

  • An Alert24 API key with write or incidents scope (Settings → API Keys)
  • Access to your alertmanager.yml configuration

Option A: Direct webhook (simple)

AlertManager's webhook payload doesn't match Alert24's schema directly. The simplest approach is a small adapter — either a Cloudflare Worker, Lambda, or a one-liner with jq piped through curl.

For teams that want zero extra infrastructure, use Option B below.

Option B: alertmanager-webhook-forwarder script

Create a tiny receiver script at a URL AlertManager can reach. Here's a minimal Node.js/Express version:

// adapter.js — run with: node adapter.js
const express = require('express');
const app = express();
app.use(express.json());

const API_KEY = process.env.ALERT24_API_KEY;

app.post('/alert24', async (req, res) => {
  const alerts = req.body.alerts || [];
  for (const alert of alerts) {
    const firing = alert.status === 'firing';
    if (!firing) continue; // skip resolved — handle separately if needed

    const severity = {
      critical: 'critical',
      warning: 'high',
      info: 'info',
    }[alert.labels?.severity] || 'medium';

    await fetch('https://app.alert24.net/api/v1/incidents', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        title: alert.annotations?.summary || alert.labels?.alertname,
        description: alert.annotations?.description || '',
        severity,
        alias: `prometheus-${alert.labels?.alertname}-${alert.labels?.instance || 'global'}`,
        source: 'prometheus',
        tags: Object.keys(alert.labels).map(k => `${k}:${alert.labels[k]}`),
      }),
    });
  }
  res.json({ ok: true });
});

app.listen(9095, () => console.log('Listening on :9095'));

Then point AlertManager at it:

# alertmanager.yml
receivers:
  - name: alert24
    webhook_configs:
      - url: http://your-adapter-host:9095/alert24
        send_resolved: false

route:
  receiver: alert24
  group_by: [alertname, instance]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h

Option C: Use the Alertmanager webhook directly via a template

If you can proxy the request through a tool that reformats JSON (e.g., webhook binary, n8n, or Zapier), map the AlertManager schema to Alert24's:

AlertManager field Alert24 field
alerts[0].annotations.summary title
alerts[0].annotations.description description
alerts[0].labels.severity severity (map critical/warning/info)
alerts[0].labels.alertname part of alias
alerts[0].labels.* tags

Deduplication

Set alias to a stable key like prometheus-{alertname}-{instance}. Alert24 deduplicates on this field — re-fires increment the occurrence count rather than opening new incidents.

Tips

  • group_wait and group_interval: AlertManager groups related alerts before firing. Keep group_wait short (30s) if you want fast Alert24 incident creation.
  • repeat_interval: Set this high (4h or more) to avoid re-firing the webhook for ongoing alerts. The dedup alias handles it, but minimizing unnecessary calls is cleaner.
  • Silences: Alerts silenced in AlertManager won't reach the webhook, so silenced alerts won't create Alert24 incidents.