Metrics & monitoring

Send Grafana alerts to on-call with CallHeim.

Grafana unified alerting contact point (8+) and legacy. CallHeim maps the payload, collapses repeats within five minutes, and pages whoever is on call for the service it belongs to.

grafanaalso accepts: grafana-alerting

Alertmanager groups

A group is split into one alert per member. An incident that holds several alerts stays open while any of them is still firing.

Grafana alert rules become CallHeim alerts: repeats of the same alert collapse onto one incident, and the service the integration is bound to pages whoever is on call for it. CallHeim includes a payload mapping for Grafana’s webhook format, built and tested against sample payloads.

How the alert reaches on-call

  1. Step 1A Grafana alert rule evaluates and its state changes; unified alerting groups it with other firing alerts sharing the same labels, the way Alertmanager does.
  2. Step 2Grafana POSTs the group as one JSON body to your CallHeim ingest URL from its webhook contact point.
  3. Step 3CallHeim reads the first alert in the payload and maps its severity label (or, on a legacy pre-8 payload, its state).
  4. Step 4Repeats of that alert (by its own Grafana fingerprint) within five minutes collapse onto one incident.
  5. Step 5The integration's bound service selects an escalation policy, which pages the on-call tier.

Setting it up

  1. 01

    Add a Webhook contact point in Alerting > Contact points.

    Create the Grafana integration in CallHeim first to get the exact ingest URL.

  2. 02

    Paste the ingest URL into the URL field.

    Grafana stores and displays this URL in plain text when the contact point is read back — treat it the same way you would any other credential.

  3. 03

    Leave the HTTP method on POST and the payload on the default JSON body, unless you need custom fields.

  4. 04

    Attach a notification policy to the contact point.

    Match it to the alert rules you want paged.

Example payloadJSON
{
  "status": "firing",
  "title": "[FIRING:1] DiskSpaceLow",
  "message": "Disk usage is 92%",
  "commonLabels": { "alertname": "DiskSpaceLow", "severity": "warning" },
  "alerts": [
    {
      "status": "firing",
      "labels": { "alertname": "DiskSpaceLow", "severity": "warning", "instance": "db-1" },
      "annotations": { "summary": "Disk space low on db-1", "description": "Only 8% free" },
      "fingerprint": "ggg111"
    }
  ]
}
Example shape written by us, matching Grafana's documented unified-alerting webhook payload; check Grafana's own documentation for the current schema.

What CallHeim reads from the payload

Payload fields and what each one maps to on the incident
Payload fieldMaps toNote
alerts[0].annotations.summary / top-level title / labels.alertnameincident titleUnified alerting (Grafana 8+).
labels.severityseverityRead as a general severity word, not a fixed enum — an unrecognised value defaults to P3.
annotations.description / top-level message / valueStringincident body
alerts[0].fingerprintidentity signalFalls back to the alert name with no fingerprint.
ruleName / state (legacy, pre-8)title / severityalerting→P2, no_data→P3, ok or paused→P4.

How CallHeim processes it

Routing

Each alert source is bound to a service, and the service’s escalation policy (or its team’s) sets who is paged.

Deduplication

Repeats of the same alert collapse onto one incident while they keep arriving within five minutes of each other. A repeat that arrives after a longer quiet gap opens a new incident. The fingerprint is Grafana's own per-alert fingerprint when present, else the alert name (or, on the legacy payload, the rule id).

Recovery

Grafana's unified alerting sends the same Alertmanager-shaped group envelope, and CallHeim reads each alert's own status in it. An incident that holds several alerts stays open while any of them is still firing. If an incident is still open after Grafana has reported every alert resolved, resolve it by hand.

Troubleshooting

Common problems and how to fix them
ProblemFix
A resolved alert stays open.Check whether it shares a notification policy grouping with an alert that is still firing — see Recovery above.
The wrong alert in a group is what gets titled and paged.CallHeim reads the first alert entry in the payload, not the highest-severity one — group rules more narrowly if that matters for a given alert set.
HTTP 400 on send.A custom payload template on the contact point produced invalid JSON — validate it in Grafana's template preview before saving.
No alerts arrive.Confirm the notification policy actually routes to this contact point; an unmatched alert falls through to the default policy.
HTTP 401 once you enabled signing.Grafana's custom header on a webhook contact point is a fixed value, not a per-request signature — it can't satisfy CallHeim's HMAC check. Leave signing off for this source unless you add a proxy in front that can compute and add the header per request.

Security

CallHeim verifies an HMAC-SHA256 signature on each source’s requests once you enable signing on that integration (the sending tool must be able to sign). Grafana's webhook contact point can send a custom header, but only a static value — never a valid per-request HMAC-SHA256 signature of a changing body. Leave CallHeim's signing off for a direct Grafana webhook and rely on the ingest URL itself as the credential, unless you add a signing proxy in front that can compute the header per request.

Vendor documentation checked

The thresholds it passes through

Dedup window
300s
Flap threshold
4 transitions / 600s
Title correlation
similarity ≥ 0.6, same source and service
Group window default
600s

All defaults are published. You can turn title correlation off or change its threshold, and set the window on your own noise rules; the dedup window and the flap settings are fixed. How alerts are processed →

CallHeim

Point Grafana at CallHeim and see what it does with your alerts.

Explore the platform, connect one source, and send yourself a test page by e-mail (early access).

Early access · every workspace starts with a 14-day trial for up to 5 seats, no card required