or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

additional-resources.mdcicd.mdclient-configuration.mdgroups.mdindex.mdissues.mdmerge-requests.mdpackage-registries.mdprojects.mdrepository-management.mdusers.md
tile.json

index.mddocs/

@gitbeaker/rest

A comprehensive, typed GitLab API client that works universally across browsers, Node.js, and Deno platforms, offering complete coverage of GitLab's REST API with over 195 resource endpoints. The library features extensive TypeScript declarations for type safety, flexible authentication options, advanced pagination support, customizable rate limiting, and comprehensive error handling.

Package Information

  • Package Name: @gitbeaker/rest
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @gitbeaker/rest
  • Minimum Node.js Version: 18.20.0
  • Platforms: Node.js, Browsers, Deno, Cloudflare Workers

Quick Start

Essential Imports

// Primary client class
import { Gitlab } from '@gitbeaker/rest';

// Individual resource classes (for tree-shaking)
import {
  Projects,
  Issues,
  MergeRequests,
  Users,
  Groups,
  Pipelines,
  Jobs,
  Branches,
  Commits,
  RepositoryFiles
} from '@gitbeaker/rest';

// Access level constants
import { AccessLevel } from '@gitbeaker/rest';

// Error types for error handling
import {
  GitbeakerRequestError,
  GitbeakerTimeoutError,
  GitbeakerRetryError
} from '@gitbeaker/rest';

Basic Client Initialization

import { Gitlab } from '@gitbeaker/rest';

// Standard initialization with personal access token
const api = new Gitlab({
  host: 'https://gitlab.com', // Can be self-hosted URL
  token: process.env.GITLAB_TOKEN // Personal access token
});

// Self-hosted GitLab instance
const selfHostedApi = new Gitlab({
  host: 'https://gitlab.mycompany.com',
  token: process.env.GITLAB_TOKEN
});

// CI/CD job context (using job token)
const ciApi = new Gitlab({
  host: process.env.CI_SERVER_URL,
  jobToken: process.env.CI_JOB_TOKEN
});

// OAuth token authentication
const oauthApi = new Gitlab({
  host: 'https://gitlab.com',
  oauthToken: process.env.OAUTH_TOKEN
});

// Dynamic token retrieval (async function)
const dynamicApi = new Gitlab({
  host: 'https://gitlab.com',
  token: async () => await getTokenFromVault()
});

Most Common Operations

// Get all user's projects
const myProjects = await api.Projects.all({ membership: true });

// Get specific project details
const project = await api.Projects.show(projectId);

// List open issues in a project
const issues = await api.Issues.all({
  projectId,
  state: 'opened'
});

// Create a new issue
const newIssue = await api.Issues.create(
  projectId,
  'Bug: Login not working',
  {
    description: 'Users cannot log in with SSO',
    labels: 'bug,priority::high',
    assigneeIds: [userId]
  }
);

// List open merge requests
const mrs = await api.MergeRequests.all({
  projectId,
  state: 'opened'
});

// Create a merge request
const mr = await api.MergeRequests.create(
  projectId,
  'feature-branch',
  'main',
  'Add user authentication',
  {
    description: 'Implements JWT-based authentication',
    assigneeIds: [userId],
    removeSourceBranch: true
  }
);

// Get file content
const fileContent = await api.RepositoryFiles.showRaw(
  projectId,
  'src/config.json',
  'main'
);

// Create a commit with multiple file operations
await api.Commits.create(
  projectId,
  'main',
  'Update configuration',
  [
    {
      action: 'update',
      filePath: 'config/settings.json',
      content: JSON.stringify({ key: 'value' })
    },
    {
      action: 'create',
      filePath: 'src/new-file.ts',
      content: 'export const foo = "bar";'
    }
  ]
);

// List pipeline jobs
const jobs = await api.Jobs.all(projectId, {
  pipelineId,
  scope: 'failed'
});

// Retry a failed job
await api.Jobs.retry(projectId, jobId);

Core Imports

import { Gitlab } from '@gitbeaker/rest';

For CommonJS:

const { Gitlab } = require('@gitbeaker/rest');

Import specific resources:

import {
  Projects,
  Issues,
  MergeRequests,
  Users,
  Groups,
  AccessLevel
} from '@gitbeaker/rest';

Import error types:

import {
  GitbeakerRequestError,
  GitbeakerTimeoutError,
  GitbeakerRetryError
} from '@gitbeaker/rest';

Architecture and Design

The @gitbeaker/rest package is built around several key components:

  • Gitlab Class: Main entry point that aggregates all resource classes
  • Resource Classes: 195+ specialized classes for different GitLab API areas (Projects, Issues, Users, etc.)
  • Requester: Built-in fetch-based HTTP client with automatic retries and rate limiting
  • Type System: Full TypeScript integration with comprehensive schemas for all API responses
  • Error Handling: Structured error types with request/response context
  • Authentication: Flexible auth supporting personal tokens, OAuth tokens, and job tokens
  • Pagination: Both offset-based and keyset-based pagination with auto-fetching support

Capabilities

Client Configuration

Initialize and configure the GitLab API client with authentication, host settings, rate limiting, and advanced options.

class Gitlab<C extends boolean = false> {
  constructor(options: GitlabOptions<C>);
}

type GitlabOptions<C extends boolean = false> = {
  // Host configuration
  host?: string; // Default: 'https://gitlab.com'
  prefixUrl?: string;

  // Authentication (one required)
  token?: string | (() => Promise<string>);
  oauthToken?: string | (() => Promise<string>);
  jobToken?: string | (() => Promise<string>);

  // Behavior configuration
  camelize?: C;
  queryTimeout?: number | null; // Default: 300000 (5 minutes)
  sudo?: string | number;

  // Rate limiting
  rateLimits?: RateLimitOptions;
  rateLimitDuration?: number; // Default: 60 seconds

  // Advanced options
  profileToken?: string;
  profileMode?: 'execution' | 'memory';
  agent?: Agent; // Node.js HTTP agent
};

Client Configuration

Projects

Comprehensive project management including CRUD operations, repository management, settings, members, and webhooks. The Projects resource is the foundation for most GitLab operations.

class Projects<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'keyset'>(
    options?: AllProjectsOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema[], C, E, P>>;

  show<E extends boolean = false>(
    projectId: string | number,
    options?: ShowProjectOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;

  create<E extends boolean = false>(
    options: CreateProjectOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;

  edit<E extends boolean = false>(
    projectId: string | number,
    options?: EditProjectOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;

  remove<E extends boolean = false>(
    projectId: string | number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;

  fork<E extends boolean = false>(
    projectId: string | number,
    options?: ForkProjectOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;

  share<E extends boolean = false>(
    projectId: string | number,
    groupId: number,
    groupAccess: number,
    options?: ShareProjectOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;

  star<E extends boolean = false>(
    projectId: string | number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;

  unstar<E extends boolean = false>(
    projectId: string | number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;

  archive<E extends boolean = false>(
    projectId: string | number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;

  unarchive<E extends boolean = false>(
    projectId: string | number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<ProjectSchema, C, E, void>>;
}

Projects

Groups

Group management including creation, member management, subgroups, epics (Premium/Ultimate), and group-level settings.

class Groups<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'keyset'>(
    options?: AllGroupsOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<GroupSchema[], C, E, P>>;

  show<E extends boolean = false>(
    groupId: string | number,
    options?: ShowGroupOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<GroupSchema, C, E, void>>;

  create<E extends boolean = false>(
    name: string,
    path: string,
    options?: CreateGroupOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<GroupSchema, C, E, void>>;

  edit<E extends boolean = false>(
    groupId: string | number,
    options?: EditGroupOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<GroupSchema, C, E, void>>;

  remove<E extends boolean = false>(
    groupId: string | number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;
}

Groups

Issues

Issue tracking including creation, editing, comments, labels, milestones, time tracking, and relationships.

class Issues<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'offset'>(
    options?: AllIssuesOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<IssueSchema[], C, E, P>>;

  show<E extends boolean = false>(
    projectId: string | number,
    issueIid: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<IssueSchema, C, E, void>>;

  create<E extends boolean = false>(
    projectId: string | number,
    title: string,
    options?: CreateIssueOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<IssueSchema, C, E, void>>;

  edit<E extends boolean = false>(
    projectId: string | number,
    issueIid: number,
    options?: EditIssueOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<IssueSchema, C, E, void>>;

  remove<E extends boolean = false>(
    projectId: string | number,
    issueIid: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;

  addSpentTime<E extends boolean = false>(
    projectId: string | number,
    issueIid: number,
    duration: string,
    options?: { summary?: string } & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<TimeStatsSchema, C, E, void>>;

  addTimeEstimate<E extends boolean = false>(
    projectId: string | number,
    issueIid: number,
    duration: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<TimeStatsSchema, C, E, void>>;
}

Issues

Merge Requests

Merge request management including creation, approval, merging, discussions, and pipeline integration.

class MergeRequests<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'offset'>(
    options?: AllMergeRequestsOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<MergeRequestSchema[], C, E, P>>;

  show<E extends boolean = false>(
    projectId: string | number,
    mergerequestIid: number,
    options?: ShowMergeRequestOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<MergeRequestSchema, C, E, void>>;

  create<E extends boolean = false>(
    projectId: string | number,
    sourceBranch: string,
    targetBranch: string,
    title: string,
    options?: CreateMergeRequestOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<MergeRequestSchema, C, E, void>>;

  edit<E extends boolean = false>(
    projectId: string | number,
    mergerequestIid: number,
    options?: EditMergeRequestOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<MergeRequestSchema, C, E, void>>;

  merge<E extends boolean = false>(
    projectId: string | number,
    mergerequestIid: number,
    options?: MergeMergeRequestOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<MergeRequestSchema, C, E, void>>;
}

Merge Requests

CI/CD

Comprehensive CI/CD operations including pipelines, jobs, runners, variables, schedules, and artifacts management.

class Pipelines<C extends boolean = false> {
  all<E extends boolean = false>(
    projectId: string | number,
    options?: AllPipelinesOptions & PaginationRequestOptions<'offset'> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<PipelineSchema[], C, E, 'offset'>>;

  show<E extends boolean = false>(
    projectId: string | number,
    pipelineId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<PipelineSchema, C, E, void>>;

  create<E extends boolean = false>(
    projectId: string | number,
    ref: string,
    options?: CreatePipelineOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<PipelineSchema, C, E, void>>;

  retry<E extends boolean = false>(
    projectId: string | number,
    pipelineId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<PipelineSchema, C, E, void>>;

  cancel<E extends boolean = false>(
    projectId: string | number,
    pipelineId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<PipelineSchema, C, E, void>>;
}

class Jobs<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'offset'>(
    projectId: string | number,
    options?: AllJobsOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<JobSchema[], C, E, P>>;

  show<E extends boolean = false>(
    projectId: string | number,
    jobId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<JobSchema, C, E, void>>;

  showLog<E extends boolean = false>(
    projectId: string | number,
    jobId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<string, C, E, void>>;

  retry<E extends boolean = false>(
    projectId: string | number,
    jobId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<JobSchema, C, E, void>>;

  cancel<E extends boolean = false>(
    projectId: string | number,
    jobId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<JobSchema, C, E, void>>;

  play<E extends boolean = false>(
    projectId: string | number,
    jobId: number,
    options?: PlayJobOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<JobSchema, C, E, void>>;

  erase<E extends boolean = false>(
    projectId: string | number,
    jobId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<JobSchema, C, E, void>>;
}

CI/CD

Repository Management

Repository operations including branches, tags, commits, files, and merge operations.

class Branches<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'offset'>(
    projectId: string | number,
    options?: AllBranchesOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<BranchSchema[], C, E, P>>;

  show<E extends boolean = false>(
    projectId: string | number,
    branchName: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<BranchSchema, C, E, void>>;

  create<E extends boolean = false>(
    projectId: string | number,
    branchName: string,
    ref: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<BranchSchema, C, E, void>>;

  remove<E extends boolean = false>(
    projectId: string | number,
    branchName: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;
}

class Commits<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'offset'>(
    projectId: string | number,
    options?: AllCommitsOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<CommitSchema[], C, E, P>>;

  show<E extends boolean = false>(
    projectId: string | number,
    sha: string,
    options?: ShowCommitOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<CommitSchema, C, E, void>>;

  create<E extends boolean = false>(
    projectId: string | number,
    branch: string,
    commitMessage: string,
    actions: CommitAction[],
    options?: CreateCommitOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<CommitSchema, C, E, void>>;
}

class RepositoryFiles<C extends boolean = false> {
  show<E extends boolean = false>(
    projectId: string | number,
    filePath: string,
    ref: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<RepositoryFileSchema, C, E, void>>;

  showRaw<E extends boolean = false>(
    projectId: string | number,
    filePath: string,
    ref: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<string, C, E, void>>;

  create<E extends boolean = false>(
    projectId: string | number,
    filePath: string,
    branch: string,
    content: string,
    commitMessage: string,
    options?: CreateRepositoryFileOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<RepositoryFileSchema, C, E, void>>;

  edit<E extends boolean = false>(
    projectId: string | number,
    filePath: string,
    branch: string,
    content: string,
    commitMessage: string,
    options?: EditRepositoryFileOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<RepositoryFileSchema, C, E, void>>;

  remove<E extends boolean = false>(
    projectId: string | number,
    filePath: string,
    branch: string,
    commitMessage: string,
    options?: RemoveRepositoryFileOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;
}

Repository Management

Users

User management including profile operations, SSH keys, GPG keys, emails, and impersonation tokens.

class Users<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'offset'>(
    options?: AllUsersOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<UserSchema[], C, E, P>>;

  show<E extends boolean = false>(
    userId: string | number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<UserSchema, C, E, void>>;

  showCurrentUser<E extends boolean = false>(
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<UserSchema, C, E, void>>;

  create<E extends boolean = false>(
    options: CreateUserOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<UserSchema, C, E, void>>;

  edit<E extends boolean = false>(
    userId: number,
    options?: EditUserOptions & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<UserSchema, C, E, void>>;

  block<E extends boolean = false>(
    userId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<boolean, C, E, void>>;

  unblock<E extends boolean = false>(
    userId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<boolean, C, E, void>>;
}

Users

Package Registries

Support for multiple package registry types including npm, Maven, PyPI, NuGet, Composer, Conan, Helm, Go, RubyGems, and Debian.

class NPM<C extends boolean = false> {
  uploadPackageFile<E extends boolean = false>(
    projectId: string | number,
    packageName: string,
    packageVersion: string,
    fileName: string,
    file: Blob | Buffer,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;

  downloadPackageFile<E extends boolean = false>(
    projectId: string | number,
    packageName: string,
    packageVersion: string,
    fileName: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<Blob | Buffer, C, E, void>>;
}

class Maven<C extends boolean = false> {
  uploadPackageFile<E extends boolean = false>(
    projectId: string | number,
    path: string,
    file: Blob | Buffer,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;

  downloadPackageFile<E extends boolean = false>(
    projectId: string | number,
    path: string,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<Blob | Buffer, C, E, void>>;
}

class Packages<C extends boolean = false> {
  all<E extends boolean = false, P extends PaginationTypes = 'offset'>(
    projectId: string | number,
    options?: AllPackagesOptions & PaginationRequestOptions<P> & Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<PackageSchema[], C, E, P>>;

  show<E extends boolean = false>(
    projectId: string | number,
    packageId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<PackageSchema, C, E, void>>;

  remove<E extends boolean = false>(
    projectId: string | number,
    packageId: number,
    options?: Sudo & ShowExpanded<E>
  ): Promise<GitlabAPIResponse<void, C, E, void>>;
}

Package Registries

Additional Resources

Extensive additional resources covering webhooks, wikis, snippets, labels, milestones, releases, deployments, environments, security, analytics, and administrative operations.

Note on Resource Naming: Many resources have both project-scoped and group-scoped variants with prefixed names:

  • Labels: ProjectLabels, GroupLabels
  • Milestones: ProjectMilestones, GroupMilestones
  • Wikis: ProjectWikis, GroupWikis
  • Releases: ProjectReleases, GroupReleases
  • Notes: IssueNotes, MergeRequestNotes, EpicNotes, ProjectSnippetNotes
  • Members: ProjectMembers, GroupMembers
  • Hooks: ProjectHooks, GroupHooks

Example usage:

const api = new Gitlab({ token: 'your-token' });

// Project-specific resources
const projectLabels = await api.ProjectLabels.all(projectId);
const projectMilestones = await api.ProjectMilestones.all(projectId);

// Group-specific resources
const groupLabels = await api.GroupLabels.all(groupId);
const groupMilestones = await api.GroupMilestones.all(groupId);

Additional Resources

Common Workflow Patterns

Working with Project ID

Most operations require a projectId. This can be:

// Numeric project ID
const projectId = 12345;

// URL-encoded project path
const projectId = 'mygroup%2Fmyproject';

// Helper for encoding project path
function encodeProjectPath(path: string): string {
  return encodeURIComponent(path);
}

const projectId = encodeProjectPath('mygroup/myproject');

Creating Issues with Full Context

// Create issue with all common fields
const issue = await api.Issues.create(projectId, 'Bug: Login failure', {
  description: '## Problem\n\nUsers cannot log in via SSO\n\n## Steps to Reproduce\n1. Click login\n2. Select SSO',
  labels: 'bug,priority::high,backend',
  assigneeIds: [456, 789],
  milestoneId: 10,
  dueDate: '2024-12-31',
  weight: 3,
  confidential: false
});

// Add time tracking immediately
await api.Issues.addTimeEstimate(projectId, issue.iid, '3h');

Complete Merge Request Workflow

// 1. Create MR
const mr = await api.MergeRequests.create(
  projectId,
  'feature/new-auth',
  'main',
  'Add OAuth authentication',
  {
    description: '## Changes\n\n- Add OAuth provider\n- Update login flow',
    assigneeIds: [userId],
    reviewerIds: [reviewerId1, reviewerId2],
    labels: 'feature,backend',
    removeSourceBranch: true,
    squash: true
  }
);

// 2. Check pipeline status
const pipelines = await api.MergeRequests.allPipelines(projectId, mr.iid);
const latestPipeline = pipelines[0];

if (latestPipeline.status === 'success') {
  // 3. Merge if pipeline passes
  await api.MergeRequests.merge(projectId, mr.iid, {
    shouldRemoveSourceBranch: true,
    squash: true,
    mergeCommitMessage: 'feat: add OAuth authentication'
  });
}

Multi-File Commit Pattern

// Update multiple files in a single commit
await api.Commits.create(
  projectId,
  'main',
  'Refactor authentication system',
  [
    // Update existing file
    {
      action: 'update',
      filePath: 'src/auth/index.ts',
      content: newAuthCode
    },
    // Create new file
    {
      action: 'create',
      filePath: 'src/auth/oauth.ts',
      content: oauthCode
    },
    // Delete old file
    {
      action: 'delete',
      filePath: 'src/auth/legacy.ts'
    },
    // Move file
    {
      action: 'move',
      filePath: 'src/auth/providers/google.ts',
      previousPath: 'src/auth/google.ts'
    },
    // Change file permissions
    {
      action: 'chmod',
      filePath: 'scripts/deploy.sh',
      executeFilemode: true
    }
  ],
  {
    authorEmail: 'bot@example.com',
    authorName: 'Deploy Bot'
  }
);

Pagination Handling

// Keyset pagination (recommended for large datasets)
let allProjects: ProjectSchema[] = [];
const options = {
  membership: true,
  perPage: 100,
  pagination: 'keyset' as const
};

const firstPage = await api.Projects.all(options);
allProjects.push(...firstPage.data);

// Handle subsequent pages
while (firstPage.paginationInfo.idAfter) {
  const nextPage = await api.Projects.all({
    ...options,
    idAfter: firstPage.paginationInfo.idAfter
  });
  allProjects.push(...nextPage.data);
  if (!nextPage.paginationInfo.idAfter) break;
}

// Offset pagination (simpler but less efficient)
const allIssues: IssueSchema[] = [];
for (let page = 1; page <= 10; page++) {
  const issues = await api.Issues.all({
    projectId,
    state: 'opened',
    page,
    perPage: 100
  });
  if (issues.length === 0) break;
  allIssues.push(...issues);
}

// Using maxPages for automatic pagination
const issues = await api.Issues.all({
  projectId,
  state: 'opened',
  perPage: 100,
  maxPages: 5 // Fetch up to 5 pages automatically
});

CI/CD Pipeline Management

// Trigger pipeline with variables
const pipeline = await api.Pipelines.create(projectId, 'main', {
  variables: [
    { key: 'DEPLOY_ENV', value: 'production' },
    { key: 'SKIP_TESTS', value: 'false' }
  ]
});

// Monitor pipeline progress
const checkPipelineStatus = async () => {
  const p = await api.Pipelines.show(projectId, pipeline.id);
  console.log(`Pipeline ${p.id}: ${p.status}`);

  if (p.status === 'running' || p.status === 'pending') {
    // Get job statuses
    const jobs = await api.Jobs.all(projectId, { pipelineId: p.id });
    jobs.forEach(job => {
      console.log(`  Job ${job.name}: ${job.status}`);
    });
  }

  return p.status;
};

// Poll until complete
let status = await checkPipelineStatus();
while (status === 'running' || status === 'pending') {
  await new Promise(resolve => setTimeout(resolve, 30000)); // Wait 30s
  status = await checkPipelineStatus();
}

// Handle failed jobs
if (status === 'failed') {
  const jobs = await api.Jobs.all(projectId, {
    pipelineId: pipeline.id,
    scope: 'failed'
  });

  for (const job of jobs) {
    // Get job logs
    const logs = await api.Jobs.showLog(projectId, job.id);
    console.error(`Job ${job.name} failed:\n${logs}`);

    // Retry if retriable
    if (job.retryable) {
      await api.Jobs.retry(projectId, job.id);
    }
  }
}

Common Types

AccessLevel

enum AccessLevel {
  NO_ACCESS = 0,
  MINIMAL_ACCESS = 5,
  GUEST = 10,
  REPORTER = 20,
  DEVELOPER = 30,
  MAINTAINER = 40,
  OWNER = 50,
  ADMIN = 60
}

Error Types

class GitbeakerRequestError extends Error {
  constructor(
    message: string,
    options?: {
      cause: {
        description: string;
        request: Request;
        response: Response;
      };
    }
  );
}

class GitbeakerTimeoutError extends Error {}

class GitbeakerRetryError extends Error {}

Pagination Types

type PaginationTypes = 'offset' | 'keyset';

interface PaginationRequestOptions<P extends PaginationTypes | void = void> {
  pagination?: P;
  perPage?: number | string;
  maxPages?: number;
  orderBy?: string;
  sort?: 'asc' | 'desc';
  page?: number | string; // For offset pagination
  idAfter?: number; // For keyset pagination
}

interface OffsetPagination {
  total: number;
  next: number | null;
  current: number;
  previous: number | null;
  perPage: number;
  totalPages: number;
}

interface KeysetPagination {
  idAfter: number;
  perPage: number;
  orderBy: string;
  sort: 'asc' | 'desc';
}

Response Types

interface ExpandedResponse<T> {
  data: T;
  headers: Record<string, string>;
  status: number;
}

type PaginatedResponse<T, P extends PaginationTypes> = {
  paginationInfo: P extends 'keyset' ? KeysetPagination : OffsetPagination;
  data: T;
};

type GitlabAPIResponse<
  T,
  C extends boolean,
  E extends boolean,
  P extends PaginationTypes | void
> =
  E extends true
    ? P extends PaginationTypes
      ? ExpandedResponse<T> & PaginatedResponse<T, P>
      : ExpandedResponse<T>
    : P extends PaginationTypes
      ? PaginatedResponse<T, P>
      : C extends true
        ? Camelize<T>
        : T;

Utility Types

interface Sudo {
  sudo?: string | number;
}

interface ShowExpanded<E extends boolean = false> {
  showExpanded?: E;
}

interface AsStream {
  asStream?: boolean;
}

Error Handling

Catching and Handling Errors

import { GitbeakerRequestError, GitbeakerTimeoutError, GitbeakerRetryError } from '@gitbeaker/rest';

try {
  const issue = await api.Issues.create(projectId, 'Title', options);
} catch (error) {
  if (error instanceof GitbeakerRequestError) {
    // HTTP error with request/response context
    console.error('Request failed:', error.message);
    console.error('Status:', error.cause.response.status);
    console.error('Description:', error.cause.description);

    // Handle specific status codes
    if (error.cause.response.status === 404) {
      console.error('Resource not found');
    } else if (error.cause.response.status === 401) {
      console.error('Authentication failed - check token');
    } else if (error.cause.response.status === 403) {
      console.error('Insufficient permissions');
    } else if (error.cause.response.status === 422) {
      console.error('Validation error - check parameters');
    } else if (error.cause.response.status === 429) {
      console.error('Rate limit exceeded');
    }
  } else if (error instanceof GitbeakerTimeoutError) {
    console.error('Request timed out');
  } else if (error instanceof GitbeakerRetryError) {
    console.error('Request failed after retries');
  }
}

Common Error Scenarios

  1. 404 Not Found: Project, issue, or resource doesn't exist

    • Verify project ID is correct
    • Check resource IID/ID is valid
    • Ensure you have access to the resource
  2. 401 Unauthorized: Authentication failed

    • Token is invalid or expired
    • Token doesn't exist
    • Wrong authentication method
  3. 403 Forbidden: Insufficient permissions

    • Token doesn't have required scopes
    • User doesn't have necessary access level
    • Resource is protected
  4. 422 Unprocessable Entity: Validation errors

    • Required parameters are missing
    • Parameters have invalid values
    • Business logic constraints violated
  5. 429 Too Many Requests: Rate limit exceeded

    • Wait for rate limit reset
    • Implement backoff strategy
    • Review rate limit configuration

Rate Limiting

// Configure custom rate limits
const api = new Gitlab({
  token: process.env.GITLAB_TOKEN,
  rateLimits: {
    '**': 1000, // 1000 requests per minute for all endpoints
    'projects/*/issues': 300, // 300 for issue operations
    'projects/*/merge_requests': {
      method: 'post',
      limit: 100 // 100 POST requests for MRs
    }
  },
  rateLimitDuration: 60 // Check rate limit every 60 seconds
});

// Handle rate limit errors
try {
  await api.Issues.create(projectId, 'Title', options);
} catch (error) {
  if (error instanceof GitbeakerRequestError && error.cause.response.status === 429) {
    const retryAfter = error.cause.response.headers.get('Retry-After');
    console.log(`Rate limited. Retry after ${retryAfter} seconds`);

    // Wait and retry
    await new Promise(resolve => setTimeout(resolve, parseInt(retryAfter) * 1000));
    return api.Issues.create(projectId, 'Title', options);
  }
}

Best Practices

  1. Use Environment Variables for Tokens: Never hardcode tokens in source code
  2. Handle Errors Appropriately: Always wrap API calls in try-catch blocks
  3. Use Keyset Pagination for Large Datasets: More efficient than offset pagination
  4. Leverage TypeScript Types: Use provided types for better code safety
  5. Implement Rate Limiting: Be mindful of API rate limits
  6. Use Specific Resource Classes: Import only what you need for better tree-shaking
  7. Cache Responses When Appropriate: Reduce unnecessary API calls
  8. Use Async/Await: Cleaner code than promise chains
  9. Validate Project IDs: Ensure project ID format is correct (numeric or URL-encoded path)
  10. Use Descriptive Variable Names: Make code self-documenting

Troubleshooting

Token Authentication Issues

// Test token validity
try {
  const currentUser = await api.Users.showCurrentUser();
  console.log('Authenticated as:', currentUser.username);
  console.log('Token scopes:', currentUser.scopes);
} catch (error) {
  console.error('Authentication failed:', error);
}

Project Not Found

// Verify project exists and you have access
try {
  const project = await api.Projects.show(projectId);
  console.log('Project found:', project.name);
} catch (error) {
  if (error instanceof GitbeakerRequestError && error.cause.response.status === 404) {
    console.error('Project not found or no access');
    // Try listing projects to see what you have access to
    const projects = await api.Projects.all({ membership: true });
    console.log('Available projects:', projects.map(p => `${p.id}: ${p.name}`));
  }
}

Debugging API Calls

// Enable expanded responses to see full HTTP details
const issue = await api.Issues.create(projectId, 'Title', {
  description: 'Test',
  showExpanded: true
});

console.log('Response status:', issue.status);
console.log('Response headers:', issue.headers);
console.log('Response data:', issue.data);

Connection Issues with Self-Hosted GitLab

// For self-signed certificates (development only)
import https from 'https';

const api = new Gitlab({
  host: 'https://gitlab.mycompany.com',
  token: process.env.GITLAB_TOKEN,
  agent: new https.Agent({
    rejectUnauthorized: false // ONLY for development/testing
  })
});