Azure DevOps Node.js API Client
The `azure-devops-node-api` package provides a robust and officially supported Node.js client for programmatically interacting with Azure DevOps Services and on-premises Team Foundation Server (TFS) REST APIs. It offers strongly typed interfaces for various services including Git, Build, Release, Work Items, and more, simplifying authentication and API calls compared to direct HTTP requests. The current stable version is 15.1.2, requiring Node.js >= 16.0.0. The library's release cadence is generally aligned with major Azure DevOps and TFS server updates, with significant version increments often indicating breaking changes tied to server compatibility and new features. Its key differentiator is providing a comprehensive, type-safe wrapper over the Azure DevOps REST APIs, making development more efficient and less error-prone.
Common errors
-
Error: TF400813: The resource cannot be found.
cause This error typically indicates that the requested resource (e.g., a project, repository, or build definition) does not exist, or the authenticated user does not have permission to access it within the specified organization or project.fixDouble-check the project name, repository ID, or other resource identifiers for typos. Ensure the PAT has sufficient permissions (e.g., 'Project and Team: Read', 'Code: Read'). Verify the organization URL is correct. -
Error: Failed to authenticate (401 Unauthorized)
cause The Personal Access Token (PAT) used for authentication is either incorrect, expired, revoked, or does not have the necessary scopes to perform the requested operation.fixGenerate a new PAT in Azure DevOps User Settings with the required scopes. Update the PAT in your application configuration. Ensure the organization URL is correct and accessible. -
TypeError: Cannot read properties of undefined (reading 'getBuilds')
cause This error occurs when attempting to call an API method (e.g., `getBuilds`) on an API client that has not been correctly initialized or retrieved from the `WebApi` connection.fixEnsure you have successfully called `connection.getBuildApi()` (or similar for other APIs) and stored its result in a variable before attempting to call methods on it. Add `await` if `getBuildApi()` is an async call. -
Error: getaddrinfo ENOTFOUND dev.azure.com
cause The Node.js environment could not resolve the hostname for the Azure DevOps organization URL. This is typically a network connectivity or DNS issue.fixVerify your internet connection and DNS settings. Double-check the Azure DevOps organization URL for typos. If behind a proxy, ensure Node.js is configured to use it (e.g., via `HTTPS_PROXY` environment variable).
Warnings
- breaking Major version updates (e.g., from v6.x to v15.x) frequently introduce breaking changes, primarily due to updates in the underlying Azure DevOps REST API and compatibility with specific TFS server versions. Always consult the official release notes and migration guides when upgrading.
- gotcha Authentication failures are common. Ensure your Personal Access Token (PAT) has the necessary scopes for the API calls you are making (e.g., 'Build: Read' for reading build data, 'Work Items: Read, Write' for modifying work items). PATs also have expiry dates.
- breaking The package maintains compatibility with specific minimum versions of TFS and Azure DevOps Server. Using a newer `azure-devops-node-api` version with an older, incompatible TFS instance will lead to runtime errors or missing functionalities. For example, `v6.6.2` supports TFS 2018 Update 2+, and earlier versions were tied to even older TFS releases.
- gotcha When migrating to ESM or using modern Node.js module systems, be aware of potential import issues. While `require()` generally works for older versions or CommonJS environments, `import` statements are preferred and sometimes required for newer Node.js versions and environments.
Install
-
npm install azure-devops-node-api -
yarn add azure-devops-node-api -
pnpm add azure-devops-node-api
Imports
- WebApi
const WebApi = require('azure-devops-node-api/WebApi');import { WebApi } from 'azure-devops-node-api/WebApi'; - getPersonalAccessTokenHandler
import { PersonalAccessTokenHandler } from 'azure-devops-node-api/handlers/pat';import { getPersonalAccessTokenHandler } from 'azure-devops-node-api/handlers/pat'; - BuildApi
import { IBuildApi } from 'azure-devops-node-api/BuildApi';import { BuildApi } from 'azure-devops-node-api/BuildApi'; - * as azdev
const azdev = require('azure-devops-node-api').default;import * as azdev from 'azure-devops-node-api';
Quickstart
import { WebApi } from 'azure-devops-node-api/WebApi';
import { getPersonalAccessTokenHandler } from 'azure-devops-node-api/handlers/pat';
import { BuildApi } from 'azure-devops-node-api/BuildApi';
async function listBuilds() {
const orgUrl = process.env.AZURE_DEVOPS_ORG_URL ?? 'https://dev.azure.com/your-organization';
const token = process.env.AZURE_DEVOPS_PAT ?? ''; // Ensure PAT has 'Build: Read' scope
const projectName = process.env.AZURE_DEVOPS_PROJECT_NAME ?? 'MyProject';
if (!token) {
console.error('AZURE_DEVOPS_PAT environment variable is not set.');
return;
}
try {
const authHandler = getPersonalAccessTokenHandler(token);
const connection = new WebApi(orgUrl, authHandler);
// Get the Build API client
const buildApi: BuildApi = await connection.getBuildApi();
// List recent builds for a specific project
console.log(`Fetching builds for project: ${projectName}...`);
const builds = await buildApi.getBuilds(projectName, undefined, undefined, undefined, undefined, undefined, 5); // Get top 5 builds
if (builds.length === 0) {
console.log('No builds found.');
return;
}
console.log(`Found ${builds.length} recent builds:`)
for (const build of builds) {
console.log(` - Build #${build.buildNumber}: ${build.status} - ${build.result ?? 'N/A'}`);
}
} catch (error: any) {
console.error('Error fetching builds:', error.message);
if (error.statusCode === 401) {
console.error('Check your PAT and organization URL. Ensure PAT has sufficient scopes.');
} else if (error.statusCode === 404) {
console.error('Project or organization URL not found.');
}
}
}
listBuilds();