Migrate from Opsgenie to Hyperping

Atlassian shuts Opsgenie down on April 5, 2027. Its APIs, integrations, schedules and heartbeats stop working that day. This guide moves your on-call setup, the checks that fed Opsgenie, and your heartbeats into Hyperping, with a parallel run before you switch.

Concept mapping

Opsgenie routes alerts that other tools send it. Hyperping runs the checks itself and covers monitoring, on-call and status pages in one product. Use this table to translate your current setup.

OpsgenieHyperping
Integrations from monitoring toolsNative monitors and browser checks
TeamsTeam members in a project
On-call schedules and rotationsOn-call schedules
Escalation policies and routing rulesEscalation policies, attached to monitors
HeartbeatsHealthchecks, with different alert routing (see Heartbeats)
AlertsOutages with acknowledgements, plus status page incidents

Migration steps

  1. Export your configuration while the API still answers

    Opsgenie's dashboard doesn't export schedules, escalations or heartbeats. Pull them as JSON through the REST API with an API key from Settings → API key management:

    # EU accounts: OPSGENIE_API=https://api.eu.opsgenie.com
    OPSGENIE_API="${OPSGENIE_API:-https://api.opsgenie.com}"
    
    for resource in teams schedules escalations heartbeats; do
      curl -fsS "${OPSGENIE_API}/v2/${resource}" \
        -H "Authorization: GenieKey ${OPSGENIE_API_KEY}" > "${resource}.json"
    done

    Keep these files even if you migrate later: after April 5, 2027 there is nothing left to export. Alert history exports as CSV from the alert list.

  2. Create monitors for what Opsgenie was receiving

    For each integration that sends alerts into Opsgenie, note what the source checks: a website, an API, a port, a certificate. Recreate those checks as Hyperping monitors so detection and paging live in the same tool. For fewer than 20 checks, the dashboard is usually fastest; for more, use the API or the Terraform provider:

    curl -X POST https://api.hyperping.io/v1/monitors \
      -H "Authorization: Bearer ${API_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Website",
        "url": "https://acme.com",
        "protocol": "http",
        "check_frequency": 30,
        "regions": ["paris", "frankfurt", "amsterdam", "london"]
      }'
  3. Rebuild schedules and escalation policies

    Recreate each rotation from schedules.json as an on-call schedule, then build escalation policies from escalations.json that page through them in the same order. On-call and escalation start on the Essentials plan.

    Connect your notification channels: push, SMS, phone call, Slack, Microsoft Teams, email and more.

  4. Recreate your heartbeats as healthchecks

    Each heartbeat becomes a healthcheck, and its ping moves to a new URL in your jobs. Read Heartbeats below first: the alert routing is not the same.

  5. Run both tools in parallel

    Send Hyperping alerts into Opsgenie with the Opsgenie integration so the on-call experience stays familiar during the overlap. Compare both sides after each alert: a difference points to a missing monitor or an escalation step to tune.

  6. Cut over before April 5, 2027

    Disconnect the Opsgenie integration in Hyperping, delete the Opsgenie pings from your jobs, and publish your Hyperping status page if you need one.

Heartbeats

An Opsgenie heartbeat expects a ping every N minutes, hours or days and opens an alert when the ping stops. A Hyperping healthcheck does the same job: your job calls its URL on every run, and a missed ping opens an outage. The schedule carries over one to one. The routing doesn't.

Read your Opsgenie heartbeats

The Heartbeat API lists every heartbeat with its interval. Heartbeats exist on Opsgenie's Standard and Enterprise plans; EU accounts use https://api.eu.opsgenie.com.

curl -fsS "https://api.opsgenie.com/v2/heartbeats" \
  -H "Authorization: GenieKey ${OPSGENIE_API_KEY}"
Response200 OK
{
  "data": {
    "heartbeats": [
      {
        "name": "nightly-backup",
        "description": "Postgres dump to S3",
        "interval": 1,
        "intervalUnit": "days",
        "enabled": true,
        "expired": false,
        "ownerTeam": { "id": "8e3f5c2a", "name": "Platform" },
        "alertMessage": "nightly-backup is expired",
        "alertTags": ["backup"],
        "alertPriority": "P2"
      }
    ]
  },
  "took": 0.05,
  "requestId": "9ae63dd7-ed00-4c81-86f0-c4ffd33142c9"
}

If the list call fails on your account, write down the names from Settings → Heartbeats and read each one with GET /v2/heartbeats/{name}, which returns the same fields.

Field mapping

Opsgenie heartbeatHyperping healthcheck
namename
intervalperiod_value
intervalUnit (minutes, hours, days)period_type, same values
No equivalentgrace_period_value and grace_period_type, required
enabled: falseLeave it out, or create it once the job runs again
ownerTeamEvery project member and channel gets the alert
alertMessage, alertPriority, alertTags, descriptionNo equivalent: the alert reads name missed its scheduled ping

Opsgenie alerts as soon as the interval passes without a ping. Hyperping waits for the period plus the grace period, which starts at 1 minute. If your Opsgenie interval already included slack for slow runs, set the period to the job's real schedule and move that slack into the grace period, so alerts arrive at the same time as today.

For a job that runs on a crontab schedule, cron mode is more precise than an interval: give the healthcheck the job's own expression and timezone, and runs that are not scheduled, such as weekends, never alert. See Healthchecks.

Recreate them with the API or Terraform

This script reads your heartbeats from Opsgenie, creates one healthcheck per enabled heartbeat with the Healthchecks API, and writes each name and ping URL to ping-urls.tsv. It needs curl, jq, an Opsgenie API key and a Hyperping API token with write access. Each healthcheck counts as one monitor on your plan.

#!/usr/bin/env bash
# Recreate every enabled Opsgenie heartbeat as a Hyperping healthcheck.
set -euo pipefail

OPSGENIE_API="${OPSGENIE_API:-https://api.opsgenie.com}"  # EU accounts: https://api.eu.opsgenie.com
GRACE_MINUTES="${GRACE_MINUTES:-5}"

# 1. Read the heartbeats from Opsgenie.
curl -fsS "${OPSGENIE_API}/v2/heartbeats" \
  -H "Authorization: GenieKey ${OPSGENIE_API_KEY}" > opsgenie-heartbeats.json

# 2. Disabled heartbeats are skipped: list them so you can decide later.
jq -r '.data.heartbeats[] | select(.enabled | not) | "skipped (disabled): \(.name)"' opsgenie-heartbeats.json

# 3. Create one healthcheck per enabled heartbeat, and keep its ping URL.
jq -c --argjson grace "${GRACE_MINUTES}" '.data.heartbeats[] | select(.enabled) | {
    name: .name,
    period_value: .interval,
    period_type: .intervalUnit,
    grace_period_value: $grace,
    grace_period_type: "minutes"
  }' opsgenie-heartbeats.json |
while read -r body; do
  curl -fsS -X POST https://api.hyperping.io/v2/healthchecks \
    -H "Authorization: Bearer ${HYPERPING_API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d "${body}" |
    jq -r '[.healthcheck.name, .healthcheck.pingUrl] | @tsv'
done > ping-urls.tsv

echo "Created $(wc -l < ping-urls.tsv | tr -d ' ') healthchecks, ping URLs in ping-urls.tsv"
Response for each healthcheck201 Created
{
  "message": "Healthcheck created",
  "healthcheck": {
    "uuid": "tok_8Kq2mXbV7rT1pLw9sZ4yH3dN",
    "publicUuid": "hc_5vR9cQ2nJ8wE4tY7uK1mB6xA",
    "name": "nightly-backup",
    "pingUrl": "https://hc.hyperping.io/tok_8Kq2mXbV7rT1pLw9sZ4yH3dN",
    "period": 1440,
    "periodValue": 1,
    "periodType": "days",
    "gracePeriod": 5,
    "gracePeriodValue": 5,
    "gracePeriodType": "minutes",
    "cron": null,
    "timezone": "UTC"
  }
}

Set GRACE_MINUTES to the longest delay you can tolerate on most jobs, then adjust individual grace periods in the dashboard. Run the script once: running it again creates duplicates.

Replace the ping URL in your jobs

An Opsgenie ping is an authenticated API call. A healthcheck ping is a plain HEAD, GET or POST to its URL, with no key in the job: the URL itself is the secret. Swap one for the other wherever the job pings today, whether it's a crontab, a CI workflow, a script or a lamp heartbeat call.

# Before: Opsgenie heartbeat ping, with an API key in the job
0 2 * * * /usr/local/bin/backup.sh && \
  curl -fsS "https://api.opsgenie.com/v2/heartbeats/nightly-backup/ping" \
    -H "Authorization: GenieKey ${OPSGENIE_API_KEY}"

Keep the &&: the job then pings only when it succeeds, and a failed run is reported as a missed one. Opsgenie also accepted heartbeat pings by email; healthchecks accept HTTP only, so move those senders to a curl call.

What about my Opsgenie alert history?

Alert history stays in Opsgenie and disappears with it. Export what you need as CSV before the shutdown. Hyperping builds its own outage history, response time metrics and reports from the moment your monitors and healthchecks are created.

What you'll gain

  • Detection and paging in one product: the monitor that finds the outage is the same tool that pages the engineer.
  • Healthchecks on every plan: heartbeats needed Opsgenie Standard or Enterprise; healthchecks are included on every Hyperping plan, Free too.
  • Status pages included: healthchecks and monitors can appear on the same status page, with subscribers.
  • Flat pricing: plans are based on monitors with seats included (3 on Essentials, 10 on Pro, 20 on Business).

Migration resources

Next steps