Use this API to retrieve the merge trains of a project. These endpoints require the Developer, Maintainer, or Owner role, and support offset-based pagination.

Each object in a response represents one merge request in a train, not an entire train. Requesting merge trains without a target branch can return entries from more than one train in the project.

Responses do not include an explicit queue position, and return merge requests as a flat list rather than grouped by train:

Read every merge train of a project

GET /api/v4/projects/{id}/merge_trains

Returns the cars of all the trains of the project at once. Cars of different target branches are mixed together, so read one train instead when the queue of a single branch is what matters.

Parameters

NameTypeDescription
id
Path, required
String or integerThe ID or URL-encoded path of the project
Example: 11
scope
Query
StringLimit the response to cars still queued (active) or to cars that have left the queue (complete)
Allowed values: active, complete
Example: active
sort
Query
StringOrder the cars by their position, oldest or newest first
Allowed values: asc, desc
Default: desc
page
Query
IntegerCurrent page number
Default: 1
Example: 1
per_page
Query
IntegerNumber of items per page
Default: 20
Example: 20

Responses

CodeDescriptionSchema
200OKAPIEntitiesMergeTrainsCar
400Bad Request—
401Unauthorized—
403Forbidden—
404Not found—

Read the place of a merge request in its merge train

GET /api/v4/projects/{id}/merge_trains/merge_requests/{merge_request_iid}

Returns the car that represents the merge request in the train of its target branch.

Parameters

NameTypeDescription
id
Path, required
String or integerThe ID or URL-encoded path of the project
Example: 11
merge_request_iid
Path, required
IntegerIID of the merge request
Example: 1

Responses

CodeDescriptionSchema
200OKAPIEntitiesMergeTrainsCar
400Bad Request—
401Unauthorized—
403Forbidden—
404Not found—

Queue a merge request on a merge train

POST /api/v4/projects/{id}/merge_trains/merge_requests/{merge_request_iid}

Puts the merge request at the back of the train of its target branch, or has it join the queue once its merge checks pass.

Parameters

NameTypeDescription
id
Path, required
String or integerThe ID or URL-encoded path of the project
Example: 11
merge_request_iid
Path, required
IntegerIID of the merge request
Example: 1

Request body (application/json)

PropertyTypeDescription
auto_mergeBooleanQueue the merge request instead of merging it right away
shaStringHead of the source branch as the caller last saw it. The request is rejected when it moved
squashBooleanSquash the commits of the source branch into one when the merge request merges

Responses

CodeDescriptionSchema
201CreatedAPIEntitiesMergeTrainsCar
202AcceptedAPIEntitiesMergeTrainsCar
400Cannot be queued—
401Unauthorized—
403Forbidden—
404Not found—
409Conflict—

Read the merge train of a target branch

GET /api/v4/projects/{id}/merge_trains/{target_branch}

Returns the cars queued for one target branch, in queue order.

Parameters

NameTypeDescription
id
Path, required
String or integerThe ID or URL-encoded path of the project
Example: 11
target_branch
Path, required
StringTarget branch whose train to read
Example: main
scope
Query
StringLimit the response to cars still queued (active) or to cars that have left the queue (complete)
Allowed values: active, complete
Example: active
sort
Query
StringOrder the cars by their position, oldest or newest first
Allowed values: asc, desc
Default: desc
page
Query
IntegerCurrent page number
Default: 1
Example: 1
per_page
Query
IntegerNumber of items per page
Default: 20
Example: 20

Responses

CodeDescriptionSchema
200OKAPIEntitiesMergeTrainsCar
400Bad Request—
401Unauthorized—
403Forbidden—
404Not found—

Schemas

Objects returned by the operations above and objects nested in their request bodies.

APIEntitiesCiPipelineBasic

PropertyTypeDescription
created_atString (date-time)Example: 2022-10-21T16:49:48.000+02:00
idInteger (int64)Example: 1
iidIntegerExample: 2
project_idInteger (int64)Example: 3
refStringExample: feature-branch
shaStringExample: 0ec9e58fdfca6cdd6652c083c9edb53abc0bad52
sourceStringExample: push
statusStringExample: success
updated_atString (date-time)Example: 2022-10-21T16:49:48.000+02:00
web_urlStringExample: https://gitlab.example.com/gitlab-org/gitlab-foss/-/pipelines/61

APIEntitiesCustomAttribute

PropertyTypeDescription
keyStringExample: foo
valueStringExample: bar

APIEntitiesMergeRequestSimple

PropertyTypeDescription
created_atString (date-time)Example: 2022-08-17T12:46:35.053Z
descriptionStringExample: Repellendus impedit et vel velit dignissimos.
idInteger (int64)Example: 84
iidIntegerExample: 14
project_idInteger (int64)Example: 4
stateStringExample: closed
titleStringExample: Test MR 1580978354
updated_atString (date-time)Example: 2022-11-14T17:22:01.470Z
web_urlStringExample: http://local.gitlab.test:8181/root/merge-train-race-condition/-/merge_requests/59

APIEntitiesMergeTrainsCar

PropertyTypeDescription
created_atString (date-time)Example: 2026-03-05T09:15:00.000Z
durationIntegerSeconds between queueing and merging
Example: 480
idIntegerExample: 7
merge_requestAPIEntitiesMergeRequestSimple—
merged_atString (date-time)Example: 2026-03-05T09:23:00.000Z
pipelineAPIEntitiesCiPipelineBasic—
statusStringWhere the car stands in its queue
Allowed values: idle, merged, stale, fresh, merging, skip_merged
Example: merged
target_branchStringExample: main
updated_atString (date-time)Example: 2026-03-05T09:23:00.000Z
userAPIEntitiesUserBasic—

APIEntitiesUserBasic

PropertyTypeDescription
avatar_pathStringExample: /user/avatar/28/The-Big-Lebowski-400-400.png
avatar_urlStringExample: https://gravatar.com/avatar/1
custom_attributesArray of APIEntitiesCustomAttribute—
idInteger (int64)Example: 1
lockedBoolean—
nameStringExample: Administrator
public_emailStringExample: john@example.com
stateStringExample: active
usernameStringExample: admin
web_urlStringExample: https://gitlab.example.com/root