CircleCI API Client
The `circle-client` package provides a JavaScript and TypeScript client for interacting with the CircleCI v2 API. It allows developers to programmatically manage CI/CD pipelines, retrieve workflow and job insights, manage contexts and environment variables, and access user and project details. Currently at version `0.2.4`, the library is in a pre-1.0 development phase, which implies that minor versions may introduce breaking changes. It ships with comprehensive TypeScript definitions, offering a strongly-typed interface for API interactions, which significantly enhances developer experience and reduces common API-related errors. Key differentiators include its direct mapping of CircleCI v2 API endpoints to client methods, simplified handling of paginated results through a `Paged<T>` object, and a focus on abstracting the underlying HTTP request complexities, making it easier to integrate CircleCI operations into Node.js applications.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` syntax in a pure ESM or ES Module-aware Node.js environment where `circle-client` is treated as an ESM module.fixUpdate your import statements to use ES Module syntax: `import CircleCI from 'circle-client';`. Ensure your `package.json` specifies `"type": "module"` if you are running pure ESM in Node.js, or use a transpiler like Babel or TypeScript. -
TypeError: Cannot read properties of undefined (reading 'name') or similar for API response data
cause Incorrectly handling the structure of paginated API responses or accessing properties on potentially undefined objects.fixRemember that `list` methods return a `Paged<T>` object; access results via `response.items`. Always add optional chaining (`?.`) or null checks (`if (item)`) when accessing properties of API response objects, as certain fields might be optional or absent. -
Error: Invalid project slug format. Expected an array like ['vcs', 'owner', 'repo']
cause Providing the `slug` option in the client constructor or a method as a single string (e.g., 'github/owner/repo') instead of the required array format.fixConvert your project slug string into the specified array format: `slug: ['github', 'owner', 'repo']`.
Warnings
- gotcha As a pre-1.0 release (`0.2.4`), any minor version increment (e.g., `0.2.x` to `0.3.0`) may introduce breaking changes without strictly adhering to semantic versioning until a stable 1.0 release.
- deprecated Certain API endpoints, such as those related to 'User' and 'Job' details, are marked as 'Preview' by CircleCI itself. These endpoints may change or be removed without prior warning, as indicated in the CircleCI API documentation.
- gotcha All methods beginning with `list` (e.g., `listContexts`, `listProjectPipelines`) return a `Paged<T>` object, not directly an array of items. Developers must access the `items` property for results and check `next_page_token` for pagination.
- gotcha CircleCI API Tokens grant extensive permissions. Exposing them in client-side code, checking them into version control, or using them insecurely can lead to unauthorized access to your CircleCI projects.
Install
-
npm install circle-client -
yarn add circle-client -
pnpm add circle-client
Imports
- CircleCI
const CircleCI = require('circle-client');import CircleCI from 'circle-client';
- All Types
import CircleCI, { Paged, Workflow, Pipeline } from 'circle-client'; - Configuration options
const client = new CircleCI(token, 'github/owner/repo');
import CircleCI from 'circle-client'; const client = new CircleCI(token, { slug: ['github', 'owner', 'repo'], branch: 'main' });
Quickstart
import CircleCI from 'circle-client';
// Get your CircleCI API token from https://app.circleci.com/settings/user/tokens
const CIRCLECI_API_TOKEN = process.env.CIRCLECI_API_TOKEN ?? 'YOUR_SECRET_TOKEN_HERE';
if (CIRCLECI_API_TOKEN === 'YOUR_SECRET_TOKEN_HERE') {
console.warn('Please set the CIRCLECI_API_TOKEN environment variable or replace the placeholder.');
}
async function runExample() {
try {
const client = new CircleCI(CIRCLECI_API_TOKEN, {
slug: ['github', 'jodyheavener', 'circle-client'], // Replace with your actual project slug
branch: 'main',
});
console.log('Fetching current user details...');
const me = await client.getMe();
console.log('Logged in as:', me.name);
console.log('Listing recent pipelines for the project...');
const pipelinesPage = await client.listProjectPipelines({
projectSlug: ['github', 'jodyheavener', 'circle-client'] // Required for this method
});
console.log(`Found ${pipelinesPage.items.length} pipelines. Latest:`, pipelinesPage.items[0]?.id);
if (pipelinesPage.next_page_token) {
console.log('More pipelines available. Next page token:', pipelinesPage.next_page_token);
}
} catch (error) {
console.error('An error occurred:', error instanceof Error ? error.message : String(error));
}
}
runExample();