Everything an AI agent can do with the GitLab API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints25
API versionv4
Last updated23 June 2026
Orientation

How the GitLab API works.

The GitLab API is how an app or AI agent works with a GitLab project: reading and creating issues, opening and merging merge requests, reading and writing repository files, and triggering CI/CD pipelines. Access is granted through a token, and the scope on that token decides whether a call can only read or can also write, and which projects and groups it reaches. GitLab can also push events to a webhook URL when something happens in a project, so an agent learns about activity without polling.

25Endpoints
9Capability groups
11Read
14Write
4Permissions
Authentication
Every write and most private reads need a token, sent in a PRIVATE-TOKEN header or as a Bearer token in an Authorization header. Four token types exist: a personal access token acting as a user, an OAuth 2.0 access token for a third-party app acting on a user's behalf, a project or group access token scoped to one project or group, and a CI/CD job token created automatically inside a pipeline. OAuth access tokens expire after two hours and are renewed with a refresh token.
Permissions
A token carries one or more coarse scopes that decide its reach. The api scope grants full read and write across the API; read_api grants read-only access across the API; read_repository and write_repository cover repository access through Git-over-HTTP and the repository files API; read_user grants read-only access to the authenticated user's own profile. There is no per-resource permission like Issues-only; a token broad enough to write one area can write others within its scope, which is why a governance layer in front matters.
Versioning
The REST API is versioned by a single major number in the path, currently 4, and follows semantic versioning, so new endpoints and fields are added within v4 without breaking it. Version 4 has been the supported version since GitLab 9.0, with the older v3 removed in GitLab 11.0. Breaking changes are deferred to a future v5 rather than shipped into v4; individual fields are deprecated across dated GitLab releases ahead of that.
Data model
The API is resource-oriented JSON over HTTPS, answering under /api/v4 on the GitLab host. Most resources nest under a project at /projects/:id, covering issues, merge requests, repository files, commits, branches, and pipelines, while users and groups live at the top level. Issues and merge requests are addressed by a per-project internal id (the iid), not their global id. A GraphQL API and event-push webhooks complement REST.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to GitLab determines what it can reach. There are several routes, each governed by the token behind it and the scope that token carries.

Ways to connect

REST API

The REST API answers under /api/v4 on the GitLab host, for example https://gitlab.com/api/v4. A call authenticates with a token sent in a PRIVATE-TOKEN header, or as a Bearer token in an Authorization header.

Best forConnecting an app or AI agent to GitLab.
Governed byThe token and the scope it carries.
Docs ↗

GraphQL API

The GraphQL API answers at /api/graphql with a typed schema, letting a caller fetch many related fields in one request. It complements REST and GitLab is investing in it for newer features.

Best forConnecting an app or AI agent to GitLab.
Governed byThe token and the scope it carries.
Docs ↗

MCP server (Model Context Protocol)

GitLab's own MCP server lets an agent call GitLab through the Model Context Protocol, at /api/v4/mcp on the GitLab host. It is in beta, having changed from experiment to beta in GitLab 18.6, and authenticates with OAuth 2.0 Dynamic Client Registration so a tool can register itself. It exposes tools for issues, merge requests, and pipelines.

Best forConnecting an AI agent to GitLab through MCP.
Governed byThe OAuth grant and the scope it carries.
Docs ↗

Webhooks

Webhooks deliver the chosen events to a receiver URL when activity happens in a project or group. Each payload carries an object_kind field naming the event, and a configured secret token is sent in the X-Gitlab-Token header so the receiver can confirm the delivery came from GitLab.

Best forReceiving GitLab events at an app or AI agent.
Governed byThe secret token configured on the webhook.
Docs ↗
Authentication

Personal access token

A personal access token acts as the user who created it and carries one or more scopes, such as api for full read and write, read_api for read-only, read_repository or write_repository for repository access, and read_user for the user's own profile. It is sent in a PRIVATE-TOKEN header.

TokenPersonal access token
Best forServer-side scripts and automation as a user
Docs ↗

OAuth 2.0

OAuth 2.0 lets a third-party app act for a user after consent, through the authorization code with PKCE flow or the device authorization grant. The access token carries the granted scopes, expires after two hours, and is renewed with a refresh token. It is sent as a Bearer token.

TokenOAuth 2.0 access token
Best forThird-party apps acting on behalf of a user
Docs ↗

Project or group access token

A project or group access token is scoped to a single project or group rather than a whole user, with its own scopes and an attached bot user and role. It suits automation that should reach only one project or group. It is sent in a PRIVATE-TOKEN header.

TokenProject or group access token
Best forAutomation scoped to one project or group
Docs ↗

CI/CD job token

A CI/CD job token is created automatically for a running pipeline job and exposed as the CI_JOB_TOKEN variable. It is short-lived, tied to the job, and reaches only what the job's project is authorized for. It is sent in a JOB-TOKEN header.

TokenCI/CD job token
Best forCalls made from inside a pipeline job
Docs ↗
Capability map

What an AI agent can do in GitLab.

The GitLab API is split into areas an agent can act on, such as projects, issues, merge requests, repository files, and pipelines. Each area has its own methods, and a single token scope decides whether a call can only read or can also write.

Endpoint reference

Every GitLab API method.

Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.

MethodEndpointWhat it doesAccessPermissionVersion

Projects

List projects, read a single project, create a project, update its settings, and delete it.4

read_api grants read-only access across the API. The api scope also works but adds write access.

Acts onproject
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Any default role can read project properties; editing needs the Maintainer or Owner role.

Acts onproject
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

The api scope grants full read and write access to the API. read_api cannot write.

Acts onproject
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires the Maintainer or Owner role on the project.

Acts onproject
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Issues

List, read, create, and update issues in a project.4

Issues are addressed by their per-project internal id (issue_iid), not the global id.

Acts onissue
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

read_api grants read-only access across the API.

Acts onissue
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

The api scope grants full read and write across the API.

Acts onissue
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventissue
Rate limitStandard limits apply

Closing and reopening use the state_event field here.

Acts onissue
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventissue
Rate limitStandard limits apply

Merge requests

List, create, and update merge requests, and merge them.4

Merge requests are addressed by their per-project internal id (merge_request_iid).

Acts onmerge request
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

The api scope grants full read and write across the API.

Acts onmerge request
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventmerge_request
Rate limitStandard limits apply

Closing and reopening use the state_event field here.

Acts onmerge request
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventmerge_request
Rate limitStandard limits apply

Merging commits to the target branch and needs at least the Developer role with merge rights.

Acts onmerge request
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventmerge_request
Rate limitStandard limits apply

Comments (notes)

Create comments on issues and merge requests.2

The api scope grants full read and write across the API.

Acts onnote
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventnote
Rate limitStandard limits apply

The same note model serves merge request discussion comments.

Acts onnote
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventnote
Rate limitStandard limits apply

Repository files, commits & branches

Read and update repository files, create commits, and list and create branches.5

read_repository grants read access to repositories through the repository files API. read_api also covers this.

Acts onfile
Permission (capability)read_repository
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Writing through the repository files API needs the api scope.

Acts onfile
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventpush
Rate limitStandard limits apply

A single request can batch several file changes into one commit.

Acts oncommit
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventpush
Rate limitStandard limits apply

read_api also covers this read.

Acts onbranch
Permission (capability)read_repository
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Creating a branch fires the push event under the create object_kind for new refs.

Acts onbranch
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventpush
Rate limitStandard limits apply

Pipelines (CI/CD)

List pipelines, create a new pipeline, and retry one.3

read_api grants read-only access across the API.

Acts onpipeline
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

This path is singular (/pipeline), unlike the plural listing path.

Acts onpipeline
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventpipeline
Rate limitStandard limits apply

The api scope grants full read and write across the API.

Acts onpipeline
Permission (capability)api
VersionAvailable since the API’s base version
Webhook eventpipeline
Rate limitStandard limits apply

Users

Read the authenticated user's own profile.1

read_user grants read-only access to the authenticated user's own profile through the /user endpoint. read_api and api also cover it.

Acts onuser
Permission (capability)read_user
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Groups

List groups visible to the authenticated user.1

read_api grants read-only access across the API.

Acts ongroup
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply
Search across the instance, scoped by a search type such as projects, issues, or merge requests.1

The scope parameter chooses what to search; available scopes include projects, issues, merge_requests, milestones, users, commits, and blobs.

Acts onsearch result
Permission (capability)read_api
VersionAvailable since the API’s base version
Webhook eventNone
Rate limit10 requests per minute per IP address (search API)
No endpoints match those filters.
Webhooks

Webhook events.

GitLab can notify an app or AI agent when something happens in a project, instead of the app repeatedly asking. GitLab posts the event payload to a webhook URL that has been registered for the chosen events, and each payload carries an object_kind field naming the event.

EventWhat it signalsTriggered by
Push events (object_kind: push)Fires when a push is made to the repository, which includes commits created through the repository files and commits APIs./projects/:id/repository/files/:file_path
/projects/:id/repository/commits
/projects/:id/repository/branches
Tag push events (object_kind: tag_push)Fires when tags are created or deleted in the repository.In-app only
Issue events (object_kind: issue)Fires when an issue is created, or an existing one is edited, closed, or reopened./projects/:id/issues
/projects/:id/issues/:issue_iid
Merge request events (object_kind: merge_request)Fires when a merge request is created, edited, merged, or closed, or a commit is added in the source branch./projects/:id/merge_requests
/projects/:id/merge_requests/:merge_request_iid
/projects/:id/merge_requests/:merge_request_iid/merge
Comment events (object_kind: note)Fires when a comment is made or edited on a commit, merge request, issue, or code snippet./projects/:id/issues/:issue_iid/notes
/projects/:id/merge_requests/:merge_request_iid/notes
Pipeline events (object_kind: pipeline)Fires when a pipeline's status changes./projects/:id/pipeline
/projects/:id/pipelines/:pipeline_id/retry
Job events (object_kind: build)Fires when the status of a job within a pipeline changes.In-app only
Release events (object_kind: release)Fires when a release is created, edited, or deleted.In-app only
Deployment events (object_kind: deployment)Fires when a deployment starts, succeeds, fails, or is canceled.In-app only
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

GitLab limits how fast an app or AI agent can call, through a per-minute request quota that depends on whether the call is authenticated, with tighter limits on a few specific endpoints like search.

Request rate

GitLab.com meters requests per minute, decided by whether the call is authenticated. Authenticated API traffic for a user is allowed 2,000 requests per minute; unauthenticated traffic from an IP address is allowed 500 requests per minute, with all traffic from one IP address capped at 2,000 per minute. A few endpoints are tighter: the search API is held to 10 requests per minute per IP address, and endpoints like repository archives and webhook testing to 5 per minute per user. Every response carries RateLimit-Limit, RateLimit-Observed, RateLimit-Remaining, and RateLimit-Reset headers reporting the current state, and going over returns 429 with a Retry-After header giving the seconds to wait. Self-managed instances set their own limits, so these figures are GitLab.com's.

Pagination

List endpoints page through results with the page and per_page parameters, where per_page defaults to 20 and tops out at 100, and the response headers x-total, x-total-pages, x-next-page, and x-prev-page describe the set. For large collections, keyset pagination is offered by sending pagination=keyset with order_by and sort, which returns a Link header carrying the URL of the next page rather than a page number.

Request size

Requests and responses are JSON. List pages return at most 100 items through per_page, and some unauthenticated or wide list endpoints cap the total reachable through offset pagination, where keyset pagination is recommended instead. There is no single documented payload size limit across the whole API, though individual endpoints set their own ceilings.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
304Not ModifiedThe resource has not been modified since the last request, returned for a conditional request.Treat the cached copy as current and skip refetching it.
400Bad RequestA required attribute of the request is missing, for example the title of an issue is not given.Add the missing or correct the invalid attribute, then resend.
401UnauthorizedThe caller is not authenticated; a valid user token is necessary.Send a valid token in the PRIVATE-TOKEN or Authorization header.
403ForbiddenThe request is not allowed, for example the user lacks the role to delete a project, or the token's scope does not cover the action.Grant the needed role or token scope, then retry.
404Not FoundA resource could not be accessed, because its ID could not be found or the user is not authorized to see it. GitLab returns 404 rather than 403 so it does not reveal a private resource exists.Confirm the path and ID, and that the token has access to the resource.
409ConflictA conflicting resource already exists, for example creating something that is already present.Refetch the current state and reconcile before retrying.
412Precondition FailedThe request was denied, which can happen when an If-Unmodified-Since header is set on a delete and the resource was modified in between.Refetch the resource and retry the conditional request.
422UnprocessableThe entity could not be processed, typically a semantic validation failure on an otherwise well-formed request.Correct the offending fields named in the response and resend.
429Too Many RequestsThe caller exceeded the application rate limits.Honor the Retry-After header, or the RateLimit-Reset time, before retrying.
500Server ErrorSomething went wrong on the server while handling the request.Retry after a short delay, and contact GitLab support if it persists.
Versioning & freshness

Version history.

GitLab versions its REST API by a single major number, currently 4, and follows semantic versioning so new endpoints and fields are added without breaking the major version.

Version history

What changed, and when

Latest versionv4
v4Current version
Current major version (REST API v4)

Version 4 is the supported REST API, addressed in the path as /api/v4, and complies with semantic versioning where the major number is 4. New endpoints and fields are added within v4 without breaking it. Breaking changes are deferred to a future v5 rather than shipped into v4, and individual fields are deprecated across dated GitLab releases ahead of that move. Version 4 has been the preferred version since GitLab 9.0.

What changed
  • REST API v4 is addressed at /api/v4 and follows semantic versioning with major number 4.
  • Most breaking changes are reserved for the future v5 REST API.
  • Fields are deprecated in dated GitLab releases before any removal.
2026-06
MCP server in beta (GitLab 18.6)

GitLab's Model Context Protocol server, at /api/v4/mcp, changed from experiment to beta in GitLab 18.6, and the mcp_server and oauth_dynamic_client_registration feature flags were removed. It authenticates with OAuth 2.0 Dynamic Client Registration and exposes tools for issues, merge requests, and pipelines. Search by project path was added in the same release.

What changed
  • MCP server moved from experiment to beta and its feature flags were removed.
  • MCP server authenticates with OAuth 2.0 Dynamic Client Registration.
  • Search by project path added.
2025-08
MCP server introduced as experiment (GitLab 18.3)

GitLab introduced its Model Context Protocol server as an experiment in GitLab 18.3, behind feature flags, letting AI tools connect to a GitLab instance and act through standard MCP tools.

What changed
  • MCP server introduced as an experiment behind feature flags.
2025-05
GitLab 18.0 (notable deprecations)

GitLab 18.0, released in May 2025, removed a range of long-deprecated behaviors, including some legacy API endpoints and CI/CD defaults, ahead of their replacements. Field-level REST deprecations such as default_branch_protection across group and settings APIs were flagged in earlier 17.x releases for this transition.

What changed
  • Removed several long-deprecated features and legacy endpoints.
  • default_branch_protection deprecated across group and settings APIs (from 17.0).
  • restrict_user_defined_variables deprecated in favor of ci_pipeline_variables_minimum_override_role (from 17.7).

Breaking changes are held back for a future major version rather than shipped into the current one.

GitLab REST API deprecations ↗
Questions

GitLab API, answered.

Personal access token or OAuth, which should I use?+
A personal access token is the simplest choice for a server-side script that acts as one user: it is created in the user's settings, carries the scopes chosen for it, and is sent in a PRIVATE-TOKEN header. OAuth 2.0 suits a third-party app that acts on behalf of many users after each one consents, through the authorization code with PKCE flow; its access token expires after two hours and is renewed with a refresh token. For automation tied to a single project rather than a person, a project access token is narrower than either.
What do the token scopes actually grant?+
Scopes are coarse, not per-resource. The api scope grants full read and write across the whole API, including groups, projects, and the registries. read_api grants read-only access across the API. read_repository and write_repository cover repository access through Git-over-HTTP and the repository files API. read_user grants read-only access to the authenticated user's own profile through the /user endpoint. A token cannot be limited to, say, issues only, so a token that can write at all can write across its scope.
What are the rate limits on GitLab.com?+
GitLab.com allows 2,000 authenticated API requests per minute for a user, and 500 unauthenticated requests per minute from an IP address, with all traffic from one IP capped at 2,000 per minute. The search API is tighter at 10 requests per minute per IP, and a few endpoints such as repository archives at 5 per minute per user. Responses carry RateLimit-Limit, RateLimit-Observed, RateLimit-Remaining, and RateLimit-Reset headers, and a 429 includes a Retry-After value. Self-managed instances configure their own limits.
How does pagination work?+
List endpoints use offset pagination by default, through the page and per_page parameters, where per_page defaults to 20 and maxes at 100. The x-total, x-total-pages, x-next-page, and x-prev-page response headers describe the result set. For large collections, keyset pagination is more efficient: send pagination=keyset with order_by and sort, then follow the URL in the Link header for the next page rather than incrementing a page number.
How do I receive events instead of polling?+
Webhooks deliver events without polling. A receiver URL is registered on a project or group, and a set of events is chosen, such as push, issue, merge_request, note, or pipeline. GitLab posts a JSON payload when each event fires, and the payload's object_kind field names the event. A secret token set on the webhook is sent in the X-Gitlab-Token header so the receiver can confirm the delivery came from GitLab.
Does GitLab have an MCP server for AI agents?+
Yes. GitLab ships its own Model Context Protocol server at /api/v4/mcp on the GitLab host, which lets an MCP-compatible agent such as Claude call GitLab through standard tools. It moved from experiment to beta in GitLab 18.6, and authenticates with OAuth 2.0 Dynamic Client Registration so a tool can register itself with the instance. The current tools cover issues, merge requests, and pipelines.
Why am I getting a 404 when I'm sure the resource exists?+
A 404 is often a permissions problem rather than a missing resource. For a private project or resource, GitLab returns 404 instead of 403 when the token cannot see it, so it does not confirm the resource exists. Check that the token has access to the project and the right scope, and that issues and merge requests are addressed by their per-project iid, not their global id.
Related

More developer API guides for agents

What is Bollard AI?

Control what every AI agent can do in GitLab.

Bollard AI sits between a team's AI agents and GitLab. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared GitLab token.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
GitLab
Triage Agent
Read issues ResourceOffReadFull use
Comment on issues ActionOffReadFull use
Merge requests ResourceOffReadFull use
Run pipelines ActionOffReadFull use
Per-agent access, set in Bollard AI, not in GitLab