---
title: Manage self-service promotions using the API
description: You can find background information on self-service promotions in PingOne Advanced Identity Cloud in Introduction to self-service promotions.
component: pingoneaic
page_id: pingoneaic:tenants:self-service-promotions-api
canonical_url: https://docs.pingidentity.com/pingoneaic/tenants/self-service-promotions-api.html
keywords: ["Availability", "Deployment", "ESV", "Migration", "Promotion", "REST API", "Tenants", "Troubleshooting"]
section_ids:
  lower-and-upper-environments-api: Lower and upper environments
  reports: Reports
  promotions-api-endpoints: Promotions API endpoints
  monitor-the-progress-of-asynchronous-processes: Monitor progress when you lock or unlock environments, start a promotion, or start a rollback
  check-the-lock-state: Check the lock state
  check-the-promotion-status: Check the promotion status
  check-the-rollback-status: Check the rollback status
  lock-environments: Lock environments
  check-that-the-environments-are-unlocked: "Task 1: Check that the environments are unlocked"
  lock-the-environments: "Task 2: Lock the environments"
  run-a-promotion: Run a promotion
  check-how-a-promotion-will-affect-deferred-release-status: "Task 1: (Optional) Check how a promotion will affect deferred release status"
  lock-the-environments-before-promotion: "Task 2: Lock the environments"
  check-that-a-promotion-is-not-already-running-before-promotion: "Task 3: Check that a promotion isn't already running"
  run-a-dry-run-promotion: "Task 4: Run a dry-run promotion"
  run-the-promotion: "Task 5: Run the promotion"
  view-the-promotion-report: "Task 6: View the promotion report"
  unlock-the-environments-after-promotion: "Task 7: Unlock the environments"
  run-a-rollback: Run a rollback
  check-how-a-rollback-will-impact-a-release-upgrade: "Task 1: (Optional) Check how a rollback will impact a release upgrade"
  lock-the-environments-before-rollback: "Task 2: Lock the environments"
  check-that-a-promotion-is-not-already-running-before-rollback: "Task 3: Check that a promotion isn't already running"
  get-a-provisional-rollback-report: "Task 4: Get a provisional rollback report"
  run-the-rollback: "Task 5: Run the rollback"
  unlock-the-environments-after-rollback: "Task 6: Unlock the environments"
  unlock-environments: Unlock environments
  view-previous-promotion-or-rollback-reports: View previous promotion or rollback reports
  resolve-environment-errors-that-are-preventing-a-promotion-or-a-rollback: Resolve environment errors that are preventing a promotion or a rollback
  revert-configuration-in-your-development-environment-api: Revert configuration in your development environment
---

# Manage self-service promotions using the API

You can find background information on self-service promotions in PingOne Advanced Identity Cloud in [Introduction to self-service promotions](self-service-promotions.html).

## Lower and upper environments

Before you run any promotions API requests, you must know which tenant environment is the lower environment and which is the upper environment. Learn more in [Lower and upper environments](self-service-promotions.html#lower-and-upper-environments).

The API uses a pull model to promote configuration, so most API commands must be run against the *upper* environment.

## Reports

| Report type                 | Description                                                                                                                                                              |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Dry-run promotion report    | A promotion report generated after a dry-run promotion. It provides a full list of configuration changes that will be promoted between a lower and an upper environment. |
| Promotion report            | A promotion report generated after a promotion. It provides a full list of configuration changes that were promoted between a lower and an upper environment.            |
| Provisional rollback report | A rollback report generated before rollback. It provides a full list of configuration changes that will be reverted from the upper environment.                          |
| Rollback report             | A rollback report generated after a rollback. It provides a full list of configuration changes that were reverted from the upper environment.                            |

## Promotions API endpoints

Advanced Identity Cloud provides these API endpoints for promotions:

* [Lock](https://docs.pingidentity.com/pingoneaic/_attachments/api/#tag/Promotion/operation/lock) API endpoint

* [Info](https://docs.pingidentity.com/pingoneaic/_attachments/api/#tag/Promotion/operation/get-info) API endpoint

* [Promote](https://docs.pingidentity.com/pingoneaic/_attachments/api/#tag/Promotion/operation/start) API endpoint

* [Rollback](https://docs.pingidentity.com/pingoneaic/_attachments/api/#tag/Promotion/operation/rollback) API endpoint

* [Report](https://docs.pingidentity.com/pingoneaic/_attachments/api/#tag/Promotion/operation/getReport) and [Reports](https://docs.pingidentity.com/pingoneaic/_attachments/api/#tag/Promotion/operation/getReportList) API endpoints

To authenticate to promotions API endpoints, use an [access token](../developer-docs/authenticate-to-rest-api-with-access-token.html) created with the `fr:idc:promotion:*` scope.

The following diagram summarizes how promotions API commands are used to run a promotion. Learn more in [Run a promotion](#run-a-promotion).

![self service promotions api states](_images/self-service-promotions-api-states.png)

## Monitor progress when you lock or unlock environments, start a promotion, or start a rollback

When you use API commands to [lock environments](#lock-environments), [unlock environments](#unlock-environments), [start a promotion](#run-a-promotion), or [start a rollback](#run-a-rollback), you trigger asynchronous processes in your environments. You can monitor the progress of these asynchronous processes by checking their state or status until they have completed. You do this by running further API commands and analyzing their responses.

### Check the lock state

To check the lock state during the [lock environments](#lock-environments) or [unlock environments](#unlock-environments) processes, use the `/environment/promotion/lock/state` endpoint:

```bash
curl \
--request GET 'https://<tenant-env-upper-fqdn>/environment/promotion/lock/state' \(1)
--header 'Content-Type: application/json' \
--header 'Accept-API-Version: resource=1.0' \
--header 'Authorization: Bearer <access-token>'(2)
```

|       |                                                                                                                                                                                                       |
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
| **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

Learn how to analyze the response from this endpoint in [Lock environments](#lock-environments).

### Check the promotion status

To check the promotion status after you [start a promotion](#run-a-promotion), use the `/environment/promotion/promote` endpoint:

```bash
curl \
--request GET 'https://<tenant-env-upper-fqdn>/environment/promotion/promote' \(1)
--header 'Content-Type: application/json' \
--header 'Accept-API-Version: resource=1.0' \
--header 'Authorization: Bearer <access-token>'(2)
```

|       |                                                                                                                                                                                                       |
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
| **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

Learn how to analyze the response from this endpoint during a promotion in [Run a promotion](#run-a-promotion).

### Check the rollback status

To check the rollback status after you [start a rollback](#run-a-rollback), use the `/environment/promotion/promote` endpoint, as described in [Check the promotion status](#check-the-promotion-status).

Learn how to analyze the response from this endpoint during a rollback in [Run a rollback](#run-a-rollback).

## Lock environments

Before you run a promotion or a rollback, you must lock the upper and lower environments.

### Task 1: Check that the environments are unlocked

1. [Check the lock state](#check-the-lock-state) to confirm that both environments are unlocked. This is indicated in the response when `result` has a value of `unlocked`:

   ```json
   {
       "description": "Environment unlocked",
       "lowerEnv": {
           "state": "unlocked"
       },
       "result": "unlocked",
       "upperEnv": {
           "state": "unlocked"
       }
   }
   ```

### Task 2: Lock the environments

|   |                                                                                                                                                                   |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Locking an environment prevents configuration changes that could disrupt a promotion or a rollback; however, all authentication flows continue to work as normal. |

1. To lock the environments, use the `/environment/promotion/lock` endpoint to create a lock request:

   ```bash
   curl \
   --request POST 'https://<tenant-env-upper-fqdn>/environment/promotion/lock' \(1)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>'(2)
   ```

   |       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)).1) If the lock request is successful, the response `result` has a value of `locking`:

      ```json
      {
          "description": "Environment lock in progress",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "result": "locking"
      }
      ```

   2) If the lock request is rejected, the response `code` has a value of `409`.

      * In the example below the lock request was rejected because a lock already exists:

        ```json
        {
            "code": 409,
            "message": "Environment is already locked for promotion 791eb03a-7ec1-42ae-ae84-ed142cf52688"
        }
        ```

        To resolve this:

        1. If another member of your team is already running a promotion:

           1. Wait until the team member has completed their promotion and has released the lock.

           2. Start the promotion steps again.

        2. If the lock has accidentally been left in place, and no one else is running a promotion:

           1. [Unlock the environments](#unlock-environments) using the promotion ID stated in the error message.

           2. Start the promotion steps again.

      * In the example below the lock request was rejected because Ping Identity locked the environment:

        ```json
        {
            "code": 409,
            "message": "Environment is locked by {forgerock_name} for maintenance. Retry later."
        }
        ```

        Ping Identity typically locks an environment so that Ping Identity support engineers can investigate an issue or perform maintenance. To resolve this, wait until Ping Identity releases the lock.

   3) If the lock request causes an unexpected error, the response `code` has a value of `500`.

      ```json
      {
          "code": 500,
          "message": "<internal-error-message>"
      }
      ```

      To resolve this, open a support case with Ping Identity support. Learn more in [Resolve environment errors that are preventing a promotion or a rollback](#resolve-environment-errors-that-are-preventing-a-promotion-or-a-rollback). |

2. [Check the lock state](#check-the-lock-state) to confirm that the lock is in progress. This is indicated in the response when `result` has a value of `locking`:

   ```json
   {
       "description": "Environment lock in progress",
       "lowerEnv": {
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "state": "locking"
       },
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "result": "locking",
       "upperEnv": {
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "state": "locking"
       }
   }
   ```

3. [Check the lock state](#check-the-lock-state) as many times as you need until both environments are locked. This is indicated in the response when `result` has a value of `locked`:

   ```json
   {
       "description": "Environment locked",
       "lowerEnv": {
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "state": "locked"
       },
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "result": "locked",
       "upperEnv": {
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "state": "locked"
       }
   }
   ```

## Run a promotion

### Task 1: (Optional) Check how a promotion will affect deferred release status

If you intend to promote to your production environment, first check whether a [deferred release](../release-notes/release-deferral.html) is currently active. This ensures you understand how your promotion aligns with the 7-day deferral period, and lets you plan the upgrade at a time that works best for your organization.

To understand how a promotion will affect an active deferred release, use the `/environment/promotion/info` endpoint.

1. Run the following command against the production environment:

   ```bash
   curl \
   --request GET 'https://<tenant-env-upper-fqdn>/environment/promotion/info' \(1)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>'(2)
   ```

   |       |                                                                                                                                                                                                       |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
   | **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

   Example response

   ```json
   {
       "activePromotionId": "ba594bbe-a589-4676-80a4-42975a56f5b6",
       "promotionWouldTriggerReleaseUpgrade": true
   }
   ```

2. Analyze the response to check if a promotion will trigger a release upgrade.

   * If `promotionWouldTriggerReleaseUpgrade` has a value of `false`, a promotion won't trigger a release upgrade. You can proceed with the self-service promotion and move to the next task.

   * If `promotionWouldTriggerReleaseUpgrade` has a value of `true`, a promotion will trigger a release upgrade. You have two options:

     * If your organization has completed its evaluation of the deferred release and is ready to promote it, you can proceed with the self-service promotion and move to the next task.

     * Otherwise, raise a support case in the [Ping Identity Support Portal](https://support.pingidentity.com) so that Ping Identity support can run the promotion on your behalf without triggering a release upgrade. Learn more in [Support-assisted deployment options](../release-notes/release-process.html#support-assisted-deployment-options).

### Task 2: Lock the environments

Follow the instructions in [Lock environments](#lock-environments).

### Task 3: Check that a promotion isn't already running

[Check the promotion status](#check-the-promotion-status) to confirm that a promotion is not already running. This is indicated in the response when `status` has a value of `READY`:

```json
{
    "status": "READY",
    "message": "Environment ready for promotion",
    "blockingError": false,
    "globalLock": "LOCKED",
    "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
    "timeStamp": "2024-06-12T17:12:32Z",
    "type": "promotion"
}
```

### Task 4: Run a dry-run promotion

When you're ready to run a promotion, perform a dry-run promotion first. This lets you identify potential problems with [missing ESVs](self-service-promotions.html#integrity-check-for-missing-esvs) or [encrypted secrets](self-service-promotions.html#integrity-check-for-encrypted-secrets) without promoting any changes to the upper environment.

To run a dry-run promotion, follow the steps in [Task 5: Run the promotion](#run-the-promotion), but in step 1, set the `dryRun` flag to `true`:

```bash
--data-raw '{
    "dryRun": true
}'
```

|   |                                                                                                                                                                                                                                                                                                                                                      |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | If there are any scripts awaiting promotion, ensure that they do not emit any personally identifiable information (PII) of your end users into Advanced Identity Cloud logs.Ping Identity recommends that you establish a review and testing process for all scripts to prevent PII leaking out of your Advanced Identity Cloud tenant environments. |

### Task 5: Run the promotion

1. To run a promotion, use the `/environment/promotion/promote` endpoint:

   ```bash
   curl \
   --request POST 'https://<tenant-env-upper-fqdn>/environment/promotion/promote' \(1)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>' \(2)
   --data-raw '{
       "dryRun": false (3)
   }'
   ```

   |       |                                                                                                                                                                                                       |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
   | **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |
   | **3** | The `dryRun` flag is set to `false` in the request body.                                                                                                                                              |

   ```json
   {
       "result": "Promotion process initiated successfully"
   }
   ```

2. [Check the promotion status](#check-the-promotion-status) to confirm that the promotion is in progress. This is indicated in the response when `status` has a value of `RUNNING`:

   ```json
   {
       "status": "RUNNING",
       "message": "Prepare config",
       "blockingError": false,
       "globalLock": "LOCKED",
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "timeStamp": "2024-06-12T17:14:13Z",
       "type": "promotion"
   }
   ```

3. [Check the promotion status](#check-the-promotion-status) as many times as you need until the promotion is complete.

   1. If the promotion is still running, the response `status` has a value of `RUNNING`:

      ```json
      {
          "status": "RUNNING",
          "message": "Promote configuration",
          "blockingError": false,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:15:51Z",
          "type": "promotion"
      }
      ```

   2. If the promotion failed but is recoverable, the response `status` has a value of `ERROR`, and the response `blockingError` has a value of `false`.

      1. In the example below, the promotion failed an [integrity check for missing ESVs](self-service-promotions.html#integrity-check-for-missing-esvs).

         ```json
         {
             "status": "ERROR",
             "message": "Missing ESVs",
             "blockingError": false,
             "missingESVs": [
                 "email.from"
             ],
             "globalLock": "LOCKED",
             "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
             "timeStamp": "2024-06-12T17:19:31Z",
             "type": "promotion"
         }
         ```

         To resolve this:

         1. [Unlock the environments](#unlock-environments).

         2. For each ESV in `missingESVs`, add an ESV into the upper environment.

         3. Start the promotion steps again.

      2. In the example below, the promotion failed an [integrity check for encrypted secrets](self-service-promotions.html#integrity-check-for-encrypted-secrets).

         ```json
         {
             "status": "ERROR",
             "message": "Found encrypted values in the AM/IDM configuration",
             "blockingError": false,
             "globalLock": "LOCKED",
             "encryptedSecrets": [
                 "* am/services/realm/root-alpha/persistentcookiedecisionnode/1.0/organizationconfig/default/dd35c42f-177e-4633-9107-373214858fa7.json:10"
             ],
             "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
             "timeStamp": "2024-06-12T17:19:31Z",
             "type": "promotion"
         }
         ```

         To resolve this:

         1. If the encrypted secret is in your configuration by accident:

            1. [Unlock the environments](#unlock-environments).

            2. Create an ESV secret containing the encrypted secret in each of the development, staging, and production environments.

            3. Update your configuration to reference the new ESV secret.

            4. Start the promotion steps again.

         2. If the encrypted secret is in your configuration deliberately, you can bypass this check:

            1. Follow the steps in [Task 5: Run the promotion](#run-the-promotion), but in step 1, set the `ignoreEncryptedSecrets` flag to `true`:

               ```bash
               --data-raw '{
                   "dryRun": false,
                   "ignoreEncryptedSecrets": true
               }'
               ```

   3. If the promotion failed and is *not* recoverable, the response `status` has a value of `ERROR`, and the response `blockingError` has a value of `true`:

      ```json
      {
          "status": "ERROR",
          "message": "Failed to promote config",
          "blockingError": true,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:19:31Z",
          "type": "promotion"
      }
      ```

      If you run the promotion again after a blocking error, the following response displays:

      ```json
      {
          "code": 409,
          "message": "Environment is blocked from a previous failed promotion or rollback"
      }
      ```

      To resolve this, open a support case with Ping Identity support. Learn more in [Resolve environment errors that are preventing a promotion or a rollback](#resolve-environment-errors-that-are-preventing-a-promotion-or-a-rollback).

   4. If Advanced Identity Cloud services are restarting, the response `status` has a value of `RUNNING`, and the response `message` has a value of `Waiting for workloads to restart`:

      ```json
      {
          "status": "RUNNING",
          "message": "Waiting for workloads to restart",
          "blockingError": false,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:32:06Z",
          "type": "promotion"
      }
      ```

      This part of the promotion can take several minutes. It does not apply to dry-run promotions, where Advanced Identity Cloud services do not need to be restarted.

   5. If the promotion is complete, the response `status` has a value of `READY`, and the response `message` has a value of `Promotion completed`:

      ```json
      {
          "status": "READY",
          "message": "Promotion completed",
          "blockingError": false,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:40:29Z",
          "type": "promotion"
      }
      ```

      If no changes have been promoted, the `message` has a value of `Promotion completed (no change)`.

### Task 6: View the promotion report

1. To view a report for the most recent promotion, use the `/environment/promotion/report` endpoint.

   ```bash
   curl \
   --request GET 'https://<tenant-env-upper-fqdn>/environment/promotion/report' \(1)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>' \(2)
   ```

   |       |                                                                                                                                                                                                       |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
   | **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

   ```json
   {
       "createdDate": "2024-06-12T17:32:05Z",
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "report": {
           "IDMConfig": [
               {
                   "configChange": {
                       "added": [
                           "Forgotten Username"
                       ]
                   },
                   "configItem": "Email > Templates",
                   "fileDestinationPattern": "idm/conf/emailTemplate-*.json",
                   "fileName": "displayName",
                   "type": "single"
               }
           ]
       },
       "reportId": "c41286bb-30cd-4109-ba9d-dc4788b6a75c",
       "reportName": "Report_2024-06-12T17-32+00Z_dryrun=false_8acd3a87-2272-450f-a3b3-1eb222108740",
       "type": "promotion"
   }
   ```

   In the example above, the promotion report shows that email template configuration was promoted.

2. To view a report from before the most recent promotion, learn more in [View previous promotion or rollback reports](#view-previous-promotion-or-rollback-reports).

### Task 7: Unlock the environments

Follow the instructions in [Unlock environments](#unlock-environments).

## Run a rollback

### Task 1: (Optional) Check how a rollback will impact a release upgrade

If you intend to run a rollback on your production environment, check with your team if the promotion you're rolling back triggered a release upgrade. To understand why the release might have triggered a release upgrade, refer to [Release deferral](../release-notes/release-deferral.html).

* If the promotion you're rolling back didn't trigger a release upgrade, you can proceed with the self-service rollback and move to the next task.

* If the promotion you're rolling back did trigger a release upgrade, you have two options:

  * If you want to roll back both the promotion and the release upgrade, raise a support case in the [Ping Identity Support Portal](https://support.pingidentity.com) so that Ping Identity support can run the rollback on your behalf.

  * Otherwise, if you want to roll back only the promotion and keep the release upgrade, you can proceed with the self-service rollback and move to the next task.

### Task 2: Lock the environments

Follow the instructions in [Lock environments](#lock-environments).

### Task 3: Check that a promotion isn't already running

[Check the promotion status](#check-the-promotion-status) to confirm that a promotion isn't already running. This is indicated in the response when `status` has a value of `READY`:

```json
{
    "status": "READY",
    "message": "Environment ready for promotion",
    "blockingError": false,
    "globalLock": "LOCKED",
    "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
    "timeStamp": "2024-06-12T17:12:32Z",
    "type": "promotion"
}
```

### Task 4: Get a provisional rollback report

To get a provisional rollback report, use the `/environment/promotion/report/provisional-rollback` endpoint:

```bash
curl \
--request GET 'https://<tenant-env-upper-fqdn>/environment/promotion/report/provisional-rollback' \(1)
--header 'Content-Type: application/json' \
--header 'Accept-API-Version: resource=1.0' \
--header 'Authorization: Bearer <access-token>'(2)
```

|       |                                                                                                                                                                                                       |
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
| **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

```json
{
    "createdDate": "2024-06-12T17:32:05Z",
    "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
    "report": {
        "IDMConfig": [
            {
                "configChange": {
                    "added": [
                        "Forgotten Username"
                    ]
                },
                "configItem": "Email > Templates",
                "fileDestinationPattern": "idm/conf/emailTemplate-*.json",
                "fileName": "displayName",
                "type": "single"
            }
        ]
    },
    "reportId": "c41286bb-30cd-4109-ba9d-dc4788b6a75c",
    "reportName": "Report_2024-06-12T17-32+00Z_dryrun=false_8acd3a87-2272-450f-a3b3-1eb222108740",
    "type": "provisional-rollback"
}
```

### Task 5: Run the rollback

1. To run a rollback, use the `/environment/promotion/rollback` endpoint:

   ```bash
   curl \
   --request POST 'https://<tenant-env-upper-fqdn>/environment/promotion/rollback' \(1)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>' \(2)
   --data-raw '{}'
   ```

   |       |                                                                                                                                                                                                       |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
   | **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

   ```json
   {
       "result": "Rollback process initiated successfully"
   }
   ```

2. [Check the rollback status](#check-the-rollback-status) to confirm that the rollback is in progress. This is indicated in the response when `status` has a value of `RUNNING`:

   ```json
   {
       "status": "RUNNING",
       "message": "Prepare config",
       "blockingError": false,
       "globalLock": "LOCKED",
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "timeStamp": "2024-06-12T17:14:13Z",
       "type": "rollback"
   }
   ```

3. [Check the rollback status](#check-the-rollback-status) as many times as you need until the rollback is complete.

   1. If the rollback is still running, the response `status` has a value of `RUNNING`:

      ```json
      {
          "status": "RUNNING",
          "message": "Rollback configuration",
          "blockingError": false,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:15:51Z",
          "type": "rollback"
      }
      ```

   2. If the rollback failed but is recoverable, the response `status` has a value of `ERROR`, and the response `blockingError` has a value of `false`.

      1. In the example below, the rollback failed an [integrity check for missing ESVs](self-service-promotions.html#integrity-check-for-missing-esvs).

         ```json
         {
             "status": "ERROR",
             "message": "Missing ESVs",
             "blockingError": false,
             "missingESVs": [
                 "email.from"
             ],
             "globalLock": "LOCKED",
             "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
             "timeStamp": "2024-06-12T17:19:31Z",
             "type": "rollback"
         }
         ```

         To resolve this:

         1. [Unlock the environments](#unlock-environments).

         2. For each ESV in `missingESVs`, re-add the ESV into the upper environment.

         3. Start the rollback steps again.

   3. If the rollback failed and is *not* recoverable, the response `status` has a value of `ERROR`, and the response `blockingError` has a value of `true`:

      ```json
      {
          "status": "ERROR",
          "message": "Failed to rollback config",
          "blockingError": true,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:19:31Z",
          "type": "rollback"
      }
      ```

      If you run the rollback again after a blocking error, the following response displays:

      ```json
      {
          "code": 409,
          "message": "Environment is blocked from a previous failed promotion or rollback"
      }
      ```

      To resolve this, open a support case with Ping Identity support. Learn more in [Resolve environment errors that are preventing a promotion or a rollback](#resolve-environment-errors-that-are-preventing-a-promotion-or-a-rollback).

   4. If Advanced Identity Cloud services are restarting, the response `status` has a value of `RUNNING`, and the response `message` has a value of `Waiting for workloads to restart`:

      ```json
      {
          "status": "RUNNING",
          "message": "Waiting for workloads to restart",
          "blockingError": false,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:32:06Z",
          "type": "rollback"
      }
      ```

      This part of the rollback can take several minutes.

   5. If the rollback is complete, the response `status` has a value of `READY`, and the response `message` has a value of `Promotion completed`:

      ```json
      {
          "status": "READY",
          "message": "Rollback completed",
          "blockingError": false,
          "globalLock": "LOCKED",
          "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
          "timeStamp": "2024-06-12T17:40:29Z",
          "type": "rollback"
      }
      ```

### Task 6: Unlock the environments

Follow the instructions in [Unlock environments](#unlock-environments).

## Unlock environments

After you run a promotion or a rollback, you must unlock the upper and lower environments.

1. To unlock the environments, use the `/environment/promotion/lock` endpoint:

   ```bash
   curl \
   --request DELETE 'https://<tenant-env-upper-fqdn>/environment/promotion/lock/<promotion-id>' \(1) (2)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>'(3)
   ```

   |       |                                                                                                                                                                                                       |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
   | **2** | Replace `<promotion-id>` with the `promotionId` created when you initially locked the environments.                                                                                                   |
   | **3** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

   ```json
   {
       "description": "Environment unlock in progress",
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "result": "unlocking"
   }
   ```

2. [Check the lock state](#check-the-lock-state) as many times as you need until both environments are unlocked. This is indicated in the response when `result` has a value of `unlocked`:

   ```json
   {
       "description": "Environment locked",
       "lowerEnv": {
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "state": "locked"
       },
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "result": "locked",
       "upperEnv": {
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "state": "locked"
       }
   }
   ```

## View previous promotion or rollback reports

1. To view a list of previous promotion or rollback reports, use the `/environment/promotion/reports` endpoint:

   ```bash
   curl \
   --request GET 'https://<tenant-env-upper-fqdn>/environment/promotion/reports' \(1)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>'(2)
   ```

   |       |                                                                                                                                                                                                       |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
   | **2** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

   ```json
   [
       {
           "createdDate": "2024-06-12T12:00:29Z",
           "dryRun": true,
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "reportId": "57aabe7d-4e8c-4fbb-8a13-2fc7d1cb4d52",
           "type": "promotion"
       },
       {
           "createdDate": "2024-06-12T17:32:05Z",
           "dryRun": false,
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "reportId": "c41286bb-30cd-4109-ba9d-dc4788b6a75c",
           "type": "promotion"
       },
       {
           "createdDate": "2024-06-12T13:56:10Z",
           "dryRun": true,
           "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
           "reportId": "df893dee-e952-489c-b94d-8c9ebf36e9a5",
           "type": "promotion"
       }
   ]
   ```

2. To view individual reports, use the `/environment/promotion/report` endpoint and supply a `reportId` from the response in the previous step:

   ```bash
   curl \
   --request GET 'https://<tenant-env-upper-fqdn>/environment/promotion/report/<report-id>' \(1) (2)
   --header 'Content-Type: application/json' \
   --header 'Accept-API-Version: resource=1.0' \
   --header 'Authorization: Bearer <access-token>'(3)
   ```

   |       |                                                                                                                                                                                                       |
   | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | Replace `<tenant-env-upper-fqdn>` with the FQDN of the upper environment.                                                                                                                             |
   | **2** | Replace `<report-id>` with a `reportId`; for example, `c41286bb-30cd-4109-ba9d-dc4788b6a75c`.                                                                                                         |
   | **3** | Replace `<access-token>` with an access token for the upper environment (learn more in [Get an access token](../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token)). |

   ```json
   {
       "createdDate": "2024-06-12T17:32:05Z",
       "promotionId": "8acd3a87-2272-450f-a3b3-1eb222108740",
       "report": {
           "IDMConfig": [
               {
                   "configChange": {
                       "added": [
                           "Forgotten Username"
                       ]
                   },
                   "configItem": "Email > Templates",
                   "fileDestinationPattern": "idm/conf/emailTemplate-*.json",
                   "fileName": "displayName",
                   "type": "single"
               }
           ]
       },
       "reportId": "c41286bb-30cd-4109-ba9d-dc4788b6a75c",
       "reportName": "Report_2024-06-12T17-32+00Z_dryrun=false_8acd3a87-2272-450f-a3b3-1eb222108740",
       "type": "promotion"
   }
   ```

## Resolve environment errors that are preventing a promotion or a rollback

To resolve environment errors that are preventing a promotion or a rollback, open a support case:

1. Go to <https://support.pingidentity.com>.

2. Click Create a case.

3. Follow the steps in the case submission wizard by selecting your account and contract and answering questions about your tenant environments.

4. On the Please answer the following questions to help us understand the issue you're facing page, enter the following details, and then click Next:

   | Field                                                | Value                                                                       |
   | ---------------------------------------------------- | --------------------------------------------------------------------------- |
   | What product family is experiencing the issue?       | Select PingOne Advanced Identity Cloud                                      |
   | What specific product is experiencing the issue?     | Select Tenant Settings                                                      |
   | What version of the product are you using?           | Select NA                                                                   |
   | Which component is affected?                         | Select Self-Service Promotion                                               |
   | What Hostname(s) or Tenant ID(s) does this apply to? | Enter a comma-separated list of FQDNs for the relevant tenant environments. |

5. On the Tell us about the issue page, enter the following details, and then click Next:

   | Field                                      | Value                                                                                                                                                                                                                                                                                                                    |
   | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
   | Provide a descriptive title for your issue | Enter one of the following:- `Resolve environment errors preventing a self-service promotion`

   - `Resolve environment errors preventing a self-service rollback`                                                                                                                                                         |
   | Describe the issue below                   | Enter the following details:- The error type, either:

     * `An error has occurred during a self-service promotion to the development/staging/production environment`

     * `An error has occurred during a self-service rollback from the staging/production environment`

   - The error code and message (API users only). |

6. Click Submit.

## Revert configuration in your development environment

To revert configuration in your development environment, open a support case:

1. Go to <https://support.pingidentity.com>.

2. Click Create a case.

3. Follow the steps in the case submission wizard by selecting your account and contract and answering questions about your tenant environments.

4. On the Please answer the following questions to help us understand the issue you're facing page, enter the following details, and then click Next:

   | Field                                                | Value                                                                       |
   | ---------------------------------------------------- | --------------------------------------------------------------------------- |
   | What product family is experiencing the issue?       | Select PingOne Advanced Identity Cloud                                      |
   | What specific product is experiencing the issue?     | Select Configuration                                                        |
   | What version of the product are you using?           | Select NA                                                                   |
   | What Hostname(s) or Tenant ID(s) does this apply to? | Enter a comma-separated list of FQDNs for the relevant tenant environments. |

5. On the Tell us about the issue page, enter the following details, and then click Next:

   | Field                                      | Value                                                                                                                                                                                   |
   | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | Provide a descriptive title for your issue | Enter `Select Restore from backup`                                                                                                                                                      |
   | Describe the issue below                   | Enter the following details:- The FQDN of the upper environment from the promotion you need to revert.

   - The date when you last had stable configuration, using the format YYYY-MM-DD. |

6. Click Submit.
