Share →

Microsoft has released documentation for the VSTS/TFS REST API as of a couple of months ago, and we’re really excited for the opportunities that the REST API brings for VSTS and TFS.


Previously, you could use the Client Object Model and the API to interact with TFS. Now, you can interact with VSTS and TFS via scripts or your preferred language of choice, even bypassing the Web UI in an easier-to-consume fashion with a popular implementation. Do you need to chain builds so that one build triggers another? Do you want a Jenkins or external build to create a release and deploy to environments? Do you need to get the results from a test run? You can do that and more using the VSTS/TFS REST API.

I was at a client site this past week and started really digging into using the REST API through PowerShell, so I thought I’d pass along tips that I’ve learned. I’ve only started exploring the Build (2.0) and Release areas of the REST API, but there’s currently documentation out there for interacting with accounts and profiles, cloud load testing, Git, code policies, packaging, projects and teams, service hooks, team rooms, test management, version control, work, and work item tracking.

What is a REST API?

REST APIs are the web technologies for the cool kids now. Many large companies you know have jumped on the bandwagon, like Twitter, WordPress, SalesForce, and more. REST (Representational State Transfer) is a software architectural style of the World Wide Web.

In a nutshell, you specify various HTTP verbs (such as GET, PUT, POST, and PATCH) and point to a specific URI (Uniform Resource Identifier) to interact with the API of that software. When you want to perform an action against a URI, you perform requests. For instance, you can perform a GET request to a specific URI to list information. When using POST, PUT, or PATCH, you may also need to specify a request body, which may be in JSON that the API can use as additional information for the request. The URI that you point to sends back responses, usually in JSON but may also be in XML, HTML, or even zip files.

You can call REST APIs in a ton of different programming languages like Perl, PHP, C#, and PowerShell. We wanted to call the TFS REST API through a script in a build process, so we opted to use PowerShell.

In PowerShell, most of the work can be done by creating the JSON stored in a variable, creating the URI (I used a base URI variable and appended specific URIs), and using Invoke-RestMethod or Invoke-WebRequest to call the REST API.

For the VSTS/TFS REST APIs, you use specific requests documented on their site to interact with your VSTS or TFS instance, such as getting build info, queueing builds, creating releases, creating work items, and others. If you haven’t already, check out this link from the VSTS/TFS REST API documentation about getting started with the REST APIs.

How can I authenticate to the VSTS/TFS REST API?

Now, this may not be the only way to authenticate, but here’s one way in PowerShell. VSTS and TFS have different authentication methods, so I’ll start with VSTS.

In order to authenticate with VSTS in a script, you need to either configure alternate credentials or set up a personal access token.

You’ll want to grab a personal access token with whichever permissions you want depending on the REST API calls you think you’ll make, then you will want to pass the token into a script. One way to do it would be masking it as a secret variable in VSTS and passing it as an argument into the PowerShell script. Then, in PowerShell, you can do something like this with your calls:

When pointing to TFS, one way that you can pass a username and password (masked as a secret variable) through PowerShell into a PSCredential object and use the -Credential switch when invoking the REST method:

However, you also need to make sure that SSL is configured so that passwords aren’t being passed as plain text over the wire.

So another (and preferred) way to pass in credentials to TFS is:

This will use the credentials of the logged in user to authenticate with TFS.

In the following examples, at the time of writing this, I’m using Build (2.0) and Release (3.0-preview.2). Future versions may change requirements (e.g. “name” is required in Release (2.2-preview.1) and optional in Release (3.0-preview.2)), so double-check that documentation.

Queuing a build

If you want to queue a build from another source (like a Jenkins job), you can use a script to call the REST API. After you’ve gotten authentication working, you’ll want to pass that into the Invoke-RestMethod call. Since this is not just listing info like a GET request, you have to pass in the JSON body:

Then, generate the URI:

I actually used variables, so mine really looks like:

Lastly, invoke the REST command:



Once you get the response, you can get the ID of the build that you just queued:


Getting build details

You can get a lot of useful build information from doing a GET request. Once you have the build ID, you can generate the URI:

And call the REST API (note that you don’t need to pass in a JSON body):



And you can also get good information like the status of the build and store it in a variable. For instance, you can have a loop that will perform a GET request looking for the status to be completed or succeeded. The benefit of that may be that if you want the script to be synchronous and be done when the build is done.


Creating a release

The Release Management API is brand-new and in preview, so it may not be fully fleshed out yet. But you can create a release, get release info, deploy to an environment, and more! To create a release, you need the JSON body:

In VSTS (required elements):

  • definitionId = release definition ID
  • description = description of release
  • alias = artifact alias
  • id = build ID


In TFS (required elements):

  • definitionId = release definition ID
  • description = description of release
  • alias = artifact alias
  • id = build ID
  • name = build name


Get the URI (VSTS is 3.0-preview.2, TFS is 2.2-preview.1):


With variables (VSTS or TFS):

Invoke the REST method (assuming that authentication has already been configured):



Again, you can get useful information from the response of the POST request, like the ID of the release.


Getting info about the release

Get the ID of the release from the response of the POST request:

Create the URI (use the right API version for you):

Invoke the REST method:



Using the GET request, you can get good info like the environment IDs.


Deploying to environments

Since deploying to an environment uses a PATCH request, you need to pass in a JSON body. You can get information about all of the environments from your GET request and determine which environment you want to deploy your artifacts. If you have pre-deployment approvals before the environment that you deploy to that hasn’t yet been approved, you will need to call that PATCH request before this.

You can get all of the environment IDs from the release response like:

You can get the first environment by grabbing the first element in the environment IDs array:

Then, create the JSON body for the deployment:

Create the URI with the environment to deploy to:

And invoke the REST method:




There you have it! Although we’ve only scratched the surface of everything that’s available in the new REST API for VSTS/TFS, there are a lot of great possibilities for interacting with VSTS and TFS in the future. You may have noticed that there is a pattern for these requests and responses, so it’s very easy to pick up on using any commands in the VSTS/TFS REST API since they follow the same general format.

Happy coding!

Print Friendly
  • Keith Lemon

    Great article. I’m looking to chain together a number of VSTS Releases to build out a IaC implementation for a complex solution. We are refactoring a very large monolithic process, and i wanted to see if you have any experience with this or would know of any material that would support the approach.

  • Joe Watts

    Very helpful. Do you have any advice on how to set up a download of the artifacts from VSTS?

    That is reliable. I have not found that utiulizing the download link as provided by the VSTS Build api 2.0 to be reliable when invoked via PowerShell using:

    Invoke-WebRequest -uri $artrifactUrl -Headers $headers -UseBasicParsing-OutFile $archiveDestination

    In fact I often get the exception “Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.” This usually occurs just before the download finishes up.

    Have you got any ideas about how to make this download reliable from a powershell process?s

  • Jan Stavngaard

    I just wanted to point out that for me it was easier to use -UseDefaultCredentials for on-prem TFS if applicable instead of -Credential $credential

  • Sachi Williamson

    Good catch! I found that as well a while ago and that is a much easier way to pass in credentials through TFS. Updated!

  • Suman Biswas


    I am looking for the rest API using which I can Scheduling the release for a specific environment. It will be similar to the pre deployment approval with selecting the option “Defer this deployment to” and specifying specific date and time to start the deployment. I am looking for rest api that will do the same thing.

    Can you provide any reference on this.

  • pczapka


    I have exacly the same question…

  • Sajan Mani

    Hi, I’m trying to add a new environment to TFS (currently have dev, need to add qa – only few variables gets changed, everything else remains as-is) how to do that, any help is appreciated.