Azure Pipelines: Bulk approve of deployments to environments

I was just searching for an answer for this regarding getting the approval id that you would need. In fact there is an undocumented API to approve an approval check.

This is as Merlin explain the following

https://dev.azure.com/{org}/{project}/_apis/pipelines/approvals/{approvalId}

The body has to look like this

[{
    "approvalId": "{approvalId}",
    "status": {approvalStatus},
    "comment": ""
}]

where {approvalStatus} is telling the API if you approved or not. You probly have to try, but I had a 4 as a status. I guess there are only 2 possibilities. Either for "approved" or "denied".

The question is now how you get the approval ID? I found it. You get it by using the timeline API of a classic build. The build API documentation says that you get it by the following

https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=5.1

the build timeline you get in the response of the build run, but it has a pattern which is

https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/Timeline?api-version=5.1

Besides a flat array container a parent / child rleationship from stage, phase, job and tasks, you can find within it something like the following:

{
  "records": [
    {
      "previousAttempts": [
        
      ],
      "id": "95f5837e-769d-5a92-9ecb-0e7edb3ac322",
      "parentId": "9e7965a8-d99d-5b8f-b47b-3ee7c58a5b1c",
      "type": "Checkpoint",
      "name": "Checkpoint",
      "startTime": "2020-08-14T13:44:03.05Z",
      "finishTime": null,
      "currentOperation": null,
      "percentComplete": null,
      "state": "inProgress",
      "result": null,
      "resultCode": null,
      "changeId": 73,
      "lastModified": "0001-01-01T00:00:00",
      "workerName": null,
      "details": null,
      "errorCount": 0,
      "warningCount": 0,
      "url": null,
      "log": null,
      "task": null,
      "attempt": 1,
      "identifier": "Checkpoint"
    },
    {
      "previousAttempts": [
        
      ],
      "id": "9e7965a8-d99d-5b8f-b47b-3ee7c58a5b1c",
      "parentId": null,
      "type": "Stage",
      "name": "Power Platform Test (orgf92be262)",
      "startTime": null,
      "finishTime": null,
      "currentOperation": null,
      "percentComplete": null,
      "state": "pending",
      "result": null,
      "resultCode": null,
      "changeId": 1,
      "lastModified": "0001-01-01T00:00:00",
      "workerName": null,
      "order": 2,
      "details": null,
      "errorCount": 0,
      "warningCount": 0,
      "url": null,
      "log": null,
      "task": null,
      "attempt": 1,
      "identifier": "Import_Test"
    },
    {
      "previousAttempts": [
        
      ],
      "id": "e54149c5-b5a7-4b82-8468-56ad493224b5",
      "parentId": "95f5837e-769d-5a92-9ecb-0e7edb3ac322",
      "type": "Checkpoint.Approval",
      "name": "Checkpoint.Approval",
      "startTime": "2020-08-14T13:44:03.02Z",
      "finishTime": null,
      "currentOperation": null,
      "percentComplete": null,
      "state": "inProgress",
      "result": null,
      "resultCode": null,
      "changeId": 72,
      "lastModified": "0001-01-01T00:00:00",
      "workerName": null,
      "details": null,
      "errorCount": 0,
      "warningCount": 0,
      "url": null,
      "log": null,
      "task": null,
      "attempt": 1,
      "identifier": "e54149c5-b5a7-4b82-8468-56ad493224b5"
    }
  ],
  "lastChangedBy": "00000002-0000-8888-8000-000000000000",
  "lastChangedOn": "2020-08-14T13:44:03.057Z",
  "id": "86fb4204-9c5e-4e72-bdb1-eefe230480ec",
  "changeId": 73,
  "url": "https://dev.azure.com/***"
}

below you can see a step that is called "Checkpoint.Approval". The id of that step IS the approval Id you need to approve everything. If you want to know from which stage the approval is, then you can follow up the parentIds until the parentId property is null. This will then be the stage.

With this you can successfully get the approval id and use it to approve with the said


What jessehouwing's guess is correct. Now multi-stage still be in preview, and the corresponding SDK/API/extension hasn't been expanded and provided to public.

You may think that what about not using API. I have checked the corresponding code from our backend, all of operations to multi-stage approval contain one required parameter: approvalId. I'm sure you have known that this value is unique and different approval map with different approvalId value. This means, no matter which method you want to try with, approvalId is the big trouble. And based on my known, until now, there's no any api/SDK, third tool or extension can achieve this value directly.


In addition, for multi-stage YAML, its release process logic is not same with the release that defined with UI. So, all of public APIs which can work with release(UI), are not suitable with the release of multi-stage.

We have one undisclosed api, can get Approval message of multi-stage:

https://dev.azure.com/{org}/{project}/_apis/pipelines/approvals/{approvalId}

You can try with listing approval without specifying approvalId: https://dev.azure.com/{org}/{project}/_apis/pipelines/approvals. And its response message: Query for approvals failed. A minimum of one query parameter is required.\r\nParameter name: queryParameters. This represents you must tell system the specified approval(the big trouble I mentioned previously).

In fact, for why approvalId is a necessary part, it is caused from our backend code structure. I'd suggest you raise suggestion on developing API/SDK for multi-stage here.