Trigger a DevOps Pipeline from the Azure DevOps Rest API Webhook

Sometimes, you need the ability to trigger a DevOps build or release pipeline when a condition is met through a piece of code or from outside of the Azure DevOps environment.

In order to achieve this, we can utilise the DevOps API (Application Programming Interface) and send a Push request to a webhook URI (Uniform Resource Identifier) that will act as a trigger for a pipeline.

Creating a Personal Access Token

You can trigger any pipeline to run as long as you have the A Personal Access Token, which can be accessed from Personal Access Tokens within the user menu.

Here, you’ll want to create a new token.

The name is not important, I’ve used “triggerFromWebhook”. For expiry, I’ve set it to custom defined and made it last a year.

You’ll want to use a Custom Defined Scope, for which I’ve used the following settings.

It’s important that you copy the token that appears as you will not be able to access it again once the tab is closed. This token will be used as a basic authentication password.

That’s all we need to now trigger this pipeline from another location using a REST (Representational State Transfer) method.

Triggering the DevOps pipeline

You’ll use the following headers:

AuthorizationBasic {token}
Content-TypeApplication/json

And the following body:

{
           definitionId: _
}

The definition ID comes from the pipeline itself. It can be found inside the the URL of the pipeline you’re triggering.

In this case, the ID will be 26.

The endpoint we’re hitting will look something like this:

https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/release?api-version=7.1-preview.8

The API method will be Post. Attach the headers and body and the release pipeline should be triggered.

Triggering a build pipeline

To trigger a build pipeline, you’ll need a different set of body and URL.

https://dev.azure.com/{organization}/{project}/_apis/pipelines/{pipelineID}/runs?&api-version=7.1-preview.1

The body will contain:

{
                      “templateParameters”: {“inputName”:”inputValue”}
}

If no inputs are required, then we run this with an empty template parameters value. The headers and method are the same for both runs.