> For the complete documentation index, see [llms.txt](https://docs.ilert.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ilert.com/knowledge-base/getting-started-and-onboarding/opsgenie-to-ilert-migration-guide.md).

# Migrate from Opsgenie to ilert

Move your on-call setup from Opsgenie to ilert — with the ilert CLI and a coding agent, or by hand — and switch your monitoring tools over without a gap in alerting.

Atlassian stopped selling Opsgenie on June 4, 2025, and shuts off access to it on April 5, 2027. This guide moves your configuration to ilert — users, teams, schedules, escalation policies and integrations — and switches your monitoring tools over without a gap in alerting.

Most of Opsgenie maps onto ilert one to one. The few parts that do not are the ones that page the wrong person, or nobody, so read [Differences that change behavior](#differences-that-change-behavior) whichever route you take.

## Choose how to migrate

| Route                            | Fits when                                                                                                    | Start with                                                |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
| **ilert CLI and a coding agent** | You want your configuration read from Opsgenie and rebuilt in ilert for you, once you have approved the plan | [Migrate with the ilert CLI](#migrate-with-the-ilert-cli) |
| **ilert's migration team**       | Your setup is large or unusual, and you want a second pair of eyes on it. The assistance is free             | <support@ilert.com>                                       |
| **By hand**                      | Your setup is small, or you want to rebuild it deliberately                                                  | [Migrate by hand](#migrate-by-hand)                       |

Every route ends the same way: [run both side by side, then switch](#run-both-side-by-side-then-switch).

## Migrate with the ilert CLI

The [ilert CLI](/developer-docs/client-libraries/ilert-cli.md) gives a coding agent — Claude Code, Codex, Cursor or similar — the whole ilert API and a migration playbook for Opsgenie. The agent reads your configuration through the Opsgenie API, maps each object onto its ilert equivalent, and shows you the full plan, built with `--dry-run`, before it creates anything. Destructive commands refuse to run without a person there to confirm them.

Follow [Migrate to ilert](/developer-docs/client-libraries/ilert-cli/migrate-to-ilert.md) for the procedure: installing the CLI, handing the agent your Opsgenie key without pasting it into the conversation, the prompt to start with, and the checks to run before you cut over.

The Opsgenie key needs two access rights and no more. In Opsgenie's **API key management**, create a key with only **Read** and **Configuration Access** selected, and revoke it once the migration is done.

The playbook is a Markdown file that ships with the CLI. Read it to see what the agent will apply:

```bash
ilert skills show migrate-from-opsgenie
```

{% hint style="info" %}
If you also run Atlassian Statuspage, the CLI has a playbook for that too, `migrate-from-statuspageio`. Ask the agent to use both.
{% endhint %}

## How Opsgenie maps to ilert

| Opsgenie                          | ilert                                                                                                                    | Watch for                                                                                                                                       |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Integration                       | [Alert source](/alerting/configure-alerting/alert-sources.md)                                                            | The alert source owns its escalation policy, and gets a new integration key                                                                     |
| Team                              | [Team](/users-and-access-management/teams.md)                                                                            | Carries no routing rules, but an escalation level can target it                                                                                 |
| Team routing rule                 | Routing key, or [event flow](/alerting/configure-alerting/event-flows.md)                                                | See [Routing moves to the alert source](#routing-moves-to-the-alert-source)                                                                     |
| Escalation                        | [Escalation policy](/on-call-management-and-escalations/escalation-policies.md)                                          | See [Escalation timeouts count from a different point](#escalation-timeouts-count-from-a-different-point)                                       |
| Schedule                          | [On-call schedule](/on-call-management-and-escalations/on-call-schedules.md)                                             | One schedule puts one person on call at a time                                                                                                  |
| Rotation                          | Schedule layer, or a schedule of its own                                                                                 | See [Overlapping rotations need a schedule each](#overlapping-rotations-need-a-schedule-each)                                                   |
| Override                          | Override                                                                                                                 | Maps one to one                                                                                                                                 |
| Forwarding rule                   | Overrides on that person's shifts                                                                                        | See [Forwarding rules become overrides](#forwarding-rules-become-overrides)                                                                     |
| Alert                             | Alert                                                                                                                    | Acknowledge is called *accept*, and close is called *resolve*                                                                                   |
| Alias                             | Alert key                                                                                                                | Whether events join one alert also depends on the alert source's [event grouping](/alerting/configure-alerting/alert-sources.md#event-grouping) |
| Priority P1–P5                    | Severity and notification priority                                                                                       | See [Priority becomes two fields](#priority-becomes-two-fields)                                                                                 |
| Incident                          | [Incident](/incidents-and-status-pages/incidents.md) and [status updates](/incidents-and-status-pages/status-updates.md) | See [An Opsgenie incident becomes two things](#an-opsgenie-incident-becomes-two-things)                                                         |
| Incident rule                     | **Update status page** alert action                                                                                      | Automates the status update, not the incident                                                                                                   |
| Alert policy, notification policy | Alert source settings, delayed escalation                                                                                | See [Policies land in several places](#policies-land-in-several-places)                                                                         |
| Notification rule                 | [Notification settings](/alerting/configure-alerting/notification-settings.md)                                           | Per user, as in Opsgenie                                                                                                                        |
| User role                         | [User role](/users-and-access-management/user-roles-and-permissions.md)                                                  | Pick the closest ilert role for each user                                                                                                       |
| Service                           | [Service](/incidents-and-status-pages/services.md)                                                                       | Also attached to alerts and incidents as an affected service                                                                                    |
| Status page                       | [Status page](/incidents-and-status-pages/status-pages.md)                                                               | Maps one to one                                                                                                                                 |
| Heartbeat                         | [Heartbeat monitor](/alerting/heartbeat-monitoring.md)                                                                   | Move each heartbeat together with the job that pings it                                                                                         |
| Maintenance                       | [Maintenance window](/alerting/configure-alerting/maintenance-windows.md)                                                | Maps one to one                                                                                                                                 |
| Incoming call routing             | [Call flow](/call-routing/call-flows.md)                                                                                 | See [Your call routing number changes](#your-call-routing-number-changes)                                                                       |

## Differences that change behavior

### Routing moves to the alert source

In Opsgenie, an integration hands each alert to a team, and the team's routing rules decide which escalation applies. In ilert the alert source owns its escalation policy, and teams have no routing rules. Two features take their place:

* **Routing keys**, when the sending tool can say which path it wants. Give each escalation policy a [routing key](/on-call-management-and-escalations/escalation-policies.md#routing-key-optional). An event that carries a matching key uses that policy instead of the alert source's own; an event with no match falls back to it. Routing keys are available on every plan.
* **Event flows**, for everything else. An [event flow](/alerting/configure-alerting/event-flows.md) sits in front of your alert sources with an integration key of its own, and branches on the event's content or on your support hours before handing the event to an alert source. Event flows are in beta, and need the [Scale plan](https://www.ilert.com/pricing) or higher.

Write your routing rules down and flatten them before you create anything. You usually end up with a handful of alert sources and one event flow, not one alert source per rule.

### Escalation timeouts count from a different point

An Opsgenie escalation rule fires a set number of minutes after the escalation *started*. An ilert escalation timeout is how long *one level* has to accept the alert before the next level is notified. The numbers do not carry over: subtract each level's Opsgenie delay from the next level's.

| Level | Target              | Opsgenie delay | ilert escalation timeout |
| ----- | ------------------- | -------------- | ------------------------ |
| 1     | On-call schedule    | 0 minutes      | 10 minutes               |
| 2     | Team lead           | 10 minutes     | 20 minutes               |
| 3     | Head of engineering | 30 minutes     | —                        |

Copied across unchanged, the first level gets a timeout of `0`: the team lead is notified at the same moment as the person on call, and the head of engineering 20 minutes early.

### Overlapping rotations need a schedule each

Every rotation in an Opsgenie schedule is active at once: where two rotations cover the same hour, two people are on call. An ilert schedule puts exactly one person on call — where its layers overlap, one layer wins (see [Which layer wins](/on-call-management-and-escalations/on-call-schedules/recurring-schedules.md#which-layer-wins)). Fold two overlapping rotations into one ilert schedule and you halve your coverage without any warning.

Give each overlapping rotation its own schedule, and put those schedules on the same escalation level, where everyone is notified at once. How many targets a level can hold depends on your plan.

Rotations meant to take turns rather than add up — follow-the-sun shifts, or a weekend rotation that takes over from the weekday one — belong in one schedule as layers.

### Priority becomes two fields

Opsgenie has one priority, P1 to P5. ilert splits it in two, and both are worth setting:

* **Severity** describes how bad the problem is, from **SEV1 Critical** to **SEV5 Info**. P1 to P5 maps onto it one for one. It changes nobody's notifications.
* **Notification priority** decides how people are notified. **High (with escalation)** uses everyone's high-priority notification rules and escalates through the policy. **Low (no escalation)** uses their low-priority rules and never gets past the first escalation level.

A common split is P1 and P2 to high, and P3 to P5 to low. Check it against how your Opsgenie notification rules treat each priority before you adopt it. Set both on the [alert source](/alerting/configure-alerting/alert-sources.md#priority-severity-and-affected-services), as a default or mapped from the event's own fields, or per event through the Events API.

### An Opsgenie incident becomes two things

An Opsgenie incident has a responder side — the people working on it — and a stakeholder side, the message everyone else reads. ilert keeps them apart:

* The [**incident**](/incidents-and-status-pages/incidents.md) is the coordination record: responders, linked alerts, a timeline and an incident channel. A person declares it, from scratch or from an alert.
* [**Status updates**](/incidents-and-status-pages/status-updates.md) are the messages posted from the incident. They reach your status pages and their subscribers.

Opsgenie incident rules, which open an incident when alerts match a condition, carry over in part. The **Update status page** alert action moves a service's status and publishes a status update when an alert arrives, with nobody watching — see [Automation with alert sources](/incidents-and-status-pages/services.md#automation-with-alert-sources). Declaring the incident stays with a person.

### Policies land in several places

Opsgenie shapes alerts with alert policies and notification policies. In ilert, what each policy did moves to a setting of its own:

| An Opsgenie policy that                | Becomes in ilert                                                                                                                                                                                                                                                                                            |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Deduplicates alerts                    | The alert source's [event grouping](/alerting/configure-alerting/alert-sources.md#event-grouping)                                                                                                                                                                                                           |
| Closes alerts automatically            | The alert source's [auto-resolution](/alerting/configure-alerting/alert-sources.md#auto-resolution)                                                                                                                                                                                                         |
| Delays notifications                   | [Delayed escalation](/on-call-management-and-escalations/escalation-policies.md#delayed-escalation) on the escalation policy — up to 15 minutes, and an alert that resolves in that time notifies nobody                                                                                                    |
| Suppresses notifications               | The alert source's [event filter](/alerting/configure-alerting/alert-sources.md#event-filter) (Scale plan or higher), which drops matching events before they become alerts and keeps them in the alert source logs. To keep the alert but notify quietly, give it **Low (no escalation)** priority instead |
| Changes an alert's message or priority | The alert source's [alert template](/alerting/configure-alerting/alert-sources.md#alert-template) (Pro plan or higher) and its [priority mapping](/alerting/configure-alerting/alert-sources.md#dynamic-priority-mapping)                                                                                   |

Opsgenie alert policies can be global as well as per team. If you migrate team by team, remember the global ones. Plans differ in which of these settings they include — see [What your plan includes](/alerting/configure-alerting/alert-sources.md#what-your-plan-includes).

### Forwarding rules become overrides

An Opsgenie forwarding rule sends everything meant for one person to someone else for a while. ilert has no single object for that. Put the stand-in on the person's shifts as an override instead — with **Override my shifts** on [My on-call shifts](/on-call-management-and-escalations/on-call-schedules/my-on-call-shifts.md), or with a [coverage request](/on-call-management-and-escalations/on-call-coverage-requests.md) the stand-in accepts.

An override covers shifts on schedules only. An escalation level that names the person directly still notifies them.

### Your call routing number changes

Opsgenie's incoming call routing becomes an ilert [call flow](/call-routing/call-flows.md): menus, voicemail, and a call that rings whoever is on call. Two things do not carry over:

* **The phone number.** Numbers cannot be ported into ilert, so your call flows get a [new number from ilert](/call-routing/getting-started-with-call-routing.md#get-a-phone-number). Everyone who has the old number — runbooks, contracts, customers — needs the new one, unless your carrier forwards the old number to it.
* **Routing to an escalation policy.** A **Route call** node rings users, schedules or teams. Point it at the schedule behind the policy, and rebuild the fallback with the node's **No one available** branch.

Give call routing its own switch-over date. It is the one part of the migration with people, not machines, dialing in.

## What does not migrate

* **History.** Past alerts and incidents stay in Opsgenie. Save what you need before April 5, 2027, when Atlassian shuts off access.
* **Integration keys.** Every alert source has a new key, so every tool that sends alerts to Opsgenie has to be re-pointed.
* **Your call routing number.** See [Your call routing number changes](#your-call-routing-number-changes).

## Migrate by hand

Create objects in the order they depend on each other, so nothing points at an object that does not exist yet:

1. **Users** and their [roles](/users-and-access-management/user-roles-and-permissions.md), then each user's [notification settings](/alerting/configure-alerting/notification-settings.md).
2. [**Teams**](/users-and-access-management/teams.md), with their members.
3. [**On-call schedules**](/on-call-management-and-escalations/on-call-schedules.md), with their layers and overrides. Create them before the escalation policies that use them, and check that each has someone on call: an escalation level whose schedule is empty is skipped at once, without waiting for its timeout, and a policy with nobody on call anywhere notifies no one.
4. [**Escalation policies**](/on-call-management-and-escalations/escalation-policies.md), with timeouts converted as [shown above](#escalation-timeouts-count-from-a-different-point).
5. [**Alert sources**](/alerting/configure-alerting/alert-sources.md), one for each set of alert source settings you need — not one per routing rule. Where ilert has an [integration](/integrations/inbound-integrations.md) for the tool, use it rather than a generic API alert source: it reads the tool's payload, including the alert key that folds repeat events into one alert.
6. [**Support hours**](/alerting/configure-alerting/support-hours.md), and [**event flows**](/alerting/configure-alerting/event-flows.md) where they replace routing rules.
7. **Alert actions**, for [outbound integrations](/integrations/outbound-integrations.md) and automation such as **Update status page**.
8. [**Services**](/incidents-and-status-pages/services.md), then [**status pages**](/incidents-and-status-pages/status-pages.md).
9. [**Maintenance windows**](/alerting/configure-alerting/maintenance-windows.md) and [**heartbeat monitors**](/alerting/heartbeat-monitoring.md).
10. [**Call flows**](/call-routing/call-flows.md), which route to the schedules and teams above.

Keep a list of which Opsgenie object became which ilert object. ilert keeps no reference to the original, and you need the list when you re-point your tools.

{% hint style="info" %}
If your people sign in through SAML single sign-on, [auto-provisioning](/users-and-access-management/single-sign-on/auto-provisioning-users-and-teams.md) can create each user — with their role, team and phone number — the first time they sign in.
{% endhint %}

## Run both side by side, then switch

Integration keys are new, so every tool that sends alerts to Opsgenie has to be pointed at ilert. That is the step where alerts get lost, so take it one tool at a time.

### Forward Opsgenie's alerts first

The [Opsgenie integration](/integrations/inbound-integrations/opsgenie.md) forwards your Opsgenie alerts to an ilert alert source, and acknowledging or closing an alert in Opsgenie accepts or resolves it in ilert. Set it up before you re-point anything: ilert then sees your alerts from the first day, and you can move your tools over one at a time.

While both systems are live, both notify. Until you are ready for ilert to page your on-call team, give that alert source an escalation policy that notifies only the people running the migration.

### Re-point each tool

For each tool that sends alerts to Opsgenie:

1. Copy the integration URL or key of its new alert source — or of the event flow, where one handles the tool's traffic.
2. Replace the Opsgenie endpoint in the tool with it.
3. Trigger a test alert in the tool, and confirm it reaches the right person in ilert.
4. Remove the tool's integration in Opsgenie.

### Rewrite scripts that call the Opsgenie Alert API

A script that calls the Opsgenie Alert API needs new code, not just a new URL. ilert creates, accepts and resolves alerts through one endpoint, the [Events API](/developer-docs/api-samples/creating-alerts-through-events.md), where an `eventType` field selects the action and the integration key travels in the body instead of a header.

| Opsgenie Alert API                    | ilert Events API                                        |
| ------------------------------------- | ------------------------------------------------------- |
| `POST /v2/alerts`                     | `"eventType": "ALERT"`                                  |
| `POST /v2/alerts/{id}/acknowledge`    | `"eventType": "ACCEPT"`                                 |
| `POST /v2/alerts/{id}/close`          | `"eventType": "RESOLVE"`                                |
| API key in the `Authorization` header | `integrationKey` in the body                            |
| `alias`                               | `alertKey`                                              |
| `message`                             | `summary`                                               |
| `description`                         | `details`                                               |
| `details`, a map of key/value pairs   | `customDetails`                                         |
| `tags`, a list                        | `labels`, a map of key/value pairs                      |
| `priority`, `P1` to `P5`              | `severity`, `1` to `5`, and `priority`, `HIGH` or `LOW` |

Watch `details`: it means something different on each side. Opsgenie's is a map of key/value pairs, ilert's is free text, so copying field names across swaps the two.

ilert accepts and resolves an alert by its alert key, not by an alert ID. If your script closed alerts by their Opsgenie ID, give each alert an `alertKey` when you create it:

```bash
curl -X POST https://api.ilert.com/api/events \
  -H "Content-Type: application/json" \
  -d '{
    "integrationKey": "YOUR_INTEGRATION_KEY",
    "eventType": "ALERT",
    "alertKey": "db-primary-disk",
    "summary": "Disk usage above 90% on db-primary",
    "details": "8 GB free of 100 GB",
    "severity": 2,
    "customDetails": {"host": "db-primary", "region": "eu-central-1"}
  }'
```

and send the same key to resolve it:

```bash
curl -X POST https://api.ilert.com/api/events \
  -H "Content-Type: application/json" \
  -d '{
    "integrationKey": "YOUR_INTEGRATION_KEY",
    "eventType": "RESOLVE",
    "alertKey": "db-primary-disk",
    "summary": "Disk usage back below 80% on db-primary"
  }'
```

A request ilert accepts returns `202 Accepted`. `summary` is required on every event, including `RESOLVE`.

### Switch Opsgenie off

When every tool sends to ilert and has delivered a test alert:

1. Check that the same people are on call in both systems — now, and after the next handover.
2. Turn off the Webhook integration in Opsgenie, and delete the alert source that received its alerts in ilert.
3. Save the Opsgenie history you want to keep, before April 5, 2027.

## Get help

ilert's migration assistance is free, including a review of your configuration and help with the setup. Email <support@ilert.com>.

* [Opsgenie migration FAQ](/knowledge-base/getting-started-and-onboarding/opsgenie-migration-faq.md)
* [ilert CLI](/developer-docs/client-libraries/ilert-cli.md)
* [Opsgenie integration](/integrations/inbound-integrations/opsgenie.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ilert.com/knowledge-base/getting-started-and-onboarding/opsgenie-to-ilert-migration-guide.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
