Merge requests API

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

Use this API to manage merge requests. You can:

  • Automate any part of the code review process.
  • Connect code changes to external tools.
  • Send merge request information to non-GitLab systems in your preferred format.
  • Update, approve, merge, or block merge requests based on data from external systems.

All API calls to non-public information require authentication.

Removals in API v5

The approvals_before_merge attribute is deprecated, and is scheduled for removal in API v5 in favor of the merge request approvals API.

List merge requests

List all merge requests accessible to the authenticated user. By default, returns only merge requests created by the current user. Use scope=all to retrieve all merge requests.

Use the state parameter to get only merge requests with a given state (opened, closed, locked, or merged) or all states (all). Searching by locked generally returns no results as that state is short-lived and transitional. Use the pagination parameters page and per_page to restrict the list of merge requests.

GET /merge_requests
GET /merge_requests?state=opened
GET /merge_requests?state=all
GET /merge_requests?milestone=release
GET /merge_requests?labels=bug,reproduced
GET /merge_requests?author_id=5
GET /merge_requests?author_username=gitlab-bot
GET /merge_requests?my_reaction_emoji=star
GET /merge_requests?scope=assigned_to_me
GET /merge_requests?scope=reviews_for_me
GET /merge_requests?search=foo&in=title

Supported attributes:

AttributeTypeRequiredDescription
approved_by_ids[]integer arrayNoReturns merge requests approved by all the users with the given id, up to 5 users. None returns merge requests with no approvals. Any returns merge requests with an approval.
approved_by_usernames[]string arrayNoReturns merge requests approved by all the users with the given username, up to 5 users. None returns merge requests with no approvals. Any returns merge requests with an approval.
approver_ids[]integer arrayNoReturns merge requests which have all users with the specified id as eligible approvers according to the approval rules. None returns merge requests with no eligible approvers. Any returns merge requests with at least one eligible approver. Premium and Ultimate only.
assignee_idinteger or stringNoReturns merge requests assigned to the given user id. None returns unassigned merge requests. Any returns merge requests with an assignee. Mutually exclusive with assignee_username.
assignee_username[]string arrayNoReturns merge requests assigned to the given usernames. Mutually exclusive with assignee_id.
author_idintegerNoReturns merge requests created by the given user id. Mutually exclusive with author_username. Combine with scope=all or scope=assigned_to_me.
author_usernamestringNoReturns merge requests created by the given username. Mutually exclusive with author_id.
created_afterdatetimeNoReturns merge requests created on or after the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
created_beforedatetimeNoReturns merge requests created on or before the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
deployed_afterdatetimeNoReturns merge requests deployed after the given date/time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
deployed_beforedatetimeNoReturns merge requests deployed before the given date/time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
merged_afterdatetimeNoReturns merge requests merged on or after the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
merged_beforedatetimeNoReturns merge requests merged on or before the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
environmentstringNoReturns merge requests deployed to the given environment.
instringNoChange the scope of the search attribute. title, description, or a string joining them with comma. Default is title,description.
labelsstringNoReturns merge requests matching a comma-separated list of labels. None lists all merge requests with no labels. Any lists all merge requests with at least one label. Predefined names are case-insensitive.
merge_user_idintegerNoReturns merge requests merged by the user with the given user id. Mutually exclusive with merge_user_username. Introduced in GitLab 17.0.
merge_user_usernamestringNoReturns merge requests merged by the user with the given username. Mutually exclusive with merge_user_id. Introduced in GitLab 17.0.
milestonestringNoReturns merge requests for a specific milestone. None returns merge requests with no milestone. Any returns merge requests that have an assigned milestone.
my_reaction_emojistringNoReturns merge requests reacted by the authenticated user by the given emoji. None returns issues not given a reaction. Any returns issues given at least one reaction.
non_archivedbooleanNoIf true, returns merge requests from non-archived projects only. Default is false.
nothashNoReturns merge requests that do not match the parameters supplied. Accepts: labels, milestone, author_id, author_username, assignee_id, assignee_username, reviewer_id, reviewer_username, my_reaction_emoji.
order_bystringNoReturns merge requests ordered by created_at, updated_at, merged_at (introduced in GitLab 17.2), label_priority, priority, milestone_due, popularity, or title fields. Default is created_at.
reviewer_idinteger or stringNoReturns merge requests which have the user as a reviewer with the given user id. None returns merge requests with no reviewers. Any returns merge requests with any reviewer. Mutually exclusive with reviewer_username.
reviewer_usernamestringNoReturns merge requests which have the user as a reviewer with the given username. None returns merge requests with no reviewers. Any returns merge requests with any reviewer. Mutually exclusive with reviewer_id.
scopestringNoReturns merge requests for the given scope: created_by_me, assigned_to_me, reviews_for_me, or all. reviews_for_me returns merge requests where the current user is assigned as a reviewer. Defaults to created_by_me.
searchstringNoSearch merge requests against their title and description. Combine with in attribute.
sortstringNoReturns merge requests sorted in asc or desc order. Default is desc.
source_branchstringNoReturns merge requests with the given source branch.
statestringNoReturns all merge requests (all) or just those that are opened, closed, locked, or merged. Defaults to all.
target_branchstringNoReturns merge requests with the given target branch.
updated_afterdatetimeNoReturns merge requests updated on or after the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
updated_beforedatetimeNoReturns merge requests updated on or before the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
viewstringNoIf simple, returns the iid, URL, title, description, and basic state of merge request.
draftbooleanNoFilter merge requests by their draft status. true returns only draft merge requests, false returns non-draft merge requests. Mutually exclusive with wip.
wipstringNoDeprecated in GitLab 19.0. Use draft instead. Filter merge requests by their wip status. yes returns only draft merge requests, no returns non-draft merge requests.
with_labels_detailsbooleanNoIf true, response returns more details for each label in labels field: :name, :color, :description, :description_html, :text_color. Default is false.
with_merge_status_recheckbooleanNoIf true, this projection requests (but does not guarantee) an asynchronous recalculation of the merge_status field. Enable the restrict_merge_status_recheck feature flag to ignore this attribute when requested by users without the Developer, Maintainer, or Owner role.

If successful, returns 200 OK. If view is set to simple, returns a subset of fields. Otherwise, response attributes include:

AttributeTypeDescription
allow_collaborationbooleanIf true, this fork allows collaboration from members who can merge to the target branch. Used only for merge requests from forks.
allow_maintainer_to_pushbooleanDeprecated. Use allow_collaboration instead.
approvals_before_mergeintegerDeprecated in GitLab 16.0. To configure approval rules, see the merge request approvals API instead. GitLab Premium and Ultimate only.
assignee[]objectDeprecated. Use assignees instead.
assignees[]arrayUsers assigned to the merge request.
assignees.avatar_urlstringFull URL to the assignee’s avatar image.
assignees.idintegerThe unique ID of the assignee.
assignees.lockedbooleanIf true, the assignee’s account is locked due to failed authentication attempts, and they cannot sign in until the lock expires or an administrator unlocks the account.
assignees.namestringDisplay name of the assignee. Might be redacted, based on current user’s permissions.
assignees.public_emailstringThe public email address of the assignee.
assignees.statestringCurrent state of the assignee’s user account. Possible values: active, blocked, or deactivated.
assignees.usernamestringUsername of the merge request assignee.
assignees.web_urlstringFull URL to the assignee’s profile page.
author[]objectObject with information about the user who created the merge request.
author.avatar_urlstringFull URL to the author’s avatar image.
author.botbooleanIf true, the author is a bot. For a list of bot account types, see BOT_USER_TYPES.
author.idintegerThe unique ID of the user who created the merge request.
author.lockedbooleanIf true, the author’s account is locked due to failed authentication attempts, and they cannot sign in until the lock expires or an administrator unlocks the account.
author.namestringDisplay name of the author. Might be redacted, based on current user’s permissions.
author.public_emailstringThe public email address of the author.
author.statestringCurrent state of the user account. Possible values: active, blocked, or deactivated.
author.usernamestringUsername of the merge request author.
author.web_urlstringFull URL to the author’s profile page.
blocking_discussions_resolvedbooleanIf true, all discussion threads in the merge request must be resolved before merging.
closed_atdateTimeTimestamp of when the merge request was closed.
closed_by[]objectObject with information about the user who closed the merge request. If null, the merge request is open.
closed_by.avatar_urlstringFull URL to the closing user’s avatar image.
closed_by.idintegerThe unique ID of the user who closed the merge request.
closed_by.lockedbooleanIf true, the closing user’s account is locked due to failed authentication attempts, and they cannot sign in until the lock expires or an administrator unlocks the account.
closed_by.namestringDisplay name of the closing user. Might be redacted, based on current user’s permissions.
closed_by.public_emailstringThe public email address of the closing user.
closed_by.statestringCurrent state of the closing user’s account. Possible values: active, blocked, or deactivated.
closed_by.usernamestringUsername of the user who closed the merge request.
closed_by.web_urlstringFull URL to the closing user’s profile page.
created_atdateTimeTimestamp of when the merge request was created.
descriptionstringDescription of the merge request. Contains Markdown rendered as HTML for caching.
description_htmlstringIf render_html is set, the rendered HTML version of the description.
detailed_merge_statusstringDetailed merge status information. See merge status for a list of potential values.
discussion_lockedbooleanIf true, discussions are locked. Only project members can add, edit, or resolve comments in locked discussions.
downvotesintegerNumber of downvotes for the merge request.
draftbooleanIf true, the merge request is marked in a draft state.
force_remove_source_branchbooleanIf true, the project settings force the deletion of the source branch after merge.
has_conflictsbooleanIf true, the merge request has conflicts and cannot merge. Dependent on the merge_status property. Returns false unless merge_status is cannot_be_merged.
idintegerThe unique ID of the merge request.
iidintegerThe internal ID of the merge request in the project.
importedbooleanIf true, the merge request was imported.
imported_fromstringSource of import, such as Bitbucket.
labels[]arrayArray of labels assigned to the merge request. If with_labels_details is true, returns an array for each label.
labels.archivedbooleanIf with_labels_details is true, the label is archived.
labels.colorstringIf with_labels_details is true, the background color of the label.
labels.descriptionstringIf with_labels_details is true, the description text of the label. If null, the label has no description.
labels.description_html.stringIf with_labels_details is true, the HTML-rendered description of the label. If null, the label has no description.
labels.idintegerIf with_labels_details is true, the unique ID of the label.
labels.namestringIf with_labels_details is true, the name of the label.
labels.text_colorstringIf with_labels_details is true, the text color for the label.
merge_afterdateTimeIf set, timestamp after which the merge request can be merged. Introduced in GitLab 17.8.
merge_commit_shastringIf set, the SHA of the merge request commit. Returns null until merged.
merge_statusstringStatus of the merge request. Use detailed_merge_status instead, which accounts for all potential statuses. Affects the has_conflicts property. For important notes on response data, see single merge request response notes. Deprecated in GitLab 15.6.
merge_userobjectObject with information about the user who merged the merge request, set it to auto-merge, or null.
merge_when_pipeline_succeedsbooleanIf true, the merge request is set to auto-merge.
merged_atdateTimeTimestamp of when the merge request merged.
merged_by[]objectDeprecated. Use merge_user instead.
milestone[]objectObject with information about the milestone assigned to the merge request.
milestone.created_atdateTimeTimestamp when the milestone was created.
milestone.descriptionstringDescription text of the milestone. If null, the milestone has no description.
milestone.due_datedateDue date for the milestone. If null, the milestone has no due date.
milestone.expiredbooleanIf true, the milestone has expired.
milestone.group_idintegerID of the group the milestone belongs to. Included only if the milestone is a group milestone.
milestone.idintegerUnique ID of the milestone.
milestone.iidintegerInternal ID of the milestone in the project or group.
milestone.project_idintegerID of the project the milestone belongs to. Included only if the milestone is a project milestone.
milestone.start_datedateStart date for the milestone. If null, the milestone has no start date
milestone.statestringCurrent state of the milestone, such as active or closed.
milestone.titlestringName of the milestone.
milestone.updated_atdateTimeTimestamp when the milestone was last updated.
milestone.web_urlstringFull web URL to view the milestone.
prepared_atdateTimeTimestamp of when the merge request was prepared. This field populates one time, only after all the preparation steps complete, and is not updated if more changes are added.
project_idintegerThe ID of the project containing the merge request.
referencestringDeprecated. Use references instead.
references[]objectObject with all internal references of the merge request.
references.fullstringComplete reference to a merge request, including full project path, like gitlab-org/gitlab!123. When requested across groups or projects, identical to references.relative.
references.relativestringReference relative to a specific project or group: !123 for a merge request in the current project, or other-project!123 for another project in the same group.
references.shortstringShortest possible reference to a merge request, like !123. When fetched from the merge request’s project, identical to references.relative.
reviewers[]arrayReviewers of the merge request.
reviewers.avatar_urlstringFull URL to the reviewer’s avatar image.
reviewers.idintegerThe unique ID of the reviewer.
reviewers.lockedbooleanIf true, the reviewer’s account is locked due to failed authentication attempts, and they cannot sign in until the lock expires or an administrator unlocks the account.
reviewers.namestringDisplay name of the reviewer. Might be redacted, based on current user’s permissions.
reviewers.public_emailstringThe public email address of the reviewer.
reviewers.statestringCurrent state of the reviewer’s user account. Possible values: active, blocked, or deactivated.
reviewers.usernamestringUsername of the merge request reviewer.
reviewers.web_urlstringFull URL to the reviewer’s profile page.
shastringSHA of the head commit in the source branch.
should_remove_source_branchbooleanIf true, the source branch is removed after merge.
source_branchstringName of the source branch.
source_project_idintegerID of the source project.
squashbooleanIf true, squash commits when merging.
squash_commit_shastringIf set, the SHA of the squash commit. Empty until merged.
squash_on_mergebooleanIf true, commits are squashed on merge.
statestringThe current state of the merge request. Possible values: opened, closed, merged, or locked.
target_branchstringName of the target branch.
target_project_idintegerID of the target project.
task_completion_status[]objectObject with information on the task list completion status.
task_completion_status.completed_countintegerNumber of completed task list items in the merge request description. Returns 0 if the merge request has no description or no task list items.
task_completion_status.countintegerTotal number of task list items found in the merge request description. Returns 0 if the merge request has no description or no task list items.
time_stats[]objectObject with information on time tracking for this merge request.
time_stats.human_time_estimatestringHuman-readable format of time_stats.time_estimate, like 3h 30m.
time_stats.human_total_time_spentstringHuman-readable format of time_stats.total_time_spent, like 3h 30m.
time_stats.time_estimateintegerEstimated time to complete the merge request, in seconds.
time_stats.total_time_spentintegerTotal time spent working on the merge request, in seconds.
titlestringThe merge request title.
title_htmlstringIf render_html is true, the rendered HTML version of the title.
updated_atdateTimeTimestamp of when the merge request was last updated.
upvotesintegerNumber of upvotes for the merge request.
user_notes_countintegerNumber of user comments.
web_urlstringWeb URL to view the merge request.
work_in_progressbooleanDeprecated. Use draft instead.

Other possible responses:

  • 401 Unauthorized if the access token is invalid.
  • 408 Request Timeout if the database query times out.
  • 422 Unprocessable Entity if validation failed.
  • 429 Too Many Requests if using the search parameter, and the request has been rate-limited.

Example response:

json
[
  {
    "id": 1,
    "iid": 1,
    "project_id": 3,
    "title": "test1",
    "description": "fixed login page css paddings",
    "state": "merged",
    "imported": false,
    "imported_from": "none",
    "merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
      "id": 87854,
      "name": "Douwe Maan",
      "username": "DouweM",
      "state": "active",
      "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
      "web_url": "https://gitlab.com/DouweM"
    },
    "merge_user": {
      "id": 87854,
      "name": "Douwe Maan",
      "username": "DouweM",
      "state": "active",
      "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
      "web_url": "https://gitlab.com/DouweM"
    },
    "merged_at": "2018-09-07T11:16:17.520Z",
    "merge_after": "2018-09-07T11:16:00.000Z",
    "prepared_at": "2018-09-04T11:16:17.520Z",
    "closed_by": null,
    "closed_at": null,
    "created_at": "2017-04-29T08:46:00Z",
    "updated_at": "2017-04-29T08:46:00Z",
    "target_branch": "main",
    "source_branch": "test1",
    "upvotes": 0,
    "downvotes": 0,
    "author": {
      "bot": false,
      "id": 1,
      "name": "Administrator",
      "username": "admin",
      "state": "active",
      "avatar_url": null,
      "web_url" : "https://gitlab.example.com/admin"
    },
    "assignee": {
      "id": 1,
      "name": "Administrator",
      "username": "admin",
      "state": "active",
      "avatar_url": null,
      "web_url" : "https://gitlab.example.com/admin"
    },
    "assignees": [{
      "name": "Miss Monserrate Beier",
      "username": "axel.block",
      "id": 12,
      "state": "active",
      "avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
      "web_url": "https://gitlab.example.com/axel.block"
    }],
    "reviewers": [{
      "id": 2,
      "name": "Sam Bauch",
      "username": "kenyatta_oconnell",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
      "web_url": "http://gitlab.example.com//kenyatta_oconnell"
    }],
    "source_project_id": 2,
    "target_project_id": 3,
    "labels": [
      "Community contribution",
      "Manage"
    ],
    "draft": false,
    "work_in_progress": false,
    "milestone": {
      "id": 5,
      "iid": 1,
      "project_id": 3,
      "title": "v2.0",
      "description": "Assumenda aut placeat expedita exercitationem labore sunt enim earum.",
      "state": "closed",
      "created_at": "2015-02-02T19:49:26.013Z",
      "updated_at": "2015-02-02T19:49:26.013Z",
      "due_date": "2018-09-22",
      "start_date": "2018-08-08",
      "web_url": "https://gitlab.example.com/my-group/my-project/milestones/1"
    },
    "merge_when_pipeline_succeeds": true,
    "merge_status": "can_be_merged",
    "detailed_merge_status": "not_open",
    "sha": "8888888888888888888888888888888888888888",
    "merge_commit_sha": null,
    "squash_commit_sha": null,
    "user_notes_count": 1,
    "discussion_locked": null,
    "should_remove_source_branch": true,
    "force_remove_source_branch": false,
    "allow_collaboration": false,
    "allow_maintainer_to_push": false,
    "web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
    "references": {
      "short": "!1",
      "relative": "my-group/my-project!1",
      "full": "my-group/my-project!1"
    },
    "time_stats": {
      "time_estimate": 0,
      "total_time_spent": 0,
      "human_time_estimate": null,
      "human_total_time_spent": null
    },
    "squash": false,
    "task_completion_status":{
      "count":0,
      "completed_count":0
    }
  }
]

Merge requests list response notes

  • Listing merge requests might not proactively update merge_status (which also affects the has_conflicts), as this can be an expensive operation. If you need the value of these fields from this endpoint, set the with_merge_status_recheck parameter to true in the query.
  • For notes on merge request object fields, see single merge request response notes.

List project merge requests

List all merge requests for a project.

GET /projects/:id/merge_requests
GET /projects/:id/merge_requests?state=opened
GET /projects/:id/merge_requests?state=all
GET /projects/:id/merge_requests?iids[]=42&iids[]=43
GET /projects/:id/merge_requests?milestone=release
GET /projects/:id/merge_requests?labels=bug,reproduced
GET /projects/:id/merge_requests?my_reaction_emoji=star

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of the project.
iids[]integer arrayNoReturns merge requests matching the provided IIDs.
approved_by_ids[]integer arrayNoReturns merge requests approved by all the users with the given id, up to 5 users. None returns merge requests with no approvals. Any returns merge requests with an approval.
approved_by_usernames[]string arrayNoReturns merge requests approved by all the users with the given username, up to 5 users. None returns merge requests with no approvals. Any returns merge requests with an approval.
approver_ids[]integer arrayNoReturns merge requests which have all users with the specified id as eligible approvers according to the approval rules. None returns merge requests with no eligible approvers. Any returns merge requests with at least one eligible approver. Premium and Ultimate only.
assignee_idinteger or stringNoReturns merge requests assigned to the given user id. None returns unassigned merge requests. Any returns merge requests with an assignee. Mutually exclusive with assignee_username.
assignee_username[]string arrayNoReturns merge requests assigned to the given usernames. Mutually exclusive with assignee_id.
author_idintegerNoReturns merge requests created by the given user id. Mutually exclusive with author_username.
author_usernamestringNoReturns merge requests created by the given username. Mutually exclusive with author_id.
created_afterdatetimeNoReturns merge requests created on or after the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
created_beforedatetimeNoReturns merge requests created on or before the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
deployed_afterdatetimeNoReturns merge requests deployed after the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
deployed_beforedatetimeNoReturns merge requests deployed before the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
merged_afterdatetimeNoReturns merge requests merged on or after the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
merged_beforedatetimeNoReturns merge requests merged on or before the given date and time. Expected in ISO 8601 format (2019-03-15T08:00:00Z).
environmentstringNoReturns merge requests deployed to the given environment.
instringNoChange the scope of the search attribute. title, description, or a string joining them with comma. Default is title,description.
labelsstringNoReturns merge requests matching a comma-separated list of labels. None lists all merge requests with no labels. Any lists all merge requests with at least one label. Predefined names are case-insensitive.
merge_user_idintegerNoReturns merge requests merged by the user with the given user id. Mutually exclusive with merge_user_username. Introduced in GitLab 17.0.
merge_user_usernamestringNoReturns merge requests merged by the user with the given username. Mutually exclusive with merge_user_id. Introduced in GitLab 17.0.
milestonestringNoReturns merge requests for a specific milestone. None returns merge requests with no milestone. Any returns merge requests that have an assigned milestone.
my_reaction_emojistringNoReturns merge requests reacted by the authenticated user by the given emoji. None returns issues not given a reaction. Any returns issues given at least one reaction.
nothashNoReturns merge requests that do not match the parameters supplied. Accepts: labels, milestone, author_id, author_username, assignee_id, assignee_username, reviewer_id, reviewer_username, my_reaction_emoji.
order_bystringNoReturns merge requests ordered by created_at, updated_at, merged_at (introduced in GitLab 17.2), label_priority, priority, milestone_due, popularity, or title fields. Default is created_at.
reviewer_idinteger or stringNoReturns merge requests which have the user as a