This document provides detailed information about the most commonly used methods in the Azure DevOps Build API.
Retrieves a list of build definitions from a project.
async getDefinitions(
    project: string,
    name?: string,
    repositoryId?: string,
    repositoryType?: string,
    queryOrder?: BuildInterfaces.DefinitionQueryOrder,
    top?: number,
    continuationToken?: string,
    minMetricsTime?: Date,
    definitionIds?: number[],
    path?: string,
    builtAfter?: Date,
    notBuiltAfter?: Date,
    includeAllProperties?: boolean,
    includeLatestBuilds?: boolean,
    taskIdFilter?: string,
    processType?: number,
    yamlFilename?: string
): Promise<VSSInterfaces.PagedList<BuildInterfaces.BuildDefinitionReference>>
| Parameter | Type | Required | Description | 
|---|---|---|---|
| project | string | Yes | Project ID or project name | 
| name | string | No | Filters to definitions whose names match this pattern | 
| repositoryId | string | No | Filters to definitions that use this repository | 
| repositoryType | string | No | Filters to definitions that have a repository of this type | 
| queryOrder | BuildInterfaces.DefinitionQueryOrder | No | Indicates the order in which definitions should be returned | 
| top | number | No | The maximum number of definitions to return | 
| continuationToken | string | No | A continuation token for pagination | 
| minMetricsTime | Date | No | If specified, indicates the date from which metrics should be included | 
| definitionIds | number[] | No | A comma-delimited list of definition IDs to retrieve | 
| path | string | No | Filters to definitions under this folder path. Must be specified using backslashes (e.g., "\TeamA\MicroServices"). Use "\" for the root folder. | 
| builtAfter | Date | No | Filters to definitions that have builds after this date | 
| notBuiltAfter | Date | No | Filters to definitions that do not have builds after this date | 
| includeAllProperties | boolean | No | Whether to return the full definitions (true) or shallow representations (false, default) | 
| includeLatestBuilds | boolean | No | Whether to return the latest and latest completed builds for this definition | 
| taskIdFilter | string | No | Filters to definitions that use the specified task | 
| processType | number | No | Filters to definitions with the given process type | 
| yamlFilename | string | No | Filters to YAML definitions that match the given filename (requires includeAllProperties=true) | 
Returns a Promise that resolves to a paged list of BuildDefinitionReference objects. Each object contains:
import * as azdev from "azure-devops-node-api";
async function getBuildDefinitions() {
    // Setup connection
    const orgUrl = "https://dev.azure.com/yourorganization";
    const token = process.env.AZURE_DEVOPS_PAT; // Personal Access Token
    
    const authHandler = azdev.getPersonalAccessTokenHandler(token);
    const connection = new azdev.WebApi(orgUrl, authHandler);
    
    try {
        // Get Build API client
        const buildApi = await connection.getBuildApi();
        
        // Get build definitions
        const projectName = "YourProject";
        const definitions = await buildApi.getDefinitions(
            projectName,
            undefined, // name
            undefined, // repositoryId
            undefined, // repositoryType
            undefined, // queryOrder
            10,        // top - limit to 10 results
            undefined, // continuationToken
            undefined, // minMetricsTime
            undefined, // definitionIds
            undefined, // path
            undefined, // builtAfter
            undefined, // notBuiltAfter
            true,      // includeAllProperties
            true       // includeLatestBuilds
        );
        
        console.log(`Found ${definitions.length} build definitions`);
        
        // Display build definition details
        definitions.forEach(def => {
            console.log(`Definition: ${def.name} (ID: ${def.id})`);
            console.log(`  Path: ${def.path}`);
            console.log(`  Latest Build: ${def.latestBuild ? def.latestBuild.buildNumber : 'None'}`);
            console.log(`  Latest Status: ${def.latestBuild ? def.latestBuild.status : 'N/A'}`);
            console.log(`  Latest Result: ${def.latestBuild ? def.latestBuild.result : 'N/A'}`);
            console.log('---');
        });
        
        return {
            success: true,
            definitions
        };
    } catch (error) {
        console.error(`Error getting build definitions: ${error.message}`);
        return {
            success: false,
            error: error.message
        };
    }
}
// Get all build definitions in a project
const definitions = await buildApi.getDefinitions("MyProject");
console.log(`Found ${definitions.length} build definitions`);
definitions.forEach(def => {
    console.log(`Definition: ${def.name} (ID: ${def.id})`);
    console.log(`Type: ${def.type === BuildInterfaces.DefinitionType.Build ? "Build" : "Release"}`);
    if (def.latestBuild) {
        console.log(`Latest build: ${def.latestBuild.buildNumber}`);
    }
});
// Get build definitions in a specific folder
const folderPath = "\\TeamA\\MicroServices";
const definitionsInFolder = await buildApi.getDefinitions("MyProject", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, folderPath);
console.log(`Found ${definitionsInFolder.length} definitions in ${folderPath}`);
// Get build definitions in the root folder
const rootDefinitions = await buildApi.getDefinitions("MyProject", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "\\");
console.log(`Found ${rootDefinitions.length} definitions in the root folder`);
### Definition References vs. Full Definitions
An important distinction to understand is that the `getDefinitions` method returns `BuildDefinitionReference` objects by default, not complete definition objects with all properties. These references are lightweight objects containing basic information about the build definition.
To understand the difference:
1. **Build Definition Reference**: A lightweight representation that includes:
   - Basic properties (id, name, path, revision)
   - References to related entities (project, queue)
   - Latest build information (if requested with `includeLatestBuilds=true`)
   
2. **Full Build Definition**: A complete representation that includes everything in the reference plus:
   - All build steps/tasks
   - All variables and their values
   - Complete repository information
   - All triggers (continuous integration, scheduled, etc.)
   - Retention policy
   - Build options and demands
#### Getting Full Definition Details
To get the complete definition with all details, use the `getDefinition` (singular) method:
```typescript
async function getFullDefinitionDetails(definitionId: number) {
    // Setup connection and API client
    // ... (connection code) ...
    
    const buildApi = await connection.getBuildApi();
    
    // Get the full definition
    const projectName = "YourProject";
    try {
        const fullDefinition = await buildApi.getDefinition(
            projectName,
            definitionId,
            undefined, // revision (optional)
            undefined, // minMetricsTime (optional)
            undefined, // propertyFilters (optional)
            true       // includeLatestBuilds
        );
        
        console.log(`Definition: ${fullDefinition.name}`);
        
        // Access detailed properties only available in the full definition
        console.log(`Number of steps: ${fullDefinition.process?.phases[0]?.steps?.length || 0}`);
        console.log(`Number of variables: ${Object.keys(fullDefinition.variables || {}).length}`);
        console.log(`Continuous integration trigger enabled: ${fullDefinition.triggers?.some(t => t.triggerType === BuildInterfaces.DefinitionTriggerType.ContinuousIntegration)}`);
        
        return fullDefinition;
    } catch (error) {
        console.error(`Error retrieving definition: ${error.message}`);
        throw error;
    }
}
When working with build definitions:
getDefinitions when you need basic information about multiple definitionsincludeAllProperties=true with getDefinitions only when you need all details for multiple definitionsgetDefinition (singular) when you need complete details about a specific definitionRetrieves a specific build by ID.
async getBuild(
    project: string,
    buildId: number,
    propertyFilters?: string
): Promise<BuildInterfaces.Build>
| Parameter | Type | Required | Description | 
|---|---|---|---|
| project | string | Yes | Project ID or project name | 
| buildId | number | Yes | The ID of the build to retrieve | 
| propertyFilters | string | No | A comma-delimited list of properties to include in the result | 
Returns a Promise that resolves to a Build object, which contains:
import * as azdev from "azure-devops-node-api";
async function getBuildDetails(buildId: number) {
    // Setup connection
    const orgUrl = "https://dev.azure.com/yourorganization";
    const token = process.env.AZURE_DEVOPS_PAT; // Personal Access Token
    
    const authHandler = azdev.getPersonalAccessTokenHandler(token);
    const connection = new azdev.WebApi(orgUrl, authHandler);
    
    // Get Build API client
    const buildApi = await connection.getBuildApi();
    
    // Get build details
    const projectName = "YourProject";
    try {
        const build = await buildApi.getBuild(projectName, buildId);
        
        console.log(`Build ${build.buildNumber} (ID: ${build.id})`);
        console.log(`Status: ${getBuildStatusText(build.status)}`);
        console.log(`Result: ${getBuildResultText(build.result)}`);
        console.log(`Started: ${build.startTime}`);
        console.log(`Finished: ${build.finishTime}`);
        console.log(`Requested by: ${build.requestedBy?.displayName}`);
        console.log(`Source branch: ${build.sourceBranch}`);
        console.log(`Source version: ${build.sourceVersion}`);
        
        return build;
    } catch (error) {
        console.error(`Error retrieving build ${buildId}: ${error.message}`);
        throw error;
    }
}
// Helper functions to convert enum values to readable text
function getBuildStatusText(status: number): string {
    const statusMap = {
        0: "None",
        1: "In Progress",
        2: "Completed",
        4: "Cancelling",
        8: "Postponed",
        32: "Not Started"
    };
    return statusMap[status] || `Unknown (${status})`;
}
function getBuildResultText(result: number): string {
    const resultMap = {
        0: "None",
        2: "Succeeded",
        4: "Partially Succeeded",
        8: "Failed",
        32: "Canceled"
    };
    return resultMap[result] || `Unknown (${result})`;
}
Retrieves a list of builds based on various filter criteria.
async getBuilds(
    project: string,
    definitions?: number[],
    queues?: number[],
    buildNumber?: string,
    minTime?: Date,
    maxTime?: Date,
    requestedFor?: string,
    reasonFilter?: BuildInterfaces.BuildReason,
    statusFilter?: BuildInterfaces.BuildStatus,
    resultFilter?: BuildInterfaces.BuildResult,
    tagFilters?: string[],
    properties?: string[],
    top?: number,
    continuationToken?: string,
    maxBuildsPerDefinition?: number,
    deletedFilter?: BuildInterfaces.QueryDeletedOption,
    queryOrder?: BuildInterfaces.BuildQueryOrder,
    branchName?: string,
    buildIds?: number[],
    repositoryId?: string,
    repositoryType?: string
): Promise<VSSInterfaces.PagedList<BuildInterfaces.Build>>
| Parameter | Type | Required | Description | 
|---|---|---|---|
| project | string | Yes | Project ID or project name | 
| definitions | number[] | No | A list of definition IDs to filter by | 
| queues | number[] | No | A list of queue IDs to filter by | 
| buildNumber | string | No | Filter by build number (append * for prefix search) | 
| minTime | Date | No | Filter to builds after this date | 
| maxTime | Date | No | Filter to builds before this date | 
| requestedFor | string | No | Filter to builds requested by this user | 
| reasonFilter | BuildInterfaces.BuildReason | No | Filter by the reason the build was created | 
| statusFilter | BuildInterfaces.BuildStatus | No | Filter by build status | 
| resultFilter | BuildInterfaces.BuildResult | No | Filter by build result | 
| tagFilters | string[] | No | Filter to builds with these tags | 
| properties | string[] | No | A list of properties to retrieve | 
| top | number | No | Maximum number of builds to return | 
| continuationToken | string | No | Continuation token for pagination | 
| maxBuildsPerDefinition | number | No | Maximum number of builds to return per definition | 
| deletedFilter | BuildInterfaces.QueryDeletedOption | No | Whether to include deleted builds | 
| queryOrder | BuildInterfaces.BuildQueryOrder | No | The order in which to return builds | 
| branchName | string | No | Filter to builds from this branch | 
| buildIds | number[] | No | A list of build IDs to retrieve | 
| repositoryId | string | No | Filter to builds from this repository | 
| repositoryType | string | No | Filter to builds from repositories of this type | 
Returns a Promise that resolves to a paged list of Build objects. See the getBuild method for details on the Build object properties.
import * as azdev from "azure-devops-node-api";
import * as BuildInterfaces from "azure-devops-node-api/interfaces/BuildInterfaces";
async function getRecentBuilds() {
    // Setup connection
    const orgUrl = "https://dev.azure.com/yourorganization";
    const token = process.env.AZURE_DEVOPS_PAT; // Personal Access Token
    
    const authHandler = azdev.getPersonalAccessTokenHandler(token);
    const connection = new azdev.WebApi(orgUrl, authHandler);
    
    // Get Build API client
    const buildApi = await connection.getBuildApi();
    
    // Get recent builds
    const projectName = "YourProject";
    const builds = await buildApi.getBuilds(
        projectName,
        undefined,                                  // definitions
        undefined,                                  // queues
        undefined,                                  // buildNumber
        new Date(Date.now() - 7 * 24 * 60 * 60000), // minTime (7 days ago)
        undefined,                                  // maxTime
        undefined,                                  // requestedFor
        undefined,                                  // reasonFilter
        BuildInterfaces.BuildStatus.Completed,      // statusFilter
        undefined,                                  // resultFilter
        undefined,                                  // tagFilters
        undefined,                                  // properties
        10,                                         // top
        undefined,                                  // continuationToken
        undefined,                                  // maxBuildsPerDefinition
        undefined,                                  // deletedFilter
        BuildInterfaces.BuildQueryOrder.FinishTimeDescending // queryOrder
    );
    
    console.log(`Found ${builds.length} builds in the last 7 days`);
    
    // Display build details
    builds.forEach(build => {
        console.log(`Build ${build.buildNumber} (ID: ${build.id})`);
        console.log(`  Definition: ${build.definition.name}`);
        console.log(`  Status: ${getBuildStatusText(build.status)}`);
        console.log(`  Result: ${getBuildResultText(build.result)}`);
        console.log(`  Started: ${build.startTime}`);
        console.log(`  Finished: ${build.finishTime}`);
        console.log(`  Branch: ${build.sourceBranch}`);
        console.log('---');
    });
}
// Helper functions to convert enum values to readable text
function getBuildStatusText(status: number): string {
    const statusMap = {
        0: "None",
        1: "In Progress",
        2: "Completed",
        4: "Cancelling",
        8: "Postponed",
        32: "Not Started"
    };
    return statusMap[status] || `Unknown (${status})`;
}
function getBuildResultText(result: number): string {
    const resultMap = {
        0: "None",
        2: "Succeeded",
        4: "Partially Succeeded",
        8: "Failed",
        32: "Canceled"
    };
    return resultMap[result] || `Unknown (${result})`;
}
Queues a new build for a specified definition.
async queueBuild(
    build: BuildInterfaces.Build,
    project: string,
    ignoreWarnings?: boolean,
    checkInTicket?: string,
    sourceBuildId?: number,
    definitionId?: number
): Promise<BuildInterfaces.Build>
| Parameter | Type | Required | Description | 
|---|---|---|---|
| build | BuildInterfaces.Build | Yes | The build to queue | 
| project | string | Yes | Project ID or project name | 
| ignoreWarnings | boolean | No | Whether to ignore warnings | 
| checkInTicket | string | No | The check-in ticket | 
| sourceBuildId | number | No | The source build ID | 
| definitionId | number | No | Optional definition ID to queue a build without a body (ignored if there's a valid body) | 
Returns a Promise that resolves to a Build object representing the queued build. See the getBuild method for details on the Build object properties.
import * as azdev from "azure-devops-node-api";
import * as BuildInterfaces from "azure-devops-node-api/interfaces/BuildInterfaces";
async function queueNewBuild(definitionId: number, sourceBranch: string) {
    // Setup connection
    const orgUrl = "https://dev.azure.com/yourorganization";
    const token = process.env.AZURE_DEVOPS_PAT; // Personal Access Token
    
    const authHandler = azdev.getPersonalAccessTokenHandler(token);
    const connection = new azdev.WebApi(orgUrl, authHandler);
    
    // Get Build API client
    const buildApi = await connection.getBuildApi();
    
    // Create build object
    const build: BuildInterfaces.Build = {
        definition: {
            id: definitionId
        },
        sourceBranch: sourceBranch,
        reason: BuildInterfaces.BuildReason.Manual,
        priority: BuildInterfaces.BuildPriority.Normal
    };
    
    // Queue the build
    const projectName = "YourProject";
    try {
        const queuedBuild = await buildApi.queueBuild(build, projectName);
        
        console.log(`Build queued successfully!`);
        console.log(`Build ID: ${queuedBuild.id}`);
        console.log(`Build Number: ${queuedBuild.buildNumber}`);
        console.log(`Status: ${getBuildStatusText(queuedBuild.status)}`);
        console.log(`URL: ${queuedBuild._links.web.href}`);
        
        return queuedBuild;
    } catch (error) {
        console.error(`Error queuing build: ${error.message}`);
        throw error;
    }
}
// Helper function to convert enum values to readable text
function getBuildStatusText(status: number): string {
    const statusMap = {
        0: "None",
        1: "In Progress",
        2: "Completed",
        4: "Cancelling",
        8: "Postponed",
        32: "Not Started"
    };
    return statusMap[status] || `Unknown (${status})`;
}
### Setting Build Variables
To set variables for a build, use the `parameters` property of the build object. The `parameters` property takes a stringified JSON object containing the variable names and values:
```typescript
import * as azdev from "azure-devops-node-api";
import * as BuildInterfaces from "azure-devops-node-api/interfaces/BuildInterfaces";
async function queueBuildWithVariables(definitionId: number, sourceBranch: string) {
    // Setup connection
    const orgUrl = "https://dev.azure.com/yourorganization";
    const token = process.env.AZURE_DEVOPS_PAT; // Personal Access Token
    
    const authHandler = azdev.getPersonalAccessTokenHandler(token);
    const connection = new azdev.WebApi(orgUrl, authHandler);
    
    // Get Build API client
    const buildApi = await connection.getBuildApi();
    
    // Define variables to pass to the build
    const buildVariables = {
        "DEPLOY_ENVIRONMENT": "Production",
        "ENABLE_DEBUG": "false",
        "VERSION": "1.2.3",
        "RUN_INTEGRATION_TESTS": "true"
    };
    
    // Create build object with variables
    const build: BuildInterfaces.Build = {
        definition: {
            id: definitionId
        },
        sourceBranch: sourceBranch,
        reason: BuildInterfaces.BuildReason.Manual,
        priority: BuildInterfaces.BuildPriority.Normal,
        parameters: JSON.stringify(buildVariables)
    };
    
    // Queue the build
    const projectName = "YourProject";
    try {
        const queuedBuild = await buildApi.queueBuild(build, projectName);
        
        console.log(`Build queued successfully with custom variables!`);
        console.log(`Build ID: ${queuedBuild.id}`);
        console.log(`Build Number: ${queuedBuild.buildNumber}`);
        
        return queuedBuild;
    } catch (error) {
        console.error(`Error queuing build: ${error.message}`);
        throw error;
    }
}
Note: Only variables that are defined in the build definition can be set when queuing a build. Setting undefined variables will have no effect.
When queueing builds, be aware that branch policies can impact whether a build can be successfully queued:
Builds for Protected Branches: If you try to queue a build for a branch that has branch policies enabled (like requiring a pull request), the build may be rejected depending on your permissions and the specific policies.
Pull Request Validation Builds: Builds triggered as part of a pull request validation policy behave differently than manually queued builds. They often have different security contexts and variable values.
Build Validation Policy: If a branch has a build validation policy, you may need to queue builds through a pull request rather than directly against the branch.
Example of queueing a build for a feature branch that will eventually be merged into a protected branch:
async function queueFeatureBranchBuild(definitionId: number) {
    // Setup connection and API client
    // ... (connection code) ...
    
    const buildApi = await connection.getBuildApi();
    
    // Use feature branch instead of protected branch
    const build: BuildInterfaces.Build = {
        definition: {
            id: definitionId
        },
        sourceBranch: "refs/heads/feature/my-feature", // Use feature branch
        reason: BuildInterfaces.BuildReason.Manual
    };
    
    try {
        const queuedBuild = await buildApi.queueBuild(build, "YourProject");
        console.log(`Build queued successfully on feature branch`);
        return queuedBuild;
    } catch (error) {
        if (error.message && error.message.includes("branch policy")) {
            console.error("Failed due to branch policy. Try using a feature branch instead.");
        } else {
            console.error(`Error queueing build: ${error.message}`);
        }
        throw error;
    }
}
Retrieves the logs for a specific build.
async getBuildLogs(
    project: string,
    buildId: number
): Promise<BuildInterfaces.BuildLog[]>
| Parameter | Type | Required | Description | 
|---|---|---|---|
| project | string | Yes | Project ID or project name | 
| buildId | number | Yes | The ID of the build | 
Returns a Promise that resolves to an array of BuildLog objects. Each BuildLog object contains:
import * as azdev from "azure-devops-node-api";
async function getBuildLogsAndContent(buildId: number) {
    // Setup connection
    const orgUrl = "https://dev.azure.com/yourorganization";
    const token = process.env.AZURE_DEVOPS_PAT; // Personal Access Token
    
    const authHandler = azdev.getPersonalAccessTokenHandler(token);
    const connection = new azdev.WebApi(orgUrl, authHandler);
    
    // Get Build API client
    const buildApi = await connection.getBuildApi();
    
    // Get build logs
    const projectName = "YourProject";
    try {
        const logs = await buildApi.getBuildLogs(projectName, buildId);
        
        console.log(`Found ${logs.length} log files for build ${buildId}`);
        
        // Display log metadata
        logs.forEach(log => {
            console.log(`Log #${log.id}: ${log.type}`);
            console.log(`  Created: ${log.createdOn}`);
            console.log(`  Lines: ${log.lineCount}`);
            console.log(`  URL: ${log.url}`);
        });
        
        // Get content for the first log
        if (logs.length > 0) {
            const logContent = await buildApi.getBuildLogLines(projectName, buildId, logs[0].id);
            console.log("\nSample log content (first 10 lines):");
            logContent.slice(0, 10).forEach((line, index) => {
                console.log(`${index + 1}: ${line}`);
            });
        }
        
        return logs;
    } catch (error) {
        console.error(`Error retrieving build logs: ${error.message}`);
        throw error;
    }
}
### Understanding Log Structure
The logs returned by `getBuildLogs` represent metadata about the available logs, not the actual log content. To get the log content, you need to use the `getBuildLogLines` method:
```typescript
async getBuildLogLines(
    project: string,
    buildId: number,
    logId: number,
    startLine?: number,
    endLine?: number
): Promise<string[]>
Build logs in Azure DevOps follow a structured format with different types:
Log content often contains ANSI color codes and formatting. When displaying logs, you might want to:
Strip ANSI Color Codes:
function stripAnsiCodes(text: string): string {
    return text.replace(/\u001b\[\d+m/g, '');
}
Parse Structured Data:
function extractJsonFromLog(logLines: string[]): any[] {
    const results = [];
    for (const line of logLines) {
        // Look for lines with JSON objects (often wrapped in special markers)
        if (line.includes('##[json]')) {
            try {
                const jsonStr = line.substring(line.indexOf('##[json]') + 8);
                results.push(JSON.parse(jsonStr));
            } catch (e) {
                // Handle parsing errors
            }
        }
    }
    return results;
}
Search for Specific Patterns:
function findErrorsInLog(logLines: string[]): string[] {
    return logLines.filter(line => 
        line.toLowerCase().includes('error') || 
        line.includes('##[error]'));
}
For builds with large logs, use the startLine and endLine parameters of getBuildLogLines to retrieve logs in chunks:
// Get logs in chunks of 1000 lines
async function getFullLogInChunks(projectName: string, buildId: number, logId: number) {
    const chunkSize = 1000;
    let allLines: string[] = [];
    let startLine = 0;
    let hasMoreLines = true;
    
    while (hasMoreLines) {
        const endLine = startLine + chunkSize - 1;
        const lines = await buildApi.getBuildLogLines(projectName, buildId, logId, startLine, endLine);
        
        allLines = allLines.concat(lines);
        
        if (lines.length < chunkSize) {
            hasMoreLines = false;
        } else {
            startLine += chunkSize;
        }
    }
    
    return allLines;
}
In addition to the top 5 methods, these related methods are also useful when working with builds: