/oncall-irm
Route alerts, run on-call rotations, and drive incidents in Grafana IRM / OnCall — integrations (Alertmanager / Grafana Alerting / generic webhook / PagerDuty), Jinja2 routing + grouping templates, escalation chains (wait → notify schedule → notify team → webhook →
$ npx -y skills add grafana/skills --skill oncall-irm --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/oncall-irm
Context preview
The summary Claude sees to decide when to auto-load this skill.
Route alerts, run on-call rotations, and drive incidents in Grafana IRM / OnCall — integrations (Alertmanager / Grafana Alerting / generic webhook / PagerDuty), Jinja2 routing + grouping templates, escalation chains (wait → notify schedule → notify team → webhook →
SKILL.md
oncall-irm.SKILL.mdname: oncall-irm
license: Apache-2.0
description: Route alerts, run on-call rotations, and drive incidents in Grafana IRM / OnCall — integrations (Alertmanager / Grafana Alerting / generic webhook / PagerDuty), Jinja2 routing + grouping templates, escalation chains (wait → notify schedule → notify team → webhook → auto-resolve), schedules (web + iCal + Terraform `grafana_oncall_schedule`), Slack chatops with Acknowledge/Resolve/Silence, and the P1-P4 incident lifecycle. Use when wiring Alertmanager to OnCall, deciding which team gets paged, building rotations from a Google Calendar / iCal, hooking up Slack notifications, or declaring an incident from an alert — even when the user says "page the platform team on critical alerts", "send Prometheus alerts to Slack", "set up our on-call rota", "escalation policy", or "auto-resolve when the alert clears" without naming OnCall / IRM. Heads up — OnCall OSS is in maintenance mode (archived March 2026); Grafana Cloud users should use IRM.
Grafana OnCall & IRM
> **OnCall docs**: https://grafana.com/docs/oncall/latest/ > **IRM docs**: https://grafana.com/docs/grafana-cloud/alerting-and-irm/
> Grafana OnCall OSS is in maintenance mode (archived March 2026). Cloud users → **IRM**. Concepts (chains, schedules, integrations) are identical.
Prerequisites
- Grafana Cloud stack with IRM/OnCall enabled
- API token (`Authorization: <token>`)
- Slack workspace + admin to install the OnCall app (for ChatOps)
Core concepts
| Concept | Description | |---------|-------------| | **Integration** | Webhook URL accepting alerts; one per source | | **Route** | Jinja2 condition that maps to an escalation chain (first True wins) | | **Escalation Chain** | Wait / notify schedule / notify team / webhook / auto-resolve steps | | **Schedule** | Calendar-based rotation (web / iCal / Terraform) | | **Alert Group** | Related alerts collapsed by a Grouping ID template | | **Notification Policy** | Per-user channels — Slack, mobile push, SMS, phone, email |
Flow: alert → integration → routing template → escalation chain → notifications → ack / resolve.
Common Workflows
1. Wire Alertmanager → IRM and verify routing
# 1. In IRM: New integration → Alertmanager. Copy the webhook URL.
# 2. alertmanager.yml (see references/integrations.md for full block):
receivers:
- name: grafana-oncall
webhook_configs:
- url: https://<stack>.grafana.net/integrations/v1/alertmanager/<id>/
send_resolved: true
max_alerts: 100# 3. Test the routing template BEFORE going live (UI: Integration → Route → "Preview")
# Paste a sample payload (use a real Alertmanager test webhook). Expect:
# Routing result: True
# Escalation chain selected: <expected chain>
# If False — your Jinja expression is wrong; fix and re-preview.
# 4. End-to-end test — fire amtool (or any test webhook) at the URL
amtool alert add foo severity=critical team=platform --alertmanager.url http://localhost:9093
# 5. Verify in IRM → Alert Groups (should appear within ~5s) — confirm:
# - Correct route fired
# - Correct schedule/user notified
# - Slack message appeared in the configured channel
Routing template syntax + Jinja helpers: [`references/templates-schedules.md`](references/templates-schedules.md). Other integrations (Grafana Alerting, generic webhook, Slack): [`references/integrations.md`](references/integrations.md).
2. Build an escalation chain + verify
1. Notify "Primary On-Call" (Important Notifications)
2. Wait 5 min
3. Notify "Primary On-Call" (Default Notifications)
4. Wait 10 min
5. Notify team "Platform"
6. Trigger outgoing webhook (PagerDuty / ticket)
# Verify: create a test alert (UI → Integration → "Send demo alert"),
# then watch the alert-group timeline tick through steps 1 → 6.
# Use IRM → Escalation Chains → "Test" if available, otherwise the demo alert is the canonical check.
3. Create a schedule from iCal + verify "who is on-call right now"
# 1. Create the schedule
curl -X POST https://<stack>.grafana.net/api/v1/schedules/ \
-H "Authorization: <token>" -H "Content-Type: application/json" \
-d '{"name":"Platform On-Call",
"ical_url_primary":"https://calendar.example.com/platform.ics",
"slack":{"channel_id":"C123456ABC","user_group_id":"S123456ABC"}}'
# 2. Verify the schedule was created
curl -s https://<stack>.grafana.net/api/v1/schedules/ \
-H "Authorization: <token>" | jq '.results[] | select(.name=="Platform On-Call")'
# 3. Verify who is on-call right now
curl -s https://<stack>.grafana.net/api/v1/schedules/<schedule_id>/next_shifts/ \
-H "Authorization: <token>" | jq '.results[0]'
# Expect a shift starting now (or recently) with the right user_id.Terraform variant + shift block: [`references/templates-schedules.md`](references/templates-schedules.md).
Best practices
- Keep chains ≤4 levels with a definitive final step (webhook to PagerDuty or auto-resolve)
- Always set `send_resolved: true` in Alertmanager so OnCall auto-resolves
- Use `max_alerts: 100` in Alertmanager webhook config
- Combine Slack + mobile push for delivery reliability
- Assign integrations/schedules to teams for RBAC
Resources
- [OnCall API](https://grafana.com/docs/oncall/latest/oncall-api-reference/)
- [IRM docs](https://grafana.com/docs/grafana-cloud/alerting-and-irm/)
- [Routing template helpers](https://grafana.com/docs/oncall/latest/configure/jinja2-template-functions/)
Read more
name: oncall-irm license: Apache-2.0 description: Route alerts, run on-call rotations, and drive incidents in Grafana IRM / OnCall — integrations (Alertmanager / Grafana Alerting / generic webhook / PagerDuty), Jinja2 routing + grouping templates, escalation chains (wait → notify schedule → notify team → webhook → auto-resolve), schedules (web + iCal + Terraform `grafana_oncall_schedule`), Slack chatops with Acknowledge/Resolve/Silence, and the P1-P4 incident lifecycle. Use when wiring Alertmanager to OnCall, deciding which team gets paged, building rotations from a Google Calendar / iCal, hooking up Slack notifications, or declaring an incident from an alert — even when the user says "page the platform team on critical alerts", "send Prometheus alerts to Slack", "set up our on-call rota", "escalation policy", or "auto-resolve when the alert clears" without naming OnCall / IRM. Heads up — OnCall OSS is in maintenance mode (archived March 2026); Grafana Cloud users should use IRM.
Grafana OnCall & IRM
> **OnCall docs**: https://grafana.com/docs/oncall/latest/ > **IRM docs**: https://grafana.com/docs/grafana-cloud/alerting-and-irm/
> Grafana OnCall OSS is in maintenance mode (archived March 2026). Cloud users → **IRM**. Concepts (chains, schedules, integrations) are identical.
Prerequisites
- Grafana Cloud stack with IRM/OnCall enabled
- API token (`Authorization: <token>`)
- Slack workspace + admin to install the OnCall app (for ChatOps)
Core concepts
| Concept | Description | |---------|-------------| | **Integration** | Webhook URL accepting alerts; one per source | | **Route** | Jinja2 condition that maps to an escalation chain (first True wins) | | **Escalation Chain** | Wait / notify schedule / notify team / webhook / auto-resolve steps | | **Schedule** | Calendar-based rotation (web / iCal / Terraform) | | **Alert Group** | Related alerts collapsed by a Grouping ID template | | **Notification Policy** | Per-user channels — Slack, mobile push, SMS, phone, email |
Flow: alert → integration → routing template → escalation chain → notifications → ack / resolve.
Common Workflows
1. Wire Alertmanager → IRM and verify routing
# 1. In IRM: New integration → Alertmanager. Copy the webhook URL.
# 2. alertmanager.yml (see references/integrations.md for full block):
receivers:
- name: grafana-oncall
webhook_configs:
- url: https://<stack>.grafana.net/integrations/v1/alertmanager/<id>/
send_resolved: true
max_alerts: 100# 3. Test the routing template BEFORE going live (UI: Integration → Route → "Preview") # Paste a sample payload (use a real Alertmanager test webhook). Expect: # Routing result: True # Escalation chain selected: <expected chain> # If False — your Jinja expression is wrong; fix and re-preview. # 4. End-to-end test — fire amtool (or any test webhook) at the URL amtool alert add foo severity=critical team=platform --alertmanager.url http://localhost:9093 # 5. Verify in IRM → Alert Groups (should appear within ~5s) — confirm: # - Correct route fired # - Correct schedule/user notified # - Slack message appeared in the configured channel
Routing template syntax + Jinja helpers: [`references/templates-schedules.md`](references/templates-schedules.md). Other integrations (Grafana Alerting, generic webhook, Slack): [`references/integrations.md`](references/integrations.md).
2. Build an escalation chain + verify
1. Notify "Primary On-Call" (Important Notifications) 2. Wait 5 min 3. Notify "Primary On-Call" (Default Notifications) 4. Wait 10 min 5. Notify team "Platform" 6. Trigger outgoing webhook (PagerDuty / ticket)
# Verify: create a test alert (UI → Integration → "Send demo alert"), # then watch the alert-group timeline tick through steps 1 → 6. # Use IRM → Escalation Chains → "Test" if available, otherwise the demo alert is the canonical check.
3. Create a schedule from iCal + verify "who is on-call right now"
# 1. Create the schedule
curl -X POST https://<stack>.grafana.net/api/v1/schedules/ \
-H "Authorization: <token>" -H "Content-Type: application/json" \
-d '{"name":"Platform On-Call",
"ical_url_primary":"https://calendar.example.com/platform.ics",
"slack":{"channel_id":"C123456ABC","user_group_id":"S123456ABC"}}'
# 2. Verify the schedule was created
curl -s https://<stack>.grafana.net/api/v1/schedules/ \
-H "Authorization: <token>" | jq '.results[] | select(.name=="Platform On-Call")'
# 3. Verify who is on-call right now
curl -s https://<stack>.grafana.net/api/v1/schedules/<schedule_id>/next_shifts/ \
-H "Authorization: <token>" | jq '.results[0]'
# Expect a shift starting now (or recently) with the right user_id.Terraform variant + shift block: [`references/templates-schedules.md`](references/templates-schedules.md).
Best practices
- Keep chains ≤4 levels with a definitive final step (webhook to PagerDuty or auto-resolve)
- Always set `send_resolved: true` in Alertmanager so OnCall auto-resolves
- Use `max_alerts: 100` in Alertmanager webhook config
- Combine Slack + mobile push for delivery reliability
- Assign integrations/schedules to teams for RBAC
Resources
- [OnCall API](https://grafana.com/docs/oncall/latest/oncall-api-reference/)
- [IRM docs](https://grafana.com/docs/grafana-cloud/alerting-and-irm/)
- [Routing template helpers](https://grafana.com/docs/oncall/latest/configure/jinja2-template-functions/)
Public skills for working with Grafana, Prometheus, Loki, Tempo, Pyroscope, k6, and the broader LGTM observability stack. Compatible with Claude Code, Cursor, Codex, and any tool supporting the Agent Skills open standard.
Repo: grafana/skills
Other skills on grafana-skills.
- /admission-control
Use when the user asks to "write a validator", "add validation", "implement admission control", "write a mutating webhook", "add a mutation handler", "validate incoming resources", "implement admission logic", "add admission webhooks", "write ingress validation", or asks how to
Open skill - /app-sdk-concepts
Use when starting any grafana-app-sdk work — scaffolding a Grafana app, initializing a Grafana App Platform app, picking a deployment mode (standalone operator / grafana/apps / frontend-only), wiring app-specific config, or onboarding to the SDK. Covers `grafana-app-sdk` CLI
Open skill - /cue-kind-definition
Author CUE kind definitions for grafana-app-sdk apps - schemas, versioning, field constraints, named type definitions, custom routes, and codegen configuration. Scaffolds kinds via `grafana-app-sdk project kind add`, writes spec/status schemas with type constraints (regex, enum,
Open skill - /reconciler-logic
Implement reconcilers and watchers for grafana-app-sdk apps — write `TypedReconciler[*MyKind]` reconcile functions, apply generation-based skip patterns, do conflict-safe status updates via `resource.UpdateObject`, configure `BasicReconcileOptions` (namespace, label/field
Open skill - /adaptive-metrics
Cut Grafana Cloud Metrics cost by shrinking active-series count with Adaptive Metrics aggregation rules — auto-recommendations from query history, custom exact/regex rules, label-drop config, unused-metric detection, and Alloy remote_write fallback. Use when investigating a high
Open skill - /admin
Manage Grafana Cloud accounts — organizations, stacks, RBAC roles and assignments, SSO/SAML/OAuth/GitHub auth, service accounts for CI/CD, user invites, team membership, and API-driven provisioning. Creates stacks via the Cloud API, mints service-account tokens, applies role
Open skill

