Merge request approvals API

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

This API manages the configuration for approvals on merge requests in your project or group:

  • Approve and unapprove a merge request as a user.
  • Reset all approvals, not just your own, on a merge request.
  • View and manage approval rules for a project.

All endpoints require authentication.

Approve merge request

Approves the specified merge request. The currently authenticated user must be an eligible approver.

The sha parameter ensures you’re approving the current version of the merge request. If defined, the value must match the merge request’s HEAD commit SHA. A mismatch returns a 409 Conflict response. This matches the behavior accepting a merge request.

POST /projects/:id/merge_requests/:merge_request_iid/approve

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approval_passwordstringNoCurrent user’s password. Required if Require user re-authentication to approve is enabled in the project settings. Always fails if the group or GitLab Self-Managed instance is configured to force SAML authentication.
merge_request_iidintegerYesThe IID of the merge request.
shastringNoThe HEAD of the merge request.
{
  "id": 5,
  "iid": 5,
  "project_id": 1,
  "title": "Approvals API",
  "description": "Test",
  "state": "opened",
  "created_at": "2016-06-08T00:19:52.638Z",
  "updated_at": "2016-06-09T21:32:14.105Z",
  "merge_status": "can_be_merged",
  "approvals_required": 2,
  "approvals_left": 0,
  "approved_by": [
    {
      "user": {
        "name": "Administrator",
        "username": "root",
        "id": 1,
        "state": "active",
        "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",
        "web_url": "http://localhost:3000/root"
      }
    },
    {
      "user": {
        "name": "Nico Cartwright",
        "username": "ryley",
        "id": 2,
        "state": "active",
        "avatar_url": "http://www.gravatar.com/avatar/cf7ad14b34162a76d593e3affca2adca?s=80\u0026d=identicon",
        "web_url": "http://localhost:3000/ryley"
      }
    }
  ]
}

Approvals for automated merge requests

If you use the API to create and immediately approve a merge request, your automation might approve the merge request before the commit is fully processed. By default, adding a new commit to a merge request resets any existing approvals. When this happens, the Activity area of the merge request shows a sequence of messages like this:

  • (botname) approved this merge request 5 minutes ago
  • (botname) added 1 commit 5 minutes ago
  • (botname) reset approvals from (botname) by pushing to the branch 5 minutes ago

To ensure automated approvals are not applied before commit processing is complete, your automation should add a wait (or sleep) function until:

  • The detailed_merge_status attribute is not in either the checking or approvals_syncing states.
  • The merge request diff contains a patch_id_sha that is not NULL.

Unapprove a merge request

Removes the approval for the currently authenticated user from a specified merge request.

POST /projects/:id/merge_requests/:merge_request_iid/unapprove

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
merge_request_iidintegerYesThe IID of a merge request.

Reset approvals for a merge request

Resets all approvals for a specified merge request.

Available only to bot users with a valid project or group token. Human users receive a 401 Unauthorized response.

PUT /projects/:id/merge_requests/:merge_request_iid/reset_approvals
AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of the project.
merge_request_iidintegerYesThe internal ID of the merge request.
curl --request PUT \
  --header "PRIVATE-TOKEN: <your_access_token>" \
  --url "https://gitlab.example.com/api/v4/projects/76/merge_requests/1/reset_approvals"

Approval rules for projects

These endpoints apply to projects and their approval rules. All endpoints require authentication.

Retrieve approval configuration for a project

Retrieves the approval configuration for a project.

GET /projects/:id/approvals

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
{
  "approvers": [], // Deprecated in GitLab 12.3, always returns empty
  "approver_groups": [], // Deprecated in GitLab 12.3, always returns empty
  "approvals_before_merge": 2, // Deprecated in GitLab 12.3, use Approval Rules instead
  "reset_approvals_on_push": true,
  "selective_code_owner_removals": false,
  "disable_overriding_approvers_per_merge_request": false,
  "merge_requests_author_approval": true,
  "merge_requests_disable_committers_approval": false,
  "require_password_to_approve": true, // Deprecated in 16.9, use require_reauthentication_to_approve instead
  "require_reauthentication_to_approve": true
}

Update approval configuration for a project

Updates the approval configuration for a project. The currently authenticated user must be an eligible approver.

POST /projects/:id/approvals

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approvals_before_merge (deprecated)integerNoThe number of required approvals before a merge request can merge. Deprecated in GitLab 12.3. Create an approval rule instead.
disable_overriding_approvers_per_merge_requestbooleanNoIf true, prevents overrides of approvers in a merge request.
merge_requests_author_approvalbooleanNoIf true, authors can self-approve their own merge requests.
merge_requests_disable_committers_approvalbooleanNoIf true, users who commit on a merge request cannot approve it.
require_password_to_approve (deprecated)booleanNoIf true, require approvers to authenticate with a password before adding the approval. Deprecated in GitLab 16.9. Use require_reauthentication_to_approve instead.
require_reauthentication_to_approvebooleanNoIf true, requires approver to authenticate before adding the approval. Introduced in GitLab 17.1.
reset_approvals_on_pushbooleanNoIf true, approvals are reset on push.
selective_code_owner_removalsbooleanNoIf true, resets approvals from Code Owners if their files change. To use this field, reset_approvals_on_push must be false.
{
  "approvals_before_merge": 2, // Use Approval Rules instead
  "reset_approvals_on_push": true,
  "selective_code_owner_removals": false,
  "disable_overriding_approvers_per_merge_request": false,
  "merge_requests_author_approval": false,
  "merge_requests_disable_committers_approval": false,
  "require_password_to_approve": true,
  "require_reauthentication_to_approve": true
}

List all approval rules for a project

Lists all approval rules and any associated details for a specified project.

GET /projects/:id/approval_rules

To restrict the list of approval rules, use the page and per_page pagination parameters.

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
[
  {
    "id": 1,
    "name": "security",
    "rule_type": "regular",
    "report_type": null,
    "eligible_approvers": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      },
      {
        "id": 50,
        "name": "Group Member 1",
        "username": "group_member_1",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/group_member_1"
      }
    ],
    "approvals_required": 3,
    "users": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      }
    ],
    "groups": [
      {
        "id": 5,
        "name": "group1",
        "path": "group1",
        "description": "",
        "visibility": "public",
        "lfs_enabled": false,
        "avatar_url": null,
        "web_url": "http://localhost/groups/group1",
        "request_access_enabled": false,
        "full_name": "group1",
        "full_path": "group1",
        "parent_id": null,
        "ldap_cn": null,
        "ldap_access": null
      }
    ],
    "applies_to_all_protected_branches": false,
    "protected_branches": [
      {
        "id": 1,
        "name": "main",
        "push_access_levels": [
          {
            "access_level": 30,
            "access_level_description": "Developers + Maintainers"
          }
        ],
        "merge_access_levels": [
          {
            "access_level": 30,
            "access_level_description": "Developers + Maintainers"
          }
        ],
        "unprotect_access_levels": [
          {
            "access_level": 40,
            "access_level_description": "Maintainers"
          }
        ],
        "code_owner_approval_required": "false"
      }
    ],
    "contains_hidden_groups": false,
  },
  {
    "id": 2,
    "name": "Coverage-Check",
    "rule_type": "report_approver",
    "report_type": "code_coverage",
    "eligible_approvers": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      },
      {
        "id": 50,
        "name": "Group Member 1",
        "username": "group_member_1",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/group_member_1"
      }
    ],
    "approvals_required": 3,
    "users": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      }
    ],
    "groups": [
      {
        "id": 5,
        "name": "group1",
        "path": "group1",
        "description": "",
        "visibility": "public",
        "lfs_enabled": false,
        "avatar_url": null,
        "web_url": "http://localhost/groups/group1",
        "request_access_enabled": false,
        "full_name": "group1",
        "full_path": "group1",
        "parent_id": null,
        "ldap_cn": null,
        "ldap_access": null
      }
    ],
    "applies_to_all_protected_branches": false,
    "protected_branches": [
      {
        "id": 1,
        "name": "main",
        "push_access_levels": [
          {
            "access_level": 30,
            "access_level_description": "Developers + Maintainers"
          }
        ],
        "merge_access_levels": [
          {
            "access_level": 30,
            "access_level_description": "Developers + Maintainers"
          }
        ],
        "unprotect_access_levels": [
          {
            "access_level": 40,
            "access_level_description": "Maintainers"
          }
        ],
        "code_owner_approval_required": "false"
      }
    ],
    "contains_hidden_groups": false,
  }
]

Retrieve an approval rule for a project

Retrieves information about a specified approval rule for a project.

GET /projects/:id/approval_rules/:approval_rule_id

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approval_rule_idintegerYesThe ID of a approval rule.
{
  "id": 1,
  "name": "security",
  "rule_type": "regular",
  "report_type": null,
  "eligible_approvers": [
    {
      "id": 5,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    },
    {
      "id": 50,
      "name": "Group Member 1",
      "username": "group_member_1",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/group_member_1"
    }
  ],
  "approvals_required": 3,
  "users": [
    {
      "id": 5,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    }
  ],
  "groups": [
    {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "description": "",
      "visibility": "public",
      "lfs_enabled": false,
      "avatar_url": null,
      "web_url": "http://localhost/groups/group1",
      "request_access_enabled": false,
      "full_name": "group1",
      "full_path": "group1",
      "parent_id": null,
      "ldap_cn": null,
      "ldap_access": null
    }
  ],
  "applies_to_all_protected_branches": false,
  "protected_branches": [
    {
      "id": 1,
      "name": "main",
      "push_access_levels": [
        {
          "access_level": 30,
          "access_level_description": "Developers + Maintainers"
        }
      ],
      "merge_access_levels": [
        {
          "access_level": 30,
          "access_level_description": "Developers + Maintainers"
        }
      ],
      "unprotect_access_levels": [
        {
          "access_level": 40,
          "access_level_description": "Maintainers"
        }
      ],
      "code_owner_approval_required": "false"
    }
  ],
  "contains_hidden_groups": false
}

Create an approval rule for a project

Creates an approval rule for a project.

The rule_type field supports these rule types:

  • any_approver: A pre-configured default rule with approvals_required set to 0.
  • regular: Used for regular merge request approval rules.
  • report_approver: Used when GitLab creates an approval rule from configured and enabled merge request approval policies. Do not use this value when creating approval rules with this API.
POST /projects/:id/approval_rules

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approvals_requiredintegerYesThe number of required approvals for this rule.
namestringYesThe name of the approval rule. Limited to 1024 characters.
applies_to_all_protected_branchesbooleanNoIf true, applies the rule to all protected branches and ignores the protected_branch_ids attribute.
group_idsArrayNoThe IDs of groups as approvers.
protected_branch_idsArrayNoThe IDs of protected branches to scope the rule by. To identify the ID, use the List protected branches API.
report_typestringNoThe report type. Required when the rule type is report_approver. The supported report types are license_scanning (Deprecated in GitLab 15.9) and code_coverage.
rule_typestringNoThe rule type. Supported values include any_approver, regular, and report_approver.
user_idsArrayNoThe IDs of users as approvers. If used with usernames, adds both lists of users.
usernamesstring arrayNoThe usernames of approvers. If used with user_ids, adds both lists of users.
{
  "id": 1,
  "name": "security",
  "rule_type": "regular",
  "eligible_approvers": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    },
    {
      "id": 50,
      "name": "Group Member 1",
      "username": "group_member_1",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/group_member_1"
    }
  ],
  "approvals_required": 1,
  "users": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    }
  ],
  "groups": [
    {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "description": "",
      "visibility": "public",
      "lfs_enabled": false,
      "avatar_url": null,
      "web_url": "http://localhost/groups/group1",
      "request_access_enabled": false,
      "full_name": "group1",
      "full_path": "group1",
      "parent_id": null,
      "ldap_cn": null,
      "ldap_access": null
    }
  ],
  "applies_to_all_protected_branches": false,
  "protected_branches": [
    {
      "id": 1,
      "name": "main",
      "push_access_levels": [
        {
          "access_level": 30,
          "access_level_description": "Developers + Maintainers"
        }
      ],
      "merge_access_levels": [
        {
          "access_level": 30,
          "access_level_description": "Developers + Maintainers"
        }
      ],
      "unprotect_access_levels": [
        {
          "access_level": 40,
          "access_level_description": "Maintainers"
        }
      ],
      "code_owner_approval_required": "false"
    }
  ],
  "contains_hidden_groups": false
}

To increase the default number of 0 required approvers:

curl --request POST \
  --header "PRIVATE-TOKEN: <your_access_token>" \
  --header 'Content-Type: application/json' \
  --data '{"name": "Any name", "rule_type": "any_approver", "approvals_required": 2}' \
  --url "https://gitlab.example.com/api/v4/projects/<project_id>/approval_rules"

Another example is to create a user-specific rule:

curl --request POST \
  --header "PRIVATE-TOKEN: <your_access_token>" \
  --header 'Content-Type: application/json' \
  --data '{"name": "Name of your rule", "approvals_required": 3, "user_ids": [123, 456, 789]}' \
  --url "https://gitlab.example.com/api/v4/projects/<project_id>/approval_rules"

Update an approval rule for a project

Updates a specified approval rule for a project. This endpoint removes any approvers and groups not defined in the group_ids, user_ids, or usernames attributes.

Hidden groups (private groups the user doesn’t have permission to view) that are not in the users or groups parameters are preserved by default. To remove them, set remove_hidden_groups to true. This ensures hidden groups are not removed unintentionally when a user updates an approval rule.

PUT /projects/:id/approval_rules/:approval_rule_id

Supported attributes:

AttributeTypeRequiredDescription
approval_rule_idintegerYesThe ID of a approval rule.
idinteger or stringYesThe ID or URL-encoded path of a project.
applies_to_all_protected_branchesbooleanNoIf true, applies the rule to all protected branches and ignores the protected_branch_ids attribute.
approvals_requiredintegerNoThe number of required approvals for this rule.
group_idsArrayNoThe IDs of groups as approvers.
namestringNoThe name of the approval rule. Limited to 1024 characters.
protected_branch_idsArrayNoThe IDs of protected branches to scope the rule by. To identify the ID, use the List protected branches API.
remove_hidden_groupsbooleanNoIf true, removes hidden groups from the approval rule.
user_idsArrayNoThe IDs of users as approvers. If used with usernames, adds both lists of users.
usernamesstring arrayNoThe usernames of approvers. If used with user_ids, adds both lists of users.
{
  "id": 1,
  "name": "security",
  "rule_type": "regular",
  "eligible_approvers": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    },
    {
      "id": 50,
      "name": "Group Member 1",
      "username": "group_member_1",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/group_member_1"
    }
  ],
  "approvals_required": 1,
  "users": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    }
  ],
  "groups": [
    {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "description": "",
      "visibility": "public",
      "lfs_enabled": false,
      "avatar_url": null,
      "web_url": "http://localhost/groups/group1",
      "request_access_enabled": false,
      "full_name": "group1",
      "full_path": "group1",
      "parent_id": null,
      "ldap_cn": null,
      "ldap_access": null
    }
  ],
  "applies_to_all_protected_branches": false,
  "protected_branches": [
    {
      "id": 1,
      "name": "main",
      "push_access_levels": [
        {
          "access_level": 30,
          "access_level_description": "Developers + Maintainers"
        }
      ],
      "merge_access_levels": [
        {
          "access_level": 30,
          "access_level_description": "Developers + Maintainers"
        }
      ],
      "unprotect_access_levels": [
        {
          "access_level": 40,
          "access_level_description": "Maintainers"
        }
      ],
      "code_owner_approval_required": "false"
    }
  ],
  "contains_hidden_groups": false
}

Delete an approval rule for a project

Deletes an approval rule for a specified project.

DELETE /projects/:id/approval_rules/:approval_rule_id

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approval_rule_idintegerYesThe ID of a approval rule.

Approval rules for a merge request

These endpoints apply to individual merge requests. All endpoints require authentication.

Retrieve approval state for a merge request

Retrieves the approval state for a specified merge request. For detailed information about the users who have already approved, and whether an approval rule is satisfied, see retrieve approval details for a merge request.

GET /projects/:id/merge_requests/:merge_request_iid/approvals

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
merge_request_iidintegerYesThe IID of the merge request.
{
  "id": 5,
  "iid": 5,
  "project_id": 1,
  "title": "Approvals API",
  "description": "Test",
  "state": "opened",
  "created_at": "2016-06-08T00:19:52.638Z",
  "updated_at": "2016-06-08T21:20:42.470Z",
  "merge_status": "cannot_be_merged",
  "approvals_required": 2,
  "approvals_left": 1,
  "approved_by": [
    {
      "user": {
        "name": "Administrator",
        "username": "root",
        "id": 1,
        "state": "active",
        "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",
        "web_url": "http://localhost:3000/root"
      }
    }
  ]
}

Retrieve approval details for a merge request

Retrieves approval details for a specified merge request.

If a user has modified the approval rules for the merge request, the response includes:

  • approval_rules_overwritten: If true, indicates the default approval rules were modified.
  • approved: If true, indicates that the associated approval rule was approved.
  • approved_by: If defined, indicates the details of the user that approved the associated approval rule.
GET /projects/:id/merge_requests/:merge_request_iid/approval_state

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
merge_request_iidintegerYesThe IID of the merge request.
{
  "approval_rules_overwritten": true,
  "rules": [
    {
      "id": 1,
      "name": "Ruby",
      "rule_type": "regular",
      "eligible_approvers": [
        {
          "id": 4,
          "name": "John Doe",
          "username": "jdoe",
          "state": "active",
          "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
          "web_url": "http://localhost/jdoe"
        }
      ],
      "approvals_required": 2,
      "users": [
        {
          "id": 4,
          "name": "John Doe",
          "username": "jdoe",
          "state": "active",
          "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
          "web_url": "http://localhost/jdoe"
        }
      ],
      "groups": [],
      "contains_hidden_groups": false,
      "approved_by": [
        {
          "id": 4,
          "name": "John Doe",
          "username": "jdoe",
          "state": "active",
          "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
          "web_url": "http://localhost/jdoe"
        }
      ],
      "source_rule": null,
      "approved": true,
      "overridden": false
    }
  ]
}

List all approval rules for a merge request

Lists all approval rules and any associated details for a specified merge request.

Use the page and per_page pagination parameters to restrict the list of approval rules.

GET /projects/:id/merge_requests/:merge_request_iid/approval_rules

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
merge_request_iidintegerYesThe IID of the merge request.
[
  {
    "id": 1,
    "name": "security",
    "rule_type": "regular",
    "report_type": null,
    "eligible_approvers": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      },
      {
        "id": 50,
        "name": "Group Member 1",
        "username": "group_member_1",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/group_member_1"
      }
    ],
    "approvals_required": 3,
    "source_rule": null,
    "users": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      }
    ],
    "groups": [
      {
        "id": 5,
        "name": "group1",
        "path": "group1",
        "description": "",
        "visibility": "public",
        "lfs_enabled": false,
        "avatar_url": null,
        "web_url": "http://localhost/groups/group1",
        "request_access_enabled": false,
        "full_name": "group1",
        "full_path": "group1",
        "parent_id": null,
        "ldap_cn": null,
        "ldap_access": null
      }
    ],
    "contains_hidden_groups": false,
    "overridden": false
  },
  {
    "id": 2,
    "name": "Coverage-Check",
    "rule_type": "report_approver",
    "report_type": "code_coverage",
    "eligible_approvers": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      },
      {
        "id": 50,
        "name": "Group Member 1",
        "username": "group_member_1",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/group_member_1"
      }
    ],
    "approvals_required": 3,
    "source_rule": null,
    "users": [
      {
        "id": 5,
        "name": "John Doe",
        "username": "jdoe",
        "state": "active",
        "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
        "web_url": "http://localhost/jdoe"
      }
    ],
    "groups": [
      {
        "id": 5,
        "name": "group1",
        "path": "group1",
        "description": "",
        "visibility": "public",
        "lfs_enabled": false,
        "avatar_url": null,
        "web_url": "http://localhost/groups/group1",
        "request_access_enabled": false,
        "full_name": "group1",
        "full_path": "group1",
        "parent_id": null,
        "ldap_cn": null,
        "ldap_access": null
      }
    ],
    "contains_hidden_groups": false,
    "overridden": false
  }
]

Retrieve an approval rule for a specific merge request

Retrieves information about an approval rule for a specific merge request.

GET /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approval_rule_idintegerYesThe ID of an approval rule.
merge_request_iidintegerYesThe IID of a merge request.
{
  "id": 1,
  "name": "security",
  "rule_type": "regular",
  "report_type": null,
  "eligible_approvers": [
    {
      "id": 5,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    },
    {
      "id": 50,
      "name": "Group Member 1",
      "username": "group_member_1",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/group_member_1"
    }
  ],
  "approvals_required": 3,
  "source_rule": null,
  "users": [
    {
      "id": 5,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    }
  ],
  "groups": [
    {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "description": "",
      "visibility": "public",
      "lfs_enabled": false,
      "avatar_url": null,
      "web_url": "http://localhost/groups/group1",
      "request_access_enabled": false,
      "full_name": "group1",
      "full_path": "group1",
      "parent_id": null,
      "ldap_cn": null,
      "ldap_access": null
    }
  ],
  "contains_hidden_groups": false,
  "overridden": false
}

Create an approval rule for a merge request

Creates an approval rule for a specific merge request. If approval_project_rule_id is set with the ID of an existing approval rule from the project, this endpoint:

  • Copies the values for name, users, and groups from the project’s rule.
  • Uses the approvals_required value you specify.
POST /projects/:id/merge_requests/:merge_request_iid/approval_rules

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approvals_requiredintegerYesThe number of required approvals for this rule.
merge_request_iidintegerYesThe IID of the merge request.
namestringYesThe name of the approval rule. Limited to 1024 characters.
approval_project_rule_idintegerNoThe ID of a project’s approval rule.
group_idsArrayNoThe IDs of groups as approvers.
user_idsArrayNoThe IDs of users as approvers. If used with usernames, adds both lists of users.
usernamesstring arrayNoThe usernames of approvers. If used with user_ids, adds both lists of users.
{
  "id": 1,
  "name": "security",
  "rule_type": "regular",
  "eligible_approvers": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    },
    {
      "id": 50,
      "name": "Group Member 1",
      "username": "group_member_1",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/group_member_1"
    }
  ],
  "approvals_required": 1,
  "source_rule": null,
  "users": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    }
  ],
  "groups": [
    {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "description": "",
      "visibility": "public",
      "lfs_enabled": false,
      "avatar_url": null,
      "web_url": "http://localhost/groups/group1",
      "request_access_enabled": false,
      "full_name": "group1",
      "full_path": "group1",
      "parent_id": null,
      "ldap_cn": null,
      "ldap_access": null
    }
  ],
  "contains_hidden_groups": false,
  "overridden": false
}

Update an approval rule for a merge request

Updates a specified approval rule for a merge request. This endpoint removes any approvers and groups not included in the group_ids, user_ids, or usernames attributes.

The report_approver or code_owner rules are system-generated, and you cannot edit them.

PUT /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approval_rule_idintegerYesThe ID of an approval rule.
merge_request_iidintegerYesThe IID of a merge request.
approvals_requiredintegerNoThe number of required approvals for this rule.
group_idsArrayNoThe IDs of groups as approvers.
namestringNoThe name of the approval rule. Limited to 1024 characters.
remove_hidden_groupsbooleanNoIf true, removes hidden groups.
user_idsArrayNoThe IDs of users as approvers. If used with usernames, adds both lists of users.
usernamesstring arrayNoThe usernames of approvers. If used with user_ids, adds both lists of users.
{
  "id": 1,
  "name": "security",
  "rule_type": "regular",
  "eligible_approvers": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    },
    {
      "id": 50,
      "name": "Group Member 1",
      "username": "group_member_1",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/group_member_1"
    }
  ],
  "approvals_required": 1,
  "source_rule": null,
  "users": [
    {
      "id": 2,
      "name": "John Doe",
      "username": "jdoe",
      "state": "active",
      "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
      "web_url": "http://localhost/jdoe"
    }
  ],
  "groups": [
    {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "description": "",
      "visibility": "public",
      "lfs_enabled": false,
      "avatar_url": null,
      "web_url": "http://localhost/groups/group1",
      "request_access_enabled": false,
      "full_name": "group1",
      "full_path": "group1",
      "parent_id": null,
      "ldap_cn": null,
      "ldap_access": null
    }
  ],
  "contains_hidden_groups": false,
  "overridden": false
}

Delete an approval rule for a merge request

Deletes an approval rule for a specified merge request.

DELETE /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id

The report_approver or code_owner rules are system-generated, and you cannot edit them.

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.
approval_rule_idintegerYesThe ID of an approval rule.
merge_request_iidintegerYesThe IID of the merge request.

Approval rules for groups

  • Status: Experiment
History

On GitLab Self-Managed, by default this feature is not available. To make it available, an administrator can enable the feature flag named approval_group_rules. On GitLab.com and GitLab Dedicated, this feature is not available. This feature is not ready for production use.

Group approval rules apply to all protected branches of projects belonging to the group.

List all approval rules for a group

History

Lists all approval rules and any associated details for a specified group. Restricted to group administrators.

Use the page and per_page pagination parameters to restrict the list of approval rules.

GET /groups/:id/approval_rules

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a project.

Example request:

curl --request GET \
  --header "PRIVATE-TOKEN: <your_access_token>" \
  --url "https://gitlab.example.com/api/v4/groups/29/approval_rules"

Example response:

[
  {
    "id": 2,
    "name": "rule1",
    "rule_type": "any_approver",
    "report_type": null,
    "eligible_approvers": [],
    "approvals_required": 3,
    "users": [],
    "groups": [],
    "contains_hidden_groups": false,
    "protected_branches": [],
    "applies_to_all_protected_branches": true
  },
  {
    "id": 3,
    "name": "rule2",
    "rule_type": "code_owner",
    "report_type": null,
    "eligible_approvers": [],
    "approvals_required": 2,
    "users": [],
    "groups": [],
    "contains_hidden_groups": false,
    "protected_branches": [],
    "applies_to_all_protected_branches": true
  },
  {
    "id": 4,
    "name": "rule2",
    "rule_type": "report_approver",
    "report_type": "code_coverage",
    "eligible_approvers": [],
    "approvals_required": 2,
    "users": [],
    "groups": [],
    "contains_hidden_groups": false,
    "protected_branches": [],
    "applies_to_all_protected_branches": true
  }
]

Create an approval rule for a group

Creates an approval rule for a group. Restricted to group administrators.

Don’t use the rule_type field when building approval rules from the API. The field supports these rule types:

POST /groups/:id/approval_rules

Supported attributes:

AttributeTypeRequiredDescription
idinteger or stringYesThe ID or URL-encoded path of a group.
approvals_requiredintegerYesThe number of required approvals for this rule.
namestringYesThe name of the approval rule. Limited to 1024 characters.
group_idsarrayNoThe IDs of groups as approvers.
rule_typestringNoThe rule type. Supported values include any_approver, regular, and report_approver.
user_idsarrayNoThe IDs of users as approvers.

Example request:

curl --request POST \
  --header "PRIVATE-TOKEN: <your_access_token>" \
  --url "https://gitlab.example.com/api/v4/groups/29/approval_rules?name=security&approvals_required=2"

Example response:

{
  "id": 5,
  "name": "security",
  "rule_type": "any_approver",
  "eligible_approvers": [],
  "approvals_required": 2,
  "users": [],
  "groups": [],
  "contains_hidden_groups": false,
  "protected_branches": [
    {
      "id": 5,
      "name": "master",
      "push_access_levels": [
        {
          "id": 5,
          "access_level": 40,
          "access_level_description": "Maintainers",
          "deploy_key_id": null,
          "user_id": null,
          "group_id": null
        }
      ],
      "merge_access_levels": [
        {
          "id": 5,
          "access_level": 40,
          "access_level_description": "Maintainers",
          "user_id": null,
          "group_id": null
        }
      ],
      "allow_force_push": false,
      "unprotect_access_levels": [],
      "code_owner_approval_required": false,
      "inherited": false
    }
  ],
  "applies_to_all_protected_branches": true
}

Update an approval rule for a group

History

Updates an approval rule for a group. Restricted to group administrators.

Don’t use the rule_type field when building approval rules from the API. The field supports these rule types:

PUT /groups/:id/approval_rules/:approval_rule_id

Supported attributes:

AttributeTypeRequiredDescription
approval_rule_id.integerYesThe ID of the approval rule.
idinteger or stringYesThe ID or URL-encoded path of a group.
approvals_requiredstringNoThe number of required approvals for this rule.
group_idsintegerNoThe IDs of users as approvers.
namestringNoThe name of the approval rule. Limited to 1024 characters.
rule_typearrayNoThe rule type. Supported values include any_approver, regular, and report_approver.
user_idsarrayNoThe IDs of groups as approvers.

Example request:

curl --request PUT \
  --header "PRIVATE-TOKEN: <your_access_token>" \
  --url "https://gitlab.example.com/api/v4/groups/29/approval_rules/5?name=security2&approvals_required=1"

Example response:

{
  "id": 5,
  "name": "security2",
  "rule_type": "any_approver",
  "eligible_approvers": [],
  "approvals_required": 1,
  "users": [],
  "groups": [],
  "contains_hidden_groups": false,
  "protected_branches": [
    {
      "id": 5,
      "name": "master",
      "push_access_levels": [
        {
          "id": 5,
          "access_level": 40,
          "access_level_description": "Maintainers",
          "deploy_key_id": null,
          "user_id": null,
          "group_id": null
        }
      ],
      "merge_access_levels": [
        {
          "id": 5,
          "access_level": 40,
          "access_level_description": "Maintainers",
          "user_id": null,
          "group_id": null
        }
      ],
      "allow_force_push": false,
      "unprotect_access_levels": [],
      "code_owner_approval_required": false,
      "inherited": false
    }
  ],
  "applies_to_all_protected_branches": true
}