Introduction
Opsgenie, Atlassian's incident management solution, excels in complex DevOps environments where alerts must intelligently escalate to the right people at the right time. In 2026, with the rise of hybrid clouds and AI for anomaly detection, mastering its API is essential for automating workflows beyond the UI. This expert tutorial guides you step-by-step to programmatically configure teams, alert policies, on-call rotations, escalations, and automation rules. Imagine: a Datadog alert triggers a Slack notification, alerts the on-call team, and auto-resolves if the service recovers. Each step includes complete, tested curl code ready to use. By the end, you'll bookmark this guide for your IaC deployments. Get ready to level up from user to Opsgenie architect.
Prerequisites
- Opsgenie Enterprise account (API v2 enabled)
curlandjqinstalled (for JSON parsing)- Environment variable
OPSGENIE_API_TOKENwith admin permissions - Advanced knowledge of REST APIs and JSON
- Monitoring tools (e.g., Datadog) for testing
Generate and Test the API Token
#!/bin/bash
export OPSGENIE_API_TOKEN="votre_token_ici"
curl -X GET "https://api.opsgenie.com/v2/me" \
-H "Authorization: GenieKey $OPSGENIE_API_TOKEN" \
| jq '.data'This script tests the API token by fetching the user profile. Replace votre_token_ici with an admin token generated in Opsgenie > Settings > API Key Management. Use jq to format the JSON response. Pitfall: an expired token returns 401; check scopes (Read+Write required).
Step 1: Create a Dedicated Team
Opsgenie teams group users, schedules, and integrations. Here, we'll programmatically create a 'DevOps Critical' team to isolate high-priority incidents, avoiding pollution of general feeds.
Create the Team via API
#!/bin/bash
curl -X POST "https://api.opsgenie.com/v2/teams" \
-H "Authorization: GenieKey $OPSGENIE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "DevOps Critical", "description": "Équipe pour incidents critiques 2026", "isDefault": false}' \
| jq '.data.id'This curl creates a team with a name and description. Capture the returned ID (via jq) for later steps. Analogy: like a Kubernetes namespace for scoping. Pitfall: name must be unique, or you'll get 409 Conflict; test with --fail for CI/CD scripts.
Step 2: Add Members and Integrations
Analogy: A team without members is like a server without users. Let's add a user and a Slack integration for alert routing.
Add Member to the Team
#!/bin/bash
TEAM_ID="$(curl -s -X POST "https://api.opsgenie.com/v2/teams" -H "Authorization: GenieKey $OPSGENIE_API_TOKEN" -H "Content-Type: application/json" -d '{"name": "TestTeam"}' | jq -r '.data.id')"
curl -X POST "https://api.opsgenie.com/v2/teams/$TEAM_ID/members" \
-H "Authorization: GenieKey $OPSGENIE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id": "user_id_ou_email@exemple.com", "role": {"type": "team.admin"}}'Replace user_id_ou_email@exemple.com with an Opsgenie user ID. The 'team.admin' role grants full rights. Chaining: the script reuses the freshly created team ID. Pitfall: users must exist; list them via /v2/users.
Create Slack Integration
{
"name": "Slack Critical Alerts",
"type": "slack",
"responders": [
{
"type": "team",
"id": "TEAM_ID_ICI"
}
],
"filters": {
"type": "match-all"
},
"isDefault": false
}JSON payload for a Slack integration routing to the team. Replace TEAM_ID_ICI. POST via curl to /v2/integrations. Expert advantage: advanced filters by tags/priority. Pitfall: Slack webhook URL required in UI after creation.
Step 3: Define On-Call Rotation
Schedules manage 24/7 on-call duties. For experts, we'll set up a weekly rotation with escalation after 15 minutes.
Create On-Call Schedule
#!/bin/bash
TEAM_ID="votre_team_id"
curl -X POST "https://api.opsgenie.com/v2/schedules" \
-H "Authorization: GenieKey $OPSGENIE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"team": {"id": "'$TEAM_ID'"}, "name": "Rotation DevOps Hebdo", "description": "Garde 24/7 avec escalade", "timezone": "Europe/Paris", "repeatInterval": 604800, "rotations": [{"participants": [{"id": "user1@ex.com", "type": "user"}, {"id": "user2@ex.com", "type": "user"}], "interval": 604800, "startDate": "2026-01-01T00:00:00Z"}]}' \
| jq '.data.id'Creates a schedule with 2 users in a weekly rotation (604800s=1 week). Paris timezone for EU. Escalation via later policies. Pitfall: strict ISO8601 dates; validate JSON with jq ..
Step 4: Alert Policies and Escalation
Policies route and escalate alerts based on tags and priority. Progression: Link to the schedule.
Create Alert Policy
{
"name": "Policy Critical Escalade",
"teams": [{"id": "TEAM_ID"}],
"enabled": true,
"filter": {
"type": "restrict",
"conditions": [
{
"field": "priority",
"operation": "is",
"expectedValue": "P1"
},
{
"field": "tags",
"operation": "contains",
"expectedValue": "critical"
}
],
"conditionMatch": {"type": "all"}
},
"actions": {
"create": {
"requestedHeartbeatDuration": "120s",
"autoCloseAction": {"timeBeforeClose": "120m"}
},
"notify": [{"id": "SCHEDULE_ID", "type": "schedule"}],
"escalate": [{"delay": "15m", "to": "next"}]
}
}Policy for P1 + 'critical' tag: notifies schedule, escalates after 15min, auto-closes after 2h without heartbeat. POST to /v2/alert-policies. Pitfall: conditionMatch: all is logical AND; test with mock alerts.
Trigger Test Alert
#!/bin/bash
curl -X POST "https://api.opsgenie.com/v2/alerts" \
-H "Authorization: GenieKey $OPSGENIE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Test Incident Critical", "alias": "test-001", "description": "Serveur down", "teams": ["TEAM_ID"], "tags": ["critical"], "priority": "P1", "source": "Datadog Mock", "details": {"key": "value"}}' \
| jq '.data.tinyId'Simulates a critical P1 alert, triggering the policy. alias deduplicates. Check UI for escalation. Pitfall: without unique alias, multiple alerts; integrate in prod with monitoring webhooks.
Step 5: Advanced Automations
Automate resolutions and enrichments for pro SREs.
Create Automation Rule
{
"name": "Auto-Resolve Low Prio",
"type": "rule",
"order": 1,
"filter": {
"type": "match-all",
"conditions": [
{
"field": "priority",
"operation": "is",
"expectedValue": "P5"
}
]
},
"actions": [
{
"type": "addTags",
"tags": ["auto-monitored"]
},
{
"type": "closeAlert",
"close": {
"message": "Auto-closed: low impact"
}
}
],
"team": {"id": "TEAM_ID"}
}Rule to auto-tag and close P5 alerts. POST to /v2/rules. Expert: Chain actions (addNote, escalateTo). Pitfall: order determines execution; start at 1.
Best Practices
- IaC only: Version Terraform/HCL scripts for Opsgenie (opsgenie provider).
- Rate limiting: Limit to 5 req/s; use batch for bulk ops.
- Strict RBAC: Tokens by scope (e.g., read-only for monitoring).
- Policy monitoring: Alerts on 'ack timeout >30min'.
- End-to-end tests: CI/CD with mock alerts via API.
Common Errors to Avoid
- Insufficient token scopes: 403 on create → check API Permissions.
- Malformed JSON: 400 without
jqvalidation; use--data-binarycurl. - Schedules without timezone: Wrong UTC hours → always specify.
- Orphaned policies: Link to active teams; archive inactive ones.
Next Steps
Integrate with Terraform: Opsgenie Provider. Advanced DevOps training: Learni Group Courses. API Docs: Opsgenie API v2. GitHub examples: search 'opsgenie-terraform-modules'.