Configure webhook notifications
Use the webhook integration in contact points to send alert notifications to your webhook.
The webhook integration is a flexible way to integrate alerts into your system. When a notification is triggered, it sends a JSON request with alert details and additional data to the webhook endpoint.
Configure webhook for a contact point
To create a contact point with webhook integration, complete the following steps.
- Navigate to Alerts & IRM -> Alerting -> Contact points.
- Click + Add contact point.
- Enter a name for the contact point.
- From the Integration list, select Webhook.
- In the URL field, copy in your Webhook URL.
- (Optional) Configure additional settings.
- Click Save contact point.
For more details on contact points, including how to test them and enable notifications, refer to Configure contact points.
Webhook settings
Optional settings
Note
You can configure either HTTP Basic Authentication or the Authorization request header, but not both.
HMAC signature
You can secure your webhook notifications using HMAC signatures to verify the authenticity and integrity of the requests. When enabled, Grafana signs the webhook payload with a shared secret using HMAC-SHA256.
When HMAC signing is configured, Grafana generates a signature using HMAC-SHA256 with your secret key. If a timestamp header is specified, a Unix timestamp is included in the signature calculation. The signature is calculated as:
HMAC(timestamp + ":" + body)The timestamp is sent in the specified header. If no timestamp header is specified, the signature is calculated just from the request body. The signature is sent as a hex-encoded string in the specified signature header.
Validate a request
To validate incoming webhook requests from Grafana, follow these steps:
- Extract the signature from the header (default is
X-Grafana-Alerting-Signature). - If you configured a timestamp header, extract the timestamp value and verify it’s recent to prevent replay attacks.
- Calculate the expected signature:
- Create an HMAC-SHA256 hash using your shared secret
- If using timestamps, include the timestamp followed by a colon (
:) before the request body - Hash the raw request body
- Convert the result to a hexadecimal string
- Compare the calculated signature with the one in the request header.
Optional settings using templates
Use the following settings to include custom data within the JSON payload. Both options support using notification templates.
Optional notification settings
Default JSON payload
The following example shows the payload of a webhook notification containing information about two firing alerts:
{
"receiver": "My Super Webhook",
"status": "firing",
"orgId": 1,
"alerts": [
{
"status": "firing",
"labels": {
"alertname": "High memory usage",
"team": "blue",
"zone": "us-1"
},
"annotations": {
"description": "The system has high memory usage",
"runbook_url": "https://myrunbook.com/runbook/1234",
"summary": "This alert was triggered for zone us-1"
},
"startsAt": "2021-10-12T09:51:03.157076+02:00",
"endsAt": "0001-01-01T00:00:00Z",
"generatorURL": "https://play.grafana.org/alerting/1afz29v7z/edit",
"fingerprint": "c6eadffa33fcdf37",
"silenceURL": "https://play.grafana.org/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DT2%2Cteam%3Dblue%2Czone%3Dus-1",
"dashboardURL": "",
"panelURL": "",
"values": {
"B": 44.23943737541908,
"C": 1
}
},
{
"status": "firing",
"labels": {
"alertname": "High CPU usage",
"team": "blue",
"zone": "eu-1"
},
"annotations": {
"description": "The system has high CPU usage",
"runbook_url": "https://myrunbook.com/runbook/1234",
"summary": "This alert was triggered for zone eu-1"
},
"startsAt": "2021-10-12T09:56:03.157076+02:00",
"endsAt": "0001-01-01T00:00:00Z",
"generatorURL": "https://play.grafana.org/alerting/d1rdpdv7k/edit",
"fingerprint": "bc97ff14869b13e3",
"silenceURL": "https://play.grafana.org/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DT1%2Cteam%3Dblue%2Czone%3Deu-1",
"dashboardURL": "",
"panelURL": "",
"values": {
"B": 44.23943737541908,
"C": 1
}
}
],
"groupLabels": {},
"commonLabels": {
"team": "blue"
},
"commonAnnotations": {},
"externalURL": "https://play.grafana.org/",
"version": "1",
"groupKey": "{}:{}",
"truncatedAlerts": 0,
"title": "[FIRING:2] (blue)",
"state": "alerting",
"message": "**Firing**\n\nLabels:\n - alertname = T2\n - team = blue\n - zone = us-1\nAnnotations:\n - description = This is the alert rule checking the second system\n - runbook_url = https://myrunbook.com\n - summary = This is my summary\nSource: https://play.grafana.org/alerting/1afz29v7z/edit\nSilence: https://play.grafana.org/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DT2%2Cteam%3Dblue%2Czone%3Dus-1\n\nLabels:\n - alertname = T1\n - team = blue\n - zone = eu-1\nAnnotations:\nSource: https://play.grafana.org/alerting/d1rdpdv7k/edit\nSilence: https://play.grafana.org/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DT1%2Cteam%3Dblue%2Czone%3Deu-1\n"
}Body
The JSON payload of webhook notifications includes the following key-value pairs:
The following key-value pairs are also included in the JSON payload and can be configured in the webhook settings using notification templates.
Alert
The Alert object represents an alert included in the notification group, as provided by the alerts field.
Custom Payload
The Custom Payload option allows you to completely customize the webhook payload using
templates. This gives you full control over the structure and content of the webhook request.
For detailed information about how to create and manage notification templates, refer to notification templates.
Note
- When using Custom Payload, the
TitleandMessagefields are ignored as the entire payload structure is determined by your template.- Custom Payload is not yet generally available in Grafana Cloud.
Example of a custom payload template that includes variables:
{
"alert_name": "{{ .CommonLabels.alertname }}",
"status": "{{ .Status }}",
"environment": "{{ .Vars.environment }}",
"custom_field": "{{ .Vars.custom_field }}"
}JSON Template Functions
When creating custom payloads, several template functions are available to help generate valid JSON structures. These include functions for creating dictionaries (coll.Dict), arrays (coll.Slice, coll.Append), and converting between JSON strings and objects (data.ToJSON, data.JSON).
For detailed information about these and other template functions, refer to notification template functions.
Example using JSON helper functions:
{- /* Generates a pretty-printed JSON payload with alert group info and individual alerts metadata. */ -}}
{{ define "webhook.custom.payload" -}}
{{ coll.Dict
"receiver" .Receiver
"status" .Status
"alerts" (tmpl.Exec "webhook.custom.simple_alerts" .Alerts | data.JSON)
"groupLabels" .GroupLabels
"commonLabels" .CommonLabels
"commonAnnotations" .CommonAnnotations
"externalURL" .ExternalURL
"version" "1"
"orgId" (index .Alerts 0).OrgID
"truncatedAlerts" .TruncatedAlerts
"groupKey" .GroupKey
"state" (tmpl.Inline "{{ if eq .Status \"resolved\" }}ok{{ else }}alerting{{ end }}" . )
"allVariables" .Vars
"title" (tmpl.Exec "default.title" . )
"message" (tmpl.Exec "default.message" . )
| data.ToJSONPretty " "}}
{{- end }}
{{- /* Embed json templates in other json templates. */ -}}
{{ define "webhook.custom.simple_alerts" -}}
{{- $alerts := coll.Slice -}}
{{- range . -}}
{{ $alerts = coll.Append (coll.Dict
"status" .Status
"labels" .Labels
"startsAt" .StartsAt
"endsAt" .EndsAt
) $alerts}}
{{- end -}}
{{- $alerts | data.ToJSON -}}
{{- end }}


