Back to blog
Engineering · By Josh Crann · August 21, 2026 · 6 min read

Webhook-Based Alerting: Connecting Prometheus and Grafana Without an Integration Project

The word "integration" suggests something that takes an integration engineer and a sprint of work. For connecting a monitoring tool to a paging tool, that's rarely true. Most monitoring systems already speak webhook natively, and the actual work is usually just pointing them at the right URL with the right payload shape.

Prometheus Alertmanager

Alertmanager already supports webhook receivers as a first-class notification method — there's no plugin to install. A webhook_configs block in Alertmanager's routing configuration, pointed at a paging tool's webhook endpoint, is enough. Firing alerts reach that endpoint as an HTTP POST with a JSON body describing the alert, its labels, and its current state.

The part worth getting right is severity mapping. Alertmanager alerts carry a severity label that's whatever the person writing the alerting rule chose to call it — often critical, warning, or page. It's not standardized beyond convention. On the receiving end, that label needs to map to an actual page priority. Otherwise every Alertmanager alert ends up treated identically, regardless of how the rule author intended it.

Grafana alerting

Grafana's built-in alerting engine (separate from, though often paired with, Prometheus) supports webhook contact points directly in its alerting configuration. A contact point pointed at a paging tool's webhook URL means firing alerts trigger a page, the same way an Alertmanager webhook does. No separate plugin needed — just a contact point pointed at the right place.

One detail worth checking: Grafana's webhook payload shape is its own format, distinct from Alertmanager's. That's true even when Grafana is technically evaluating rules sourced from Prometheus data. A paging tool needs to actually parse Grafana's specific JSON structure, not just any webhook shape. That's what carries through useful detail like the dashboard panel or the metric that triggered the alert.

Does a dropped webhook mean a missed page?

Not if the receiving end is built correctly. A single failed delivery attempt shouldn't be the difference between an alert firing and an on-call engineer never knowing about it. Both Alertmanager and Grafana retry a webhook a limited number of times on a non-2xx response, but that retry window is short, and it assumes the receiving endpoint comes back quickly. A paging tool's webhook endpoint should return a fast 200 as soon as the payload is accepted, then process severity mapping and routing asynchronously. Doing that work inline risks a timeout, and Alertmanager or Grafana reads a timeout as a failure.

It's worth testing this specifically: fire a real alert, kill the paging tool's connection mid-request in a staging setup, and confirm the alert still shows up once the endpoint recovers. Don't just assume the retry logic works as documented.

What a good receiving end does with the payload

Accepting a webhook POST is the easy half. What separates a working integration from a merely connected one is what happens with the payload after it arrives:

  • Mapping severity to priority, so a critical Alertmanager alert and a warning one don't get treated the same.
  • Carrying through the alert's summary and labels into the page itself, so the on-call responder sees what's actually firing without needing to open a separate dashboard first.
  • Resolving alerts automatically when Alertmanager or Grafana sends the corresponding "resolved" webhook, so a page doesn't sit open after the underlying issue has already cleared.
  • Deduplicating repeated fires of the same alert, so a flapping condition doesn't generate a fresh page every few minutes.

Beyond Prometheus and Grafana

The same pattern covers most other monitoring tools too, since outbound webhooks are close to universal at this point. Datadog, CloudWatch alarms routed through SNS, Uptime Kuma, and plenty of other tools all support the same idea: firing an HTTP POST to a URL when a check fails. The payload shape differs in every case, but the integration work follows the same checklist each time:

  • Confirm the webhook fires.
  • Confirm the receiving end parses the fields that matter.
  • Confirm severity maps to priority correctly.
  • Confirm a resolved event clears the page instead of leaving it open.

A paging tool that also exposes a generic JSON webhook format — not just Alertmanager- and Grafana-specific parsing — covers the long tail of tools that don't have a dedicated integration. That includes routing through something like Zapier, Make, or n8n, for a monitoring tool that doesn't support webhooks directly on its own.

PingParrot's webhook receiver

PingParrot accepts webhook payloads from both Alertmanager and Grafana directly, with no custom middleware or translation layer required. It maps severity labels to page priority and carries through the alert summary, so the page itself is useful on its own. Setup is genuinely simple: add a webhook URL to Alertmanager's config or a Grafana contact point, then generate an API key from the PingParrot dashboard. Confirm a test alert fires correctly, and the integration is done.

The broader point extends past Prometheus and Grafana specifically. Any monitoring tool that supports outbound webhooks — which is most of them at this point — can be wired into a paging tool the same way. The barrier most teams imagine, a dedicated integration project, usually doesn't exist. It's a webhook URL and a payload format, most of an afternoon at worst.

Diagram: a page escalates from the on-call engineer, to backup, to the team lead, with a wait timer between each step until someone acknowledges it Page sent to on-call engineer 5 min, no ack Escalates to backup responder 10 min, no ack Escalates to team lead, repeats until acknowledged
A three-step escalation policy: each step waits for acknowledgment before handing off to the next responder.

Related posts

Wire up your first alert in minutes

3 pagers free forever. No sales call, no contract.