---
title: "Azure DevOps"
canonical_url: "https://docs.getdx.com/connectors/azure-devops/"
md_url: "https://docs.getdx.com/connectors/azure-devops.md"
last_updated: "2026-06-18"
---

# Azure DevOps
By integrating Azure DevOps with DX, you can analyze pull requests, repositories, and pipelines data. Please refer to the API documentation below and our [schema explorer](https://docs.getdx.com/schema/) to see what data DX imports—note that DX does not read or access your source code.

DX provides four separate connectors—for Boards, Pipelines, Repos, and Pull Commits—which must be configured independently with separate service accounts and API tokens in order to avoid rate limit issues.

## Prerequisites

To connect ADO to DX, you need:

- an ADO service account
- personal access token (PAT) with expiration date

## Setup instructions


> This connector supports multiple credentials. You can add additional credentials to distribute API requests across multiple tokens, improving import speed and reliability. To learn more, go to [Can I use multiple API credentials for a data connector?](https://docs.getdx.com/knowledgebase/can-i-use-multiple-api-credentials-for-a-data-connector/)


Follow the steps below to connect Azure DevOps to DX.

### Data connection

#### Step 1

1. Go to the [Azure portal](https://portal.azure.com/) and create a service account in Microsoft Entra ID (formerly Azure Active Directory).
2. Then, assign the service account to an ADO organization and grant them permissions.
   - See [Add organization users and manage access](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/add-organization-users?view=azure-devops&tabs=browser) and [Security groups, service accounts, and permissions reference](https://learn.microsoft.com/en-us/azure/devops/organizations/security/permissions?view=azure-devops&tabs=preview-page) for more information.

#### Step 2

1. Log into ADO using the service account
2. Generate a Personal Access Token with the read permissions outlined below:

| Connection Type              | Permissions                                                                                                                         |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| ADO Boards                   | - Work Items (read)<br>- Graph (read)<br>- Identity (read)<br>- Project and Team (read)<br>- Release (read)<br>- Task Groups (read) |
| ADO Pipelines                | - Build (read)<br>- Graph (read)<br>- Identity (read)<br>- Project and Team (read)<br>- Release (read)<br>- Task Groups (read)      |
| ADO Repositories             | - Code (read)<br>- Graph (read)<br>- Identity (read)<br>- Project and Team (read)<br>- Release (read)<br>- Task Groups (read)       |
| ADO Pull Commits             | - Code (read)                                                                                                                       |
| ADO Commits (Default branch) | - Code (read)                                                                                                                       |

<aside class="aside flow info"><p>We request the same base scopes for multiple connections since it allows each connection to work independently to get the core data for projects, teams etc.</p></aside>

#### Step 3

- Navigate to the connections page in DX and select "+ Connection" in the top right.
- Enter the credentials you have generated in the previous steps—refer to the information below for errors and troubleshooting.

### Webhooks

DX supports Azure DevOps webhooks ingestion to sync pull request data in real-time. This is recommended in order to ensure real-time data accuracy in DX.

You can enable webhooks via the [Azure DevOps API](https://learn.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/create?view=azure-devops-rest-7.1&tabs=HTTP), or through the UI.

#### API-based setup

Run the CURL command three times for each project where you want to enable webhooks—once each for git.pullrequest.created, git.pullrequest.updated, and git.pullrequest.merged:

```
curl --location 'https://dev.azure.com/${your_organization}/_apis/hooks/subscriptions?api-version=7.1' \
--header 'Authorization: Basic ${token}' \\
--data-raw '{
    "consumerActionId": "httpRequest",
    "consumerId": "webHooks",
    "consumerInputs": {
        "url": "${your_url}/webhooks/ado",
        "httpHeaders": "X-ADO-Signature:${webhook_token}" # Replace this token with webhooks secret from DX, found on the Connections admin page
    },
    "eventType": "git.pullrequest.created",
    "publisherId": "tfs",
    "publisherInputs": {
        "repository": "",
        "branch": "",
        "pullrequestCreatedBy": "",
        "pullrequestReviewersContains": "",
        "projectId": "${project_id}",
    },
    "resourceVersion": "1.0",
    "scope": 1
}'
```

#### UI-based setup

To enable webhooks via the UI:

1. Navigate to Project Settings > Service Hooks
2. Click the ”+” icon and choose Service "Webhooks" to add a new webhook.
3. Here's what your settings should look like:

![](https://docs.getdx.com/assets/images/connectors/ado/webhooks.png){class="max-w-xl mx-auto"}

## API reference

The table below lists the specific API endpoints that are used by DX.


| Endpoint | Documentation |
|---------------------------------------------------------------------------------------------------|-----------------------------|
| /graph/users | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users) |
| /projects | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/core/projects/list) |
| /projects/{projectId}/teams | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/core/teams/list) |
| /projects/{projectId}/teams/{teamId}/members | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/core/teams/get-team-members) |
| /wit/classificationnodes/iterations | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/classification-nodes) |
| /wit/workitemtypecategories?project={projectId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-item-type-categories) |
| /wit/workitemtypes?project={projectId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-item-types) |
| /wit/fields?project={projectId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/fields) |
| /wit/wiql | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/wiql) |
| /wit/workitemsbatch | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items/get-work-items-batch) |
| /wit/workitems?ids={workItemIds} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items) |
| /wit/workitems/{workItemId}/updates | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-item-updates) |
| /build/builds?project={projectId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds) |
| /build/builds/{buildId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/get) |
| /build/builds/{buildId}/timeline | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/build/timeline) |
| /release/releases?project={projectId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases) |
| /release/releases/{releaseId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/get) |
| /git/repositories?project={projectId} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories) |
| /git/repositories/{repoId}/pullrequests | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-requests) |
| /git/repositories/{repoId}/pullrequests/{id} | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-requests/get) |
| /git/repositories/{repoId}/pullrequests/{id}/iterations | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-iterations) |
| /git/repositories/{repoId}/pullrequests/{id}/iterations/{id}/changes | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-iteration-changes) |
| /git/repositories/{repoId}/pullrequests/{id}/commits | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-commits) |
| /git/repositories/{repoId}/pullrequests/{id}/threads | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-threads) |
| /git/repositories/{repoId}/pullrequests/{id}/workitems | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-work-items) |
| /git/repositories/{repositoryId}/commits | [Link](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/commits/get-commits) |


## Curl commands

When DX verifies an Azure DevOps connection, it checks specific endpoints to ensure proper access. If your connection is failing, you can test these endpoints directly using the curl commands below to troubleshoot the issue.

<div>
  <p class="mb-4 text-sm text-gray-700">Replace YOUR_ORGANIZATION and YOUR_PAT with your actual values before running these commands.</p>

  <h4>1. Test Project Access (Common for all connection types)</h4>
  <p>This verifies that your service account can access project information:</p>
  <div class="code-block-wrapper">
    <button class="copy-button" title="Copy to clipboard">
      <svg class="copy-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
      <svg class="check-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
    </button>
    <pre><code class="language-bash">curl -u :YOUR_PAT -H 'Accept: application/json' 'https://dev.azure.com/YOUR_ORGANIZATION/_apis/projects?api-version=7.0'</code></pre>
  </div>

  <h4>2. Test User Access (Common for all connection types)</h4>
  <p>This verifies that your service account can access user information:</p>
  <div class="code-block-wrapper">
    <button class="copy-button" title="Copy to clipboard">
      <svg class="copy-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
      <svg class="check-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
    </button>
    <pre><code class="language-bash">curl -u :YOUR_PAT -H 'Accept: application/json' 'https://dev.azure.com/YOUR_ORGANIZATION/_apis/graph/users?api-version=7.0'</code></pre>
  </div>

  <h4>3. Test Repositories (For ADO Repos connection)</h4>
  <p>Replace YOUR_PROJECT_ID with a valid project ID to verify repository access:</p>
  <div class="code-block-wrapper">
    <button class="copy-button" title="Copy to clipboard">
      <svg class="copy-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
      <svg class="check-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
    </button>
    <pre><code class="language-bash">curl -u :YOUR_PAT -H 'Accept: application/json' 'https://dev.azure.com/YOUR_ORGANIZATION/_apis/git/repositories?projectId=YOUR_PROJECT_ID&api-version=7.0'</code></pre>
  </div>

  <h4>4. Test Build Pipelines (For ADO Pipelines connection)</h4>
  <p>Replace YOUR_PROJECT_ID with a valid project ID to verify pipeline access:</p>
  <div class="code-block-wrapper">
    <button class="copy-button" title="Copy to clipboard">
      <svg class="copy-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
      <svg class="check-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
    </button>
    <pre><code class="language-bash">curl -u :YOUR_PAT -H 'Accept: application/json' 'https://dev.azure.com/YOUR_ORGANIZATION/_apis/build/builds?projectId=YOUR_PROJECT_ID&api-version=7.0'</code></pre>
  </div>

  <h4>5. Test Work Items (For ADO Boards connection)</h4>
  <p>This verifies that your service account can access work item types:</p>
  <div class="code-block-wrapper">
    <button class="copy-button" title="Copy to clipboard">
      <svg class="copy-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
      <svg class="check-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
    </button>
    <pre><code class="language-bash">curl -u :YOUR_PAT -H 'Accept: application/json' 'https://dev.azure.com/YOUR_ORGANIZATION/_apis/wit/workitemtypes?project=YOUR_PROJECT_ID&api-version=7.0'</code></pre>
  </div>

  <h4>6. Test Pull Request Commits (For ADO Pull Commits connection)</h4>
  <p>Replace YOUR_PROJECT_ID and YOUR_REPO_ID with valid IDs, and YOUR_PULL_REQUEST_ID with a valid pull request ID to verify pull request commits access:</p>
  <div class="code-block-wrapper">
    <button class="copy-button" title="Copy to clipboard">
      <svg class="copy-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
      <svg class="check-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
    </button>
    <pre><code class="language-bash">curl -u :YOUR_PAT -H 'Accept: application/json' 'https://dev.azure.com/YOUR_ORGANIZATION/_apis/git/repositories/YOUR_REPO_ID/pullRequests/YOUR_PULL_REQUEST_ID/commits?api-version=7.0'</code></pre>
  </div>

  <h4>7. Test Default branch Commits (For ADO Commits (Default branch) connection)</h4>
  <p>Replace YOUR_ORGANIZATION, YOUR_PROJECT_ID and YOUR_REPO_ID with valid IDs, to verify commits access:</p>
  <div class="code-block-wrapper">
    <button class="copy-button" title="Copy to clipboard">
      <svg class="copy-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
      <svg class="check-icon" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
    </button>
    <pre><code class="language-bash">curl -u :YOUR_PAT -H 'Accept: application/json' 'https://dev.azure.com/YOUR_ORGANIZATION/YOUR_PROJECT_ID/_apis/git/repositories/YOUR_REPO_ID/commits'</code></pre>
  </div>
</div>

If you receive a 401 Unauthorized error, your credentials are invalid. If you receive a 403 Forbidden error, your token doesn't have the required permissions. If you receive a 404 Not Found error or empty results, check that your organization name is correct.

**Note about Authentication**: The `-u :YOUR_PAT` flag uses curl's built-in basic authentication with an empty username and your Personal Access Token as the password. This automatically handles the Base64 encoding required for Azure DevOps authentication.

## Errors

The table below lists potential error codes when adding a connection in DX.


| Error | Description |
|------------------------|--------------------------------------------------------------------------|
| `invalid_credentials` | Your API credentials entered are not valid. |
| `invalid_permissions` | Your API token does not have the permissions required by DX. |
| `no_resources` | DX cannot access any projects or repositories. |


## Data Cloud API

Once the initial connection is created successfully, Azure DevOps credentials can be managed via the Data Cloud API.

- [credentials.create](https://docs.getdx.com/datacloudapi/methods/credentials.create/)
- [credentials.update](https://docs.getdx.com/datacloudapi/methods/credentials.update/)
- [credentials.info](https://docs.getdx.com/datacloudapi/methods/credentials.info/)
- [credentials.list](https://docs.getdx.com/datacloudapi/methods/credentials.list/)
- [credentials.delete](https://docs.getdx.com/datacloudapi/methods/credentials.delete/)

### Credential fields


| Field | Type | Description |
| ----- | ---- | ----------- |
| `secrets.personal_access_token` | `String` | An Azure DevOps Personal Access Token with the required scopes. |


```json
{
  "id": 456,
  "secrets": {
    "personal_access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}
```
---

## Sitemap

[Overview of all docs pages](/llms.txt)
