# Table of Contents - [REST API resources | GitLab Docs](#rest-api-resources-gitlab-docs) - [Cleartext authentication | GitLab Docs](#cleartext-authentication-gitlab-docs) - [CORS | GitLab Docs](#cors-gitlab-docs) - [Geo API | GitLab Docs](#geo-api-gitlab-docs) - [Go Proxy API | GitLab Docs](#go-proxy-api-gitlab-docs) - [Google Cloud integration API | GitLab Docs](#google-cloud-integration-api-gitlab-docs) - [Framework debug mode | GitLab Docs](#framework-debug-mode-gitlab-docs) - [Feature flags API | GitLab Docs](#feature-flags-api-gitlab-docs) - [Flows API | GitLab Docs](#flows-api-gitlab-docs) - [GitLab To-Do List API | GitLab Docs](#gitlab-to-do-list-api-gitlab-docs) - [GLQL API | GitLab Docs](#glql-api-gitlab-docs) - [Geo sites API | GitLab Docs](#geo-sites-api-gitlab-docs) - [Geo Nodes API (deprecated) | GitLab Docs](#geo-nodes-api-deprecated-gitlab-docs) - [GraphQL API | GitLab Docs](#graphql-api-gitlab-docs) - [GraphQL API removed items | GitLab Docs](#graphql-api-removed-items-gitlab-docs) - [Group Markdown uploads API | GitLab Docs](#group-markdown-uploads-api-gitlab-docs) - [Group iterations API | GitLab Docs](#group-iterations-api-gitlab-docs) - [Group milestones API | GitLab Docs](#group-milestones-api-gitlab-docs) - [Group labels API | GitLab Docs](#group-labels-api-gitlab-docs) - [Group placeholder reassignments API | GitLab Docs](#group-placeholder-reassignments-api-gitlab-docs) - [Group issue boards API | GitLab Docs](#group-issue-boards-api-gitlab-docs) - [Group SSH certificates API | GitLab Docs](#group-ssh-certificates-api-gitlab-docs) - [Group push rules API | GitLab Docs](#group-push-rules-api-gitlab-docs) - [Heartbleed OpenSSL vulnerability | GitLab Docs](#heartbleed-openssl-vulnerability-gitlab-docs) - [Group release API | GitLab Docs](#group-release-api-gitlab-docs) - [Group security settings API | GitLab Docs](#group-security-settings-api-gitlab-docs) - [Insecure HTTP methods | GitLab Docs](#insecure-http-methods-gitlab-docs) - [Helm API | GitLab Docs](#helm-api-gitlab-docs) - [Group relations export API | GitLab Docs](#group-relations-export-api-gitlab-docs) - [Group-level protected branches API | GitLab Docs](#group-level-protected-branches-api-gitlab-docs) - [Group-level Variables API | GitLab Docs](#group-level-variables-api-gitlab-docs) - [Group wikis API | GitLab Docs](#group-wikis-api-gitlab-docs) - [Group-level protected environments API | GitLab Docs](#group-level-protected-environments-api-gitlab-docs) - [JSON injection | GitLab Docs](#json-injection-gitlab-docs) - [JSON hijacking | GitLab Docs](#json-hijacking-gitlab-docs) - [Interactive API documentation | GitLab Docs](#interactive-api-documentation-gitlab-docs) - [Instance clusters API (certificate-based) (deprecated) | GitLab Docs](#instance-clusters-api-certificate-based-deprecated-gitlab-docs) - [Identify issue boards by using GraphQL | GitLab Docs](#identify-issue-boards-by-using-graphql-gitlab-docs) - [HTML injection | GitLab Docs](#html-injection-gitlab-docs) - [Issue links API | GitLab Docs](#issue-links-api-gitlab-docs) - [LDAP group links | GitLab Docs](#ldap-group-links-gitlab-docs) - [Merge request context commits API | GitLab Docs](#merge-request-context-commits-api-gitlab-docs) - [Maven API | GitLab Docs](#maven-api-gitlab-docs) - [Merge request approval settings API | GitLab Docs](#merge-request-approval-settings-api-gitlab-docs) - [List branch rules for a project by using GraphQL | GitLab Docs](#list-branch-rules-for-a-project-by-using-graphql-gitlab-docs) - [Open redirect | GitLab Docs](#open-redirect-gitlab-docs) - [Metadata API | GitLab Docs](#metadata-api-gitlab-docs) - [Markdown uploads API | GitLab Docs](#markdown-uploads-api-gitlab-docs) - [Offline configuration | GitLab Docs](#offline-configuration-gitlab-docs) - [OS command injection | GitLab Docs](#os-command-injection-gitlab-docs) - [Overriding API fuzzing jobs | GitLab Docs](#overriding-api-fuzzing-jobs-gitlab-docs) - [Offline configuration | GitLab Docs](#offline-configuration-gitlab-docs) - [Overriding API security testing jobs | GitLab Docs](#overriding-api-security-testing-jobs-gitlab-docs) - [Model registry API | GitLab Docs](#model-registry-api-gitlab-docs) - [Path traversal | GitLab Docs](#path-traversal-gitlab-docs) - [Plan limits API | GitLab Docs](#plan-limits-api-gitlab-docs) - [npm API | GitLab Docs](#npm-api-gitlab-docs) - [Namespaces API | GitLab Docs](#namespaces-api-gitlab-docs) - [Project Aliases API | GitLab Docs](#project-aliases-api-gitlab-docs) - [Pages domains API | GitLab Docs](#pages-domains-api-gitlab-docs) - [Performance tuning and testing speed | GitLab Docs](#performance-tuning-and-testing-speed-gitlab-docs) - [Pipeline trigger tokens API | GitLab Docs](#pipeline-trigger-tokens-api-gitlab-docs) - [Performance tuning and testing speed | GitLab Docs](#performance-tuning-and-testing-speed-gitlab-docs) - [Project access tokens API | GitLab Docs](#project-access-tokens-api-gitlab-docs) - [NuGet API | GitLab Docs](#nuget-api-gitlab-docs) - [Product analytics API | GitLab Docs](#product-analytics-api-gitlab-docs) - [Project push rules API | GitLab Docs](#project-push-rules-api-gitlab-docs) - [Project iterations API | GitLab Docs](#project-iterations-api-gitlab-docs) - [Groups members API | GitLab Docs](#groups-members-api-gitlab-docs) - [Project statistics API | GitLab Docs](#project-statistics-api-gitlab-docs) - [Project milestones API | GitLab Docs](#project-milestones-api-gitlab-docs) - [Project badges API | GitLab Docs](#project-badges-api-gitlab-docs) - [Project-level Secure Files API | GitLab Docs](#project-level-secure-files-api-gitlab-docs) - [Project-level CI/CD variables API | GitLab Docs](#project-level-ci-cd-variables-api-gitlab-docs) - [Project remote mirrors API | GitLab Docs](#project-remote-mirrors-api-gitlab-docs) - [Project issue boards API | GitLab Docs](#project-issue-boards-api-gitlab-docs) - [Project security settings API | GitLab Docs](#project-security-settings-api-gitlab-docs) - [Project forks API | GitLab Docs](#project-forks-api-gitlab-docs) - [Group repository storage moves API | GitLab Docs](#group-repository-storage-moves-api-gitlab-docs) - [Project clusters API (certificate-based) (deprecated) | GitLab Docs](#project-clusters-api-certificate-based-deprecated-gitlab-docs) - [Pipelines API | GitLab Docs](#pipelines-api-gitlab-docs) - [Project vulnerabilities API | GitLab Docs](#project-vulnerabilities-api-gitlab-docs) - [REST API third-party clients | GitLab Docs](#rest-api-third-party-clients-gitlab-docs) - [Protected packages API | GitLab Docs](#protected-packages-api-gitlab-docs) - [Pull mirroring API | GitLab Docs](#pull-mirroring-api-gitlab-docs) - [PyPI API | GitLab Docs](#pypi-api-gitlab-docs) - [Ruby gems API | GitLab Docs](#ruby-gems-api-gitlab-docs) - [Group activity analytics API | GitLab Docs](#group-activity-analytics-api-gitlab-docs) - [Project relations export API | GitLab Docs](#project-relations-export-api-gitlab-docs) - [Project labels API | GitLab Docs](#project-labels-api-gitlab-docs) - [Group badges API | GitLab Docs](#group-badges-api-gitlab-docs) - [Group epic boards API | GitLab Docs](#group-epic-boards-api-gitlab-docs) - [Project wikis API | GitLab Docs](#project-wikis-api-gitlab-docs) - [Query users by using GraphQL | GitLab Docs](#query-users-by-using-graphql-gitlab-docs) - [Group access tokens API | GitLab Docs](#group-access-tokens-api-gitlab-docs) - [OAuth 2.0 identity provider API | GitLab Docs](#oauth-2-0-identity-provider-api-gitlab-docs) - [Protected environments API | GitLab Docs](#protected-environments-api-gitlab-docs) - [Release links API | GitLab Docs](#release-links-api-gitlab-docs) - [Use custom emoji with GraphQL | GitLab Docs](#use-custom-emoji-with-graphql-gitlab-docs) - [REST API authentication | GitLab Docs](#rest-api-authentication-gitlab-docs) - [Merge request approvals API | GitLab Docs](#merge-request-approvals-api-gitlab-docs) - [Web API fuzz testing | GitLab Docs](#web-api-fuzz-testing-gitlab-docs) - [Group clusters API (certificate-based) (deprecated) | GitLab Docs](#group-clusters-api-certificate-based-deprecated-gitlab-docs) - [Group enterprise users API | GitLab Docs](#group-enterprise-users-api-gitlab-docs) - [Projects members API | GitLab Docs](#projects-members-api-gitlab-docs) - [Project repository storage moves API | GitLab Docs](#project-repository-storage-moves-api-gitlab-docs) - [Group import and export API | GitLab Docs](#group-import-and-export-api-gitlab-docs) - [SAML API | GitLab Docs](#saml-api-gitlab-docs) - [Group webhooks API | GitLab Docs](#group-webhooks-api-gitlab-docs) - [Group and project migration by direct transfer API | GitLab Docs](#group-and-project-migration-by-direct-transfer-api-gitlab-docs) - [Retrieve GitLab Duo and SDLC trend data | GitLab Docs](#retrieve-gitlab-duo-and-sdlc-trend-data-gitlab-docs) - [Migrate epic APIs to work items | GitLab Docs](#migrate-epic-apis-to-work-items-gitlab-docs) - [Project starring API | GitLab Docs](#project-starring-api-gitlab-docs) - [Project webhooks API | GitLab Docs](#project-webhooks-api-gitlab-docs) - [Protected branches API | GitLab Docs](#protected-branches-api-gitlab-docs) - [Project import and export API | GitLab Docs](#project-import-and-export-api-gitlab-docs) - [Run GraphQL API queries and mutations | GitLab Docs](#run-graphql-api-queries-and-mutations-gitlab-docs) - [Project release API | GitLab Docs](#project-release-api-gitlab-docs) - [Project templates API | GitLab Docs](#project-templates-api-gitlab-docs) - [REST API deprecations | GitLab Docs](#rest-api-deprecations-gitlab-docs) - [Protected tags API | GitLab Docs](#protected-tags-api-gitlab-docs) - [Project snippets | GitLab Docs](#project-snippets-gitlab-docs) - [Project integrations API | GitLab Docs](#project-integrations-api-gitlab-docs) - [Notes API | GitLab Docs](#notes-api-gitlab-docs) - [Merge requests API | GitLab Docs](#merge-requests-api-gitlab-docs) - [GraphQL examples | GitLab Docs](#graphql-examples-gitlab-docs) - [Tags API | GitLab Docs](#tags-api-gitlab-docs) - [Snippets API | GitLab Docs](#snippets-api-gitlab-docs) - [Snippet repository storage moves API | GitLab Docs](#snippet-repository-storage-moves-api-gitlab-docs) - [System hooks API | GitLab Docs](#system-hooks-api-gitlab-docs) - [Group integrations API | GitLab Docs](#group-integrations-api-gitlab-docs) --- # REST API resources | GitLab Docs  /  * * * REST API resources ================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated The GitLab REST API gives you programmatic control over GitLab resources. Build integrations with your existing tools, automate repetitive tasks, and extract data for custom reports. Access and manipulate projects, groups, issues, and merge requests without using the web interface. Use the REST API to: * Automate project creation and user management. * Trigger CI/CD pipelines from external systems. * Extract issue and merge request data for custom dashboards. * Integrate GitLab with third-party applications. * Implement custom workflows across multiple repositories. The REST API resources are organized into: * [Project resources](https://docs.gitlab.com/api/api_resources/#project-resources) * [Group resources](https://docs.gitlab.com/api/api_resources/#group-resources) * [Standalone resources](https://docs.gitlab.com/api/api_resources/#standalone-resources) * [Template resources](https://docs.gitlab.com/api/api_resources/#template-resources) Project resources[](https://docs.gitlab.com/api/api_resources/#project-resources "Permalink") ---------------------------------------------------------------------------------------------- The following API resources are available in the project context: | Resource | Available endpoints | | --- | --- | | [Access requests](https://docs.gitlab.com/api/access_requests/) | `/projects/:id/access_requests` (also available for groups) | | [Access tokens](https://docs.gitlab.com/api/project_access_tokens/) | `/projects/:id/access_tokens` (also available for groups) | | [Agents](https://docs.gitlab.com/api/cluster_agents/) | `/projects/:id/cluster_agents` | | [Branches](https://docs.gitlab.com/api/branches/) | `/projects/:id/repository/branches/`, `/projects/:id/repository/merged_branches` | | [Commits](https://docs.gitlab.com/api/commits/) | `/projects/:id/repository/commits`, `/projects/:id/statuses` | | [Container registry](https://docs.gitlab.com/api/container_registry/) | `/projects/:id/registry/repositories` | | [Container repository protection rules](https://docs.gitlab.com/api/container_repository_protection_rules/) | `/projects/:id/registry/protection/repository/rules` | | [Container registry protection tag rules](https://docs.gitlab.com/api/container_registry_protection_tag_rules/) | `/projects/:id/registry/protection/tag/rules` | | [Custom attributes](https://docs.gitlab.com/api/custom_attributes/) | `/projects/:id/custom_attributes` (also available for groups and users) | | [Composer distributions](https://docs.gitlab.com/api/packages/composer/) | `/projects/:id/packages/composer` (also available for groups) | | [Conan v1 distributions](https://docs.gitlab.com/api/packages/conan_v1/) | `/projects/:id/packages/conan` (also available standalone) | | [Conan v2 distributions](https://docs.gitlab.com/api/packages/conan_v2/) | `/projects/:id/packages/conan` (also available standalone) | | [Debian distributions](https://docs.gitlab.com/api/packages/debian_project_distributions/) | `/projects/:id/debian_distributions` (also available for groups) | | [Debian packages](https://docs.gitlab.com/api/packages/debian/) | `/projects/:id/packages/debian` (also available for groups) | | [Dependencies](https://docs.gitlab.com/api/dependencies/) | `/projects/:id/dependencies` | | [Deploy keys](https://docs.gitlab.com/api/deploy_keys/) | `/projects/:id/deploy_keys` (also available standalone) | | [Deploy tokens](https://docs.gitlab.com/api/deploy_tokens/) | `/projects/:id/deploy_tokens` (also available for groups and standalone) | | [Deployments](https://docs.gitlab.com/api/deployments/) | `/projects/:id/deployments` | | [Discussions](https://docs.gitlab.com/api/discussions/)
(threaded comments) | `/projects/:id/issues/.../discussions`, `/projects/:id/snippets/.../discussions`, `/projects/:id/merge_requests/.../discussions`, `/projects/:id/commits/.../discussions` (also available for groups) | | [Draft Notes](https://docs.gitlab.com/api/draft_notes/)
(comments) | `/projects/:id/merge_requests/.../draft_notes` | | [Emoji reactions](https://docs.gitlab.com/api/emoji_reactions/) | `/projects/:id/issues/.../award_emoji`, `/projects/:id/merge_requests/.../award_emoji`, `/projects/:id/snippets/.../award_emoji` | | [Environments](https://docs.gitlab.com/api/environments/) | `/projects/:id/environments` | | [Error Tracking](https://docs.gitlab.com/api/error_tracking/) | `/projects/:id/error_tracking/settings` | | [Events](https://docs.gitlab.com/api/events/) | `/projects/:id/events` (also available for users and standalone) | | [External status checks](https://docs.gitlab.com/api/status_checks/) | `/projects/:id/external_status_checks` | | [Feature flag User Lists](https://docs.gitlab.com/api/feature_flag_user_lists/) | `/projects/:id/feature_flags_user_lists` | | [Feature flags](https://docs.gitlab.com/api/feature_flags/) | `/projects/:id/feature_flags` | | [Freeze Periods](https://docs.gitlab.com/api/freeze_periods/) | `/projects/:id/freeze_periods` | | [Go Proxy](https://docs.gitlab.com/api/packages/go_proxy/) | `/projects/:id/packages/go` | | [Helm repository](https://docs.gitlab.com/api/packages/helm/) | `/projects/:id/packages/helm_repository` | | [Integrations](https://docs.gitlab.com/api/project_integrations/)
(Formerly “services”) | `/projects/:id/integrations` | | [Invitations](https://docs.gitlab.com/api/invitations/) | `/projects/:id/invitations` (also available for groups) | | [Issue boards](https://docs.gitlab.com/api/boards/) | `/projects/:id/boards` | | [Issue links](https://docs.gitlab.com/api/issue_links/) | `/projects/:id/issues/.../links` | | [Issues Statistics](https://docs.gitlab.com/api/issues_statistics/) | `/projects/:id/issues_statistics` (also available for groups and standalone) | | [Issues](https://docs.gitlab.com/api/issues/) | `/projects/:id/issues` (also available for groups and standalone) | | [Iterations](https://docs.gitlab.com/api/iterations/) | `/projects/:id/iterations` (also available for groups) | | [Project CI/CD job token scope](https://docs.gitlab.com/api/project_job_token_scopes/) | `/projects/:id/job_token_scope` | | [Jobs](https://docs.gitlab.com/api/jobs/) | `/projects/:id/jobs`, `/projects/:id/pipelines/.../jobs` | | [Jobs Artifacts](https://docs.gitlab.com/api/job_artifacts/) | `/projects/:id/jobs/:job_id/artifacts` | | [Labels](https://docs.gitlab.com/api/labels/) | `/projects/:id/labels` | | [Maven repository](https://docs.gitlab.com/api/packages/maven/) | `/projects/:id/packages/maven` (also available for groups and standalone) | | [Members](https://docs.gitlab.com/api/project_members/) | `/projects/:id/members` (also available for groups) | | [Merge request approvals](https://docs.gitlab.com/api/merge_request_approvals/) | `/projects/:id/approvals`, `/projects/:id/merge_requests/.../approvals` | | [Merge requests](https://docs.gitlab.com/api/merge_requests/) | `/projects/:id/merge_requests` (also available for groups and standalone) | | [Merge trains](https://docs.gitlab.com/api/merge_trains/) | `/projects/:id/merge_trains` | | [Metadata](https://docs.gitlab.com/api/metadata/) | `/metadata` | | [Model registry](https://docs.gitlab.com/api/model_registry/) | `/projects/:id/packages/ml_models/` | | [Notes](https://docs.gitlab.com/api/notes/)
(comments) | `/projects/:id/issues/.../notes`, `/projects/:id/snippets/.../notes`, `/projects/:id/merge_requests/.../notes` (also available for groups) | | [Notification settings](https://docs.gitlab.com/api/notification_settings/) | `/projects/:id/notification_settings` (also available for groups and standalone) | | [NPM repository](https://docs.gitlab.com/api/packages/npm/) | `/projects/:id/packages/npm` | | [NuGet packages](https://docs.gitlab.com/api/packages/nuget/) | `/projects/:id/packages/nuget` (also available for groups) | | [Packages](https://docs.gitlab.com/api/packages/) | `/projects/:id/packages` | | [Pages domains](https://docs.gitlab.com/api/pages_domains/) | `/projects/:id/pages/domains` (also available standalone) | | [Pages settings](https://docs.gitlab.com/api/pages/) | `/projects/:id/pages` | | [Pipeline schedules](https://docs.gitlab.com/api/pipeline_schedules/) | `/projects/:id/pipeline_schedules` | | [Pipeline triggers](https://docs.gitlab.com/api/pipeline_triggers/) | `/projects/:id/triggers` | | [Pipelines](https://docs.gitlab.com/api/pipelines/) | `/projects/:id/pipelines` | | [Project badges](https://docs.gitlab.com/api/project_badges/) | `/projects/:id/badges` | | [Project clusters](https://docs.gitlab.com/api/project_clusters/) | `/projects/:id/clusters` | | [Project import/export](https://docs.gitlab.com/api/project_import_export/) | `/projects/:id/export`, `/projects/import`, `/projects/:id/import` | | [Project milestones](https://docs.gitlab.com/api/milestones/) | `/projects/:id/milestones` | | [Project snippets](https://docs.gitlab.com/api/project_snippets/) | `/projects/:id/snippets` | | [Project templates](https://docs.gitlab.com/api/project_templates/) | `/projects/:id/templates` | | [Project vulnerabilities](https://docs.gitlab.com/api/project_vulnerabilities/)
. | `/projects/:id/vulnerabilities` | | [Project wikis](https://docs.gitlab.com/api/wikis/) | `/projects/:id/wikis` | | [Project-level variables](https://docs.gitlab.com/api/project_level_variables/) | `/projects/:id/variables` | | [Projects](https://docs.gitlab.com/api/projects/)
including setting Webhooks | `/projects`, `/projects/:id/hooks` (also available for users) | | [Protected branches](https://docs.gitlab.com/api/protected_branches/) | `/projects/:id/protected_branches` | | [Protected container registry](https://docs.gitlab.com/api/container_repository_protection_rules/) | `/projects/:id/registry/protection/rules` | | [Protected environments](https://docs.gitlab.com/api/protected_environments/) | `/projects/:id/protected_environments` | | [Protected packages](https://docs.gitlab.com/api/project_packages_protection_rules/) | `/projects/:id/packages/protection/rules` | | [Protected tags](https://docs.gitlab.com/api/protected_tags/) | `/projects/:id/protected_tags` | | [PyPI packages](https://docs.gitlab.com/api/packages/pypi/) | `/projects/:id/packages/pypi` (also available for groups) | | [Release links](https://docs.gitlab.com/api/releases/links/) | `/projects/:id/releases/.../assets/links` | | [Releases](https://docs.gitlab.com/api/releases/) | `/projects/:id/releases` | | [Remote mirrors](https://docs.gitlab.com/api/remote_mirrors/) | `/projects/:id/remote_mirrors` | | [Repositories](https://docs.gitlab.com/api/repositories/) | `/projects/:id/repository` | | [Repository files](https://docs.gitlab.com/api/repository_files/) | `/projects/:id/repository/files` | | [Repository submodules](https://docs.gitlab.com/api/repository_submodules/) | `/projects/:id/repository/submodules` | | [Resource label events](https://docs.gitlab.com/api/resource_label_events/) | `/projects/:id/issues/.../resource_label_events`, `/projects/:id/merge_requests/.../resource_label_events` (also available for groups) | | [Ruby gems](https://docs.gitlab.com/api/packages/rubygems/) | `/projects/:id/packages/rubygems` | | [Runners](https://docs.gitlab.com/api/runners/) | `/projects/:id/runners` (also available standalone) | | [Search](https://docs.gitlab.com/api/search/) | `/projects/:id/search` (also available for groups and standalone) | | [Tags](https://docs.gitlab.com/api/tags/) | `/projects/:id/repository/tags` | | [Terraform modules](https://docs.gitlab.com/api/packages/terraform-modules/) | `/projects/:id/packages/terraform/modules` (also available standalone) | | [Validate `.gitlab-ci.yml` file](https://docs.gitlab.com/api/lint/) | `/projects/:id/ci/lint` | | [Vulnerabilities](https://docs.gitlab.com/api/vulnerabilities/) | `/vulnerabilities/:id` | | [Vulnerability exports](https://docs.gitlab.com/api/vulnerability_exports/) | `/projects/:id/vulnerability_exports` | | [Vulnerability findings](https://docs.gitlab.com/api/vulnerability_findings/) | `/projects/:id/vulnerability_findings` | Group resources[](https://docs.gitlab.com/api/api_resources/#group-resources "Permalink") ------------------------------------------------------------------------------------------ The following API resources are available in the group context: | Resource | Available endpoints | | --- | --- | | [Access requests](https://docs.gitlab.com/api/access_requests/) | `/groups/:id/access_requests/` (also available for projects) | | [Access tokens](https://docs.gitlab.com/api/group_access_tokens/) | `/groups/:id/access_tokens` (also available for projects) | | [Custom attributes](https://docs.gitlab.com/api/custom_attributes/) | `/groups/:id/custom_attributes` (also available for projects and users) | | [Debian distributions](https://docs.gitlab.com/api/packages/debian_group_distributions/) | `/groups/:id/-/packages/debian` (also available for projects) | | [Deploy tokens](https://docs.gitlab.com/api/deploy_tokens/) | `/groups/:id/deploy_tokens` (also available for projects and standalone) | | [Discussions](https://docs.gitlab.com/api/discussions/)
(comments and threads) | `/groups/:id/epics/.../discussions` (also available for projects) | | [Epic issues](https://docs.gitlab.com/api/epic_issues/) | `/groups/:id/epics/.../issues` | | [Epic links](https://docs.gitlab.com/api/epic_links/) | `/groups/:id/epics/.../epics` | | [Epics](https://docs.gitlab.com/api/epics/) | `/groups/:id/epics` | | [Groups](https://docs.gitlab.com/api/groups/) | `/groups`, `/groups/.../subgroups` | | [Group badges](https://docs.gitlab.com/api/group_badges/) | `/groups/:id/badges` | | [Group issue boards](https://docs.gitlab.com/api/group_boards/) | `/groups/:id/boards` | | [Group iterations](https://docs.gitlab.com/api/group_iterations/) | `/groups/:id/iterations` (also available for projects) | | [Group labels](https://docs.gitlab.com/api/group_labels/) | `/groups/:id/labels` | | [Group-level variables](https://docs.gitlab.com/api/group_level_variables/) | `/groups/:id/variables` | | [Group milestones](https://docs.gitlab.com/api/group_milestones/) | `/groups/:id/milestones` | | [Group releases](https://docs.gitlab.com/api/group_releases/) | `/groups/:id/releases` | | [Group SSH certificates](https://docs.gitlab.com/api/group_ssh_certificates/) | `/groups/:id/ssh_certificates` | | [Group wikis](https://docs.gitlab.com/api/group_wikis/) | `/groups/:id/wikis` | | [Invitations](https://docs.gitlab.com/api/invitations/) | `/groups/:id/invitations` (also available for projects) | | [Issues](https://docs.gitlab.com/api/issues/) | `/groups/:id/issues` (also available for projects and standalone) | | [Issues Statistics](https://docs.gitlab.com/api/issues_statistics/) | `/groups/:id/issues_statistics` (also available for projects and standalone) | | [Linked epics](https://docs.gitlab.com/api/linked_epics/) | `/groups/:id/epics/.../related_epics` | | [Member Roles](https://docs.gitlab.com/api/member_roles/) | `/groups/:id/member_roles` | | [Members](https://docs.gitlab.com/api/group_members/) | `/groups/:id/members` (also available for projects) | | [Merge requests](https://docs.gitlab.com/api/merge_requests/) | `/groups/:id/merge_requests` (also available for projects and standalone) | | [Notes](https://docs.gitlab.com/api/notes/)
(comments) | `/groups/:id/epics/.../notes` (also available for projects) | | [Notification settings](https://docs.gitlab.com/api/notification_settings/) | `/groups/:id/notification_settings` (also available for projects and standalone) | | [Resource label events](https://docs.gitlab.com/api/resource_label_events/) | `/groups/:id/epics/.../resource_label_events` (also available for projects) | | [Search](https://docs.gitlab.com/api/search/) | `/groups/:id/search` (also available for projects and standalone) | Standalone resources[](https://docs.gitlab.com/api/api_resources/#standalone-resources "Permalink") ---------------------------------------------------------------------------------------------------- The following API resources are available outside of project and group contexts (including `/users`): | Resource | Available endpoints | | --- | --- | | [Appearance](https://docs.gitlab.com/api/appearance/) | `/application/appearance` | | [Applications](https://docs.gitlab.com/api/applications/) | `/applications` | | [Audit events](https://docs.gitlab.com/api/audit_events/) | `/audit_events` | | [Avatar](https://docs.gitlab.com/api/avatar/) | `/avatar` | | [Broadcast messages](https://docs.gitlab.com/api/broadcast_messages/) | `/broadcast_messages` | | [Code snippets](https://docs.gitlab.com/api/snippets/) | `/snippets` | | [Code Suggestions](https://docs.gitlab.com/api/code_suggestions/) | `/code_suggestions` | | [Custom attributes](https://docs.gitlab.com/api/custom_attributes/) | `/users/:id/custom_attributes` (also available for groups and projects) | | [Dependency list exports](https://docs.gitlab.com/api/dependency_list_export/) | `/pipelines/:id/dependency_list_exports`, `/projects/:id/dependency_list_exports`, `/groups/:id/dependency_list_exports`, `/security/dependency_list_exports/:id`, `/security/dependency_list_exports/:id/download` | | [Deploy keys](https://docs.gitlab.com/api/deploy_keys/) | `/deploy_keys` (also available for projects) | | [Deploy tokens](https://docs.gitlab.com/api/deploy_tokens/) | `/deploy_tokens` (also available for projects and groups) | | [GitLab Duo Agent Platform flows](https://docs.gitlab.com/api/duo_agent_platform_flows/) | `/ai/duo_workflows` | | [Events](https://docs.gitlab.com/api/events/) | `/events`, `/users/:id/events` (also available for projects) | | [Feature flags](https://docs.gitlab.com/api/features/) | `/features` | | [Geo Nodes](https://docs.gitlab.com/api/geo_nodes/) | `/geo_nodes` | | [GLQL](https://docs.gitlab.com/api/glql/) | `/glql` | | [Group Activity Analytics](https://docs.gitlab.com/api/group_activity_analytics/) | `/analytics/group_activity/{issues_count}` | | [Group repository storage moves](https://docs.gitlab.com/api/group_repository_storage_moves/) | `/group_repository_storage_moves` | | [Import repository from GitHub](https://docs.gitlab.com/api/import/#import-repository-from-github) | `/import/github` | | [Import repository from Bitbucket Server](https://docs.gitlab.com/api/import/#import-repository-from-bitbucket-server) | `/import/bitbucket_server` | | [Instance clusters](https://docs.gitlab.com/api/instance_clusters/) | `/admin/clusters` | | [Instance-level CI/CD variables](https://docs.gitlab.com/api/instance_level_ci_variables/) | `/admin/ci/variables` | | [Issues Statistics](https://docs.gitlab.com/api/issues_statistics/) | `/issues_statistics` (also available for groups and projects) | | [Issues](https://docs.gitlab.com/api/issues/) | `/issues` (also available for groups and projects) | | [Jobs](https://docs.gitlab.com/api/jobs/) | `/job` | | [Keys](https://docs.gitlab.com/api/keys/) | `/keys` | | [License](https://docs.gitlab.com/api/license/) | `/license` | | [Markdown](https://docs.gitlab.com/api/markdown/) | `/markdown` | | [Merge requests](https://docs.gitlab.com/api/merge_requests/) | `/merge_requests` (also available for groups and projects) | | [Namespaces](https://docs.gitlab.com/api/namespaces/) | `/namespaces` | | [Notification settings](https://docs.gitlab.com/api/notification_settings/) | `/notification_settings` (also available for groups and projects) | | [Compliance and Policy settings](https://docs.gitlab.com/api/compliance_policy_settings/) | `/admin/security/compliance_policy_settings` | | [Pages domains](https://docs.gitlab.com/api/pages_domains/) | `/pages/domains` (also available for projects) | | [Personal access tokens](https://docs.gitlab.com/api/personal_access_tokens/) | `/personal_access_tokens` | | [Plan limits](https://docs.gitlab.com/api/plan_limits/) | `/application/plan_limits` | | [Project repository storage moves](https://docs.gitlab.com/api/project_repository_storage_moves/) | `/project_repository_storage_moves` | | [Projects](https://docs.gitlab.com/api/projects/) | `/users/:id/projects` (also available for projects) | | [Runners](https://docs.gitlab.com/api/runners/) | `/runners` (also available for projects) | | [Search](https://docs.gitlab.com/api/search/) | `/search` (also available for groups and projects) | | [Service Data](https://docs.gitlab.com/api/usage_data/) | `/usage_data` (For GitLab instance [Administrator](https://docs.gitlab.com/user/permissions/)
users only) | | [Settings](https://docs.gitlab.com/api/settings/) | `/application/settings` | | [Sidekiq metrics](https://docs.gitlab.com/api/sidekiq_metrics/) | `/sidekiq` | | [Sidekiq queues administration](https://docs.gitlab.com/api/admin_sidekiq_queues/) | `/admin/sidekiq/queues/:queue_name` | | [Snippet repository storage moves](https://docs.gitlab.com/api/snippet_repository_storage_moves/) | `/snippet_repository_storage_moves` | | [Statistics](https://docs.gitlab.com/api/statistics/) | `/application/statistics` | | [Suggestions](https://docs.gitlab.com/api/suggestions/) | `/suggestions` | | [System hooks](https://docs.gitlab.com/api/system_hooks/) | `/hooks` | | [To-dos](https://docs.gitlab.com/api/todos/) | `/todos` | | [Token information](https://docs.gitlab.com/api/admin/token/) | `/admin/token` | | [Topics](https://docs.gitlab.com/api/topics/) | `/topics` | | [Users](https://docs.gitlab.com/api/users/) | `/users` | | [Web commits](https://docs.gitlab.com/api/web_commits/) | `/web_commits/public_key` | Template resources[](https://docs.gitlab.com/api/api_resources/#template-resources "Permalink") ------------------------------------------------------------------------------------------------ Endpoints are available for: * [Dockerfile templates](https://docs.gitlab.com/api/templates/dockerfiles/) * [`.gitignore` templates](https://docs.gitlab.com/api/templates/gitignores/) * [GitLab CI/CD YAML templates](https://docs.gitlab.com/api/templates/gitlab_ci_ymls/) * [Open source license templates](https://docs.gitlab.com/api/templates/licenses/) Was this page helpful?YesNo ![](https://cdn.bizible.com/ipv?_biz_r=&_biz_h=-1719903975&_biz_u=437e54a22fb3403af0311b6605a715fa&_biz_l=https%3A%2F%2Fdocs.gitlab.com%2Fapi%2Fapi_resources%2F&_biz_t=1776089959811&_biz_i=REST%20API%20resources%20%7C%20GitLab%20Docs&_biz_n=0&rnd=110815&cdn_o=a&_biz_z=1776089959816)![](https://cdn.bizibly.com/u?_biz_u=437e54a22fb3403af0311b6605a715fa&_biz_l=https%3A%2F%2Fdocs.gitlab.com%2Fapi%2Fapi_resources%2F&_biz_t=1776089959822&_biz_i=REST%20API%20resources%20%7C%20GitLab%20Docs&rnd=858603&cdn_o=a&_biz_z=1776089959822) ![Company Logo](https://cdn.cookielaw.org/logos/aa14a5c8-79e3-442a-8177-464ad850b19d/e46c1d0d-1f66-481f-bc06-5427671431da/253e6fee-c4c0-4b60-bc35-79cdae5dda32/gitlab-logo-100.png) Privacy Preference Center ------------------------- Privacy Preference Center ------------------------- * ### Your Privacy * ### Strictly Necessary Cookies * ### Functionality Cookies * ### Performance and Analytics Cookies * ### Targeting and Advertising Cookies * ### Ad User Data * ### Ad Personalization #### Your Privacy When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer. [Cookie Policy](https://about.gitlab.com/privacy/cookies/) **User ID:** 4de6862b-6924-430a-a278-ac2ce22f60e1 _This User ID will be used as a unique identifier while storing and accessing your preferences for future._ **Timestamp:** \-- #### Strictly Necessary Cookies Always Active These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, enabling you to securely log into the site, filling in forms, or using the customer checkout. GitLab processes any personal data collected through these cookies on the basis of our legitimate interest. Cookies Details #### Functionality Cookies Functionality Cookies These cookies enable helpful but non-essential website functions that improve your website experience. By recognizing you when you return to our website, they may, for example, allow us to personalize our content for you or remember your preferences. If you do not allow these cookies then some or all of these services may not function properly. GitLab processes any personal data collected through these cookies on the basis of your consent Cookies Details #### Performance and Analytics Cookies Performance and Analytics Cookies These cookies allow us and our third-party service providers to recognize and count the number of visitors on our websites and to see how visitors move around our websites when they are using it. This helps us improve our products and ensures that users can easily find what they need on our websites. These cookies usually generate aggregate statistics that are not associated with an individual. To the extent any personal data is collected through these cookies, GitLab processes that data on the basis of your consent. Cookies Details #### Targeting and Advertising Cookies Targeting and Advertising Cookies These cookies enable different advertising related functions. They may allow us to record information about your visit to our websites, such as pages visited, links followed, and videos viewed so we can make our websites and the advertising displayed on it more relevant to your interests. They may be set through our website by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant advertisements on other websites. GitLab processes any personal data collected through these cookies on the basis of your consent. Cookies Details #### Ad User Data Ad User Data Sets consent for sending user data to Google for advertising purposes. Cookies Details #### Ad Personalization Ad Personalization Sets consent for personalized advertising. Cookies Details Back Button ### Cookie List Filter Button Consent Leg.Interest checkbox label label checkbox label label checkbox label label Clear * checkbox label label Apply Cancel Confirm My Choices Allow All [![Powered by Onetrust](https://cdn.cookielaw.org/logos/static/powered_by_logo.svg "Powered by OneTrust Opens in a new Tab")](https://www.onetrust.com/products/cookie-consent/) ![](https://cdn.bizible.com/u?mapType=mkto&mapValue=id%3A194-VVC-221%26token%3A_mch-gitlab.com-a322a7a88c3c2345955dd3c1ff519a55&_biz_u=437e54a22fb3403af0311b6605a715fa&_biz_l=https%3A%2F%2Fdocs.gitlab.com%2Fapi%2Fapi_resources%2F&_biz_t=1776089960823&_biz_i=REST%20API%20resources%20%7C%20GitLab%20Docs&_biz_n=1&rnd=109258&cdn_o=a&_biz_z=1776089960823) --- # Cleartext authentication | GitLab Docs * * * Cleartext authentication ======================== Description ----------- This check looks for cleartext authentication such as HTTP Basic auth with no-TLS. Remediation ----------- Authentication credentials are transported via unencrypted channel (HTTP). This exposes the transmitted credentials to any attacker who can monitor (sniff) the network traffic during transmission. Sensitive information such as credentials should always be transmitted via encrypted channels such as HTTPS. Links ----- * [OWASP](https://owasp.org/Top10/A02_2021-Cryptographic_Failures/) * [CWE](https://cwe.mitre.org/data/definitions/319.html) --- # CORS | GitLab Docs * * * CORS ==== Description ----------- Check for CORS misconfiguration including overly permissive white-lists of accepted Origin headers or failure to validate Origin header. Also checks for allowing credentials on potentially invalid or dangerous Origins and missing headers that could potentially result in cache poisoning. Remediation ----------- A misconfigured CORS implementation may be overly permissive in which domains should be trusted and at what level of trust. This could allow an untrusted domain to forge the Origin header and launch various types of attacks such as cross-site request forgery or cross-site scripting. An attacker could potentially steal a victim’s credentials or send malicious requests on behalf of a victim. The victim may not even be aware that an attack is being launched. Links ----- * [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control/) * [CWE](https://cwe.mitre.org/data/definitions/942.html) --- # Geo API | GitLab Docs * * * Geo API ======= * Tier: Premium, Ultimate * Offering: GitLab Self-Managed * Status: Beta The Geo API is used internally by GitLab components to assist in coordinating Geo actions. It is inaccessible to admins or users. Fetch pipeline refs ------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/415179) in GitLab 16.7. This method returns a list of branches matching `pipeline/refs/X` that exist on the repository for `gl_repository` on the current Geo node. This endpoint is used by runners registered with a secondary Geo instance to check if a repository is up to date. GET /geo/repositories/:gl_repository/pipeline_refs Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `gl_repository` | string | Yes | The `gl_repository` ID of the repository to query | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `attribute` | ‘array’ | An array of ids matching `refs/pipeline/X` created for running pipelines. | --- # Go Proxy API | GitLab Docs * * * Go Proxy API ============ * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Use this API to interact with the [Go package manager client](https://docs.gitlab.com/user/packages/go_proxy/) . This API is behind a feature flag that is disabled by default. GitLab administrators with access to the GitLab Rails console can [enable](https://docs.gitlab.com/administration/feature_flags/) this API for your GitLab instance. This API is used by the [`go` command](https://go.dev/ref/mod#go-get) and is generally not meant for manual consumption. These endpoints do not adhere to the standard API authentication methods. See the [Go Proxy package documentation](https://docs.gitlab.com/user/packages/go_proxy/) for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future. List ---- Get all tagged versions for a given Go module: GET projects/:id/packages/go/:module_name/@v/list | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The project ID or full path of a project. | | `module_name` | string | yes | The name of the Go module. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/go/my-go-module/@v/list" Example output: "v1.0.0\nv1.0.1\nv1.3.8\n2.0.0\n2.1.0\n3.0.0" Version metadata ---------------- Get all tagged versions for a given Go module: GET projects/:id/packages/go/:module_name/@v/:module_version.info | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The project ID or full path of a project. | | `module_name` | string | yes | The name of the Go module. | | `module_version` | string | yes | The version of the Go module. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/go/my-go-module/@v/1.0.0.info" Example output: { "Version": "v1.0.0", "Time": "1617822312 -0600" } Download module file -------------------- Fetch the `.mod` module file: GET projects/:id/packages/go/:module_name/@v/:module_version.mod | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The project ID or full path of a project. | | `module_name` | string | yes | The name of the Go module. | | `module_version` | string | yes | The version of the Go module. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/go/my-go-module/@v/1.0.0.mod" Write to a file: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/go/my-go-module/@v/1.0.0.mod" >> foo.mod This writes to `foo.mod` in the current directory. Download module source ---------------------- Fetch the `.zip` of the module source: GET projects/:id/packages/go/:module_name/@v/:module_version.zip | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The project ID or full path of a project. | | `module_name` | string | yes | The name of the Go module. | | `module_version` | string | yes | The version of the Go module. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/go/my-go-module/@v/1.0.0.zip" Write to a file: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/go/my-go-module/@v/1.0.0.zip" >> foo.zip This writes to `foo.zip` in the current directory. --- # Google Cloud integration API | GitLab Docs * * * Google Cloud integration API ============================ * Tier: Free, Premium, Ultimate * Offering: GitLab.com * Status: Experiment Use this API to interact with the Google Cloud integration. For more information, see [GitLab and Google Cloud integration](https://docs.gitlab.com/ci/gitlab_google_cloud_integration/) . Project-level Google Cloud integration scripts ---------------------------------------------- * Status: Experiment History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141870) in GitLab 16.10. This feature is an [experiment](https://docs.gitlab.com/policy/development_stages_support/) . ### Workload identity federation creation script History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141870) in GitLab 16.10. Users with the Maintainer or Owner role for the project can use the following endpoint to query a shell script that creates and configures the workload identity federation in Google Cloud: GET /projects/:id/google_cloud/setup/wlif.sh Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID a project. | | `google_cloud_project_id` | string | Yes | Google Cloud Project ID for the workload identity federation. | | `google_cloud_workload_identity_pool_id` | string | No | ID of the Google Cloud workload identity pool to create. Defaults to `gitlab-wlif`. | | `google_cloud_workload_identity_pool_display_name` | string | No | Display name of the Google Cloud workload identity pool to create. Defaults to `WLIF for GitLab integration`. | | `google_cloud_workload_identity_pool_provider_id` | string | No | ID of the Google Cloud workload identity pool provider to create. Defaults to `gitlab-wlif-oidc-provider`. | | `google_cloud_workload_identity_pool_provider_display_name` | string | No | Display name of the Google Cloud workload identity pool provider to created. Defaults to `GitLab OIDC provider`. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.com/api/v4/projects//google_cloud/setup/wlif.sh" ### Script to set up a Google Cloud integration History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144787) in GitLab 16.10. Users with the Maintainer or Owner role for the project can use the following endpoint to query a shell script to set up a Google Cloud integration: GET /projects/:id/google_cloud/setup/integrations.sh Only the [Google Artifact Management integration](https://docs.gitlab.com/user/project/integrations/google_artifact_management/) is supported. The script creates IAM policies to access Google Artifact Registry: * [Artifact Registry Reader](https://cloud.google.com/artifact-registry/docs/access-control#roles) role is granted to members with at least Reporter role * [Artifact Registry Writer](https://cloud.google.com/artifact-registry/docs/access-control#roles) role is granted to members with at least Developer role Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of a GitLab project. | | `enable_google_cloud_artifact_registry` | boolean | Yes | Flag to indicate if Google Artifact Management integration should be enabled. | | `google_cloud_artifact_registry_project_id` | string | Yes | Google Cloud Project ID for the Artifact Registry. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.com/api/v4/projects//google_cloud/setup/integrations.sh" ### Script to configure a Google Cloud project for runner provisioning History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145525) in GitLab 16.10. Users with the Maintainer or Owner role for the project can use the following endpoint to query a shell script to configure a Google Cloud project for runner provisioning and execution: GET /projects/:id/google_cloud/setup/runner_deployment_project.sh The script performs preparatory configuration steps in the specified Google Cloud project, namely enabling required services and creating a `GRITProvisioner` role and a `grit-provisioner` service account. Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of a GitLab project. | | `google_cloud_project_id` | string | Yes | The ID of the Google Cloud project. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.com/api/v4/projects//google_cloud/setup/runner_deployment_project.sh?google_cloud_project_id=" --- # Framework debug mode | GitLab Docs * * * Framework debug mode ==================== Description ----------- Checks to see if debug mode is enabled in various frameworks such as Flask and ASP.NET. This check has a low false positive rate. Remediation ----------- The Flask or ASP .NET framework was identified with debug mode enabled. This allows an attacker the ability to download any file on the file system and other capabilities. This is a high severity issue that is easy for an attacker to exploit. Links ----- * [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration/) * [CWE-23: Relative Path Traversal](https://cwe.mitre.org/data/definitions/23.html) * [CWE-285: Improper Authorization](https://cwe.mitre.org/data/definitions/285.html) --- # Feature flags API | GitLab Docs * * * Feature flags API ================= * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed This API is for managing Flipper-based feature flags used in development of GitLab. All methods require administrator authorization. Notice that the API only supports boolean and percentage-of-time gate values. List all feature flags ---------------------- List all persisted feature flags, with their gate values. GET /features curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/features" Example response: [\ {\ "name": "experimental_feature",\ "state": "off",\ "gates": [\ {\ "key": "boolean",\ "value": false\ }\ ],\ "definition": null\ },\ {\ "name": "my_user_feature",\ "state": "on",\ "gates": [\ {\ "key": "percentage_of_actors",\ "value": 34\ }\ ],\ "definition": {\ "name": "my_user_feature",\ "introduced_by_url": "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40880",\ "rollout_issue_url": "https://gitlab.com/gitlab-org/gitlab/-/issues/244905",\ "group": "group::ci",\ "type": "development",\ "default_enabled": false\ }\ },\ {\ "name": "new_library",\ "state": "on",\ "gates": [\ {\ "key": "boolean",\ "value": true\ }\ ],\ "definition": null\ }\ ] List all feature flag definitions --------------------------------- List all feature flag definitions. GET /features/definitions curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/features/definitions" Example response: [\ {\ "name": "geo_pages_deployment_replication",\ "introduced_by_url": "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68662",\ "rollout_issue_url": "https://gitlab.com/gitlab-org/gitlab/-/issues/337676",\ "milestone": "14.3",\ "log_state_changes": null,\ "type": "development",\ "group": "group::geo",\ "default_enabled": true\ }\ ] Create or update a feature flag ------------------------------- Create or update a feature flag’s gate value. If a feature flag with the given name doesn’t exist yet, it’s created. The value can be a boolean, or an integer to indicate percentage of time. Before you enable a feature still in development, you should understand the [security and stability risks](https://docs.gitlab.com/administration/feature_flags/#risks-when-enabling-features-still-in-development) . POST /features/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | Name of the feature to create or update | | `value` | integer or string | yes | `true` or `false` to enable/disable, or an integer for percentage of time | | `key` | string | no | `percentage_of_actors` or `percentage_of_time` (default) | | `feature_group` | string | no | A Feature group name | | `user` | string | no | A GitLab username or comma-separated multiple usernames | | `group` | string | no | A GitLab group’s path, for example `gitlab-org`, or comma-separated multiple group paths | | `namespace` | string | no | A GitLab group or user namespace’s path, for example `john-doe`, or comma-separated multiple namespace paths. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353117)
in GitLab 15.0. | | `project` | string | no | A projects path, for example `gitlab-org/gitlab-foss`, or comma-separated multiple project paths | | `repository` | string | no | A repository path, for example `gitlab-org/gitlab-test.git`, `gitlab-org/gitlab-test.wiki.git`, , `snippets/21.git`, to name a few. Use comma to separate multiple repository paths | | `runner` | string | no | A runner ID, or comma-separated list of runner IDs | | `force` | boolean | no | Skip feature flag validation checks, such as a YAML definition | You can enable or disable a feature for a `feature_group`, a `user`, a `group`, a `namespace`, a `project`, a `repository`, and a `runner` in a single API call. curl --request POST \ --data "value=30" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/features/new_library" Example response: { "name": "new_library", "state": "conditional", "gates": [\ {\ "key": "boolean",\ "value": false\ },\ {\ "key": "percentage_of_time",\ "value": 30\ }\ ], "definition": { "name": "my_user_feature", "introduced_by_url": "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40880", "rollout_issue_url": "https://gitlab.com/gitlab-org/gitlab/-/issues/244905", "group": "group::ci", "type": "development", "default_enabled": false } } ### Set percentage of actors rollout Rollout to percentage of actors. POST https://gitlab.example.com/api/v4/features/my_user_feature?private_token= Content-Type: application/x-www-form-urlencoded value=42&key=percentage_of_actors& Example response: { "name": "my_user_feature", "state": "conditional", "gates": [\ {\ "key": "boolean",\ "value": false\ },\ {\ "key": "percentage_of_actors",\ "value": 42\ }\ ], "definition": { "name": "my_user_feature", "introduced_by_url": "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40880", "rollout_issue_url": "https://gitlab.com/gitlab-org/gitlab/-/issues/244905", "group": "group::ci", "type": "development", "default_enabled": false } } Rolls out the `my_user_feature` to `42%` of actors. Delete a feature ---------------- Delete a feature flag gate. Returns the same response whether the feature flag exists or not. DELETE /features/:name --- # Flows API | GitLab Docs * * * Flows API ========= * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to create and manage [flows](https://docs.gitlab.com/user/duo_agent_platform/flows/) in the [GitLab Duo Agent Platform](https://docs.gitlab.com/user/duo_agent_platform/) . Flows are combinations of AI agents that work together to complete developer tasks, such as fixing bugs, writing code, or resolving vulnerabilities. Create a flow ------------- * Status: Experiment Creates and starts a new flow. POST /ai/duo_workflows/workflows Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `additional_context` | array of objects | No | Additional context for the flow. Each element must be an object with at minimum a `Category` (string) and `Content` (string, serialized JSON) key. | | `agent_privileges` | integer array | No | Privilege IDs the agent is allowed to use. Defaults to all privileges. See [List all agent privileges](https://docs.gitlab.com/api/duo_agent_platform_flows/#list-all-agent-privileges)
. | | `ai_catalog_item_consumer_id` | integer | No | ID of the AI Catalog item consumer that configures which catalog item to execute. Requires `project_id`. Cannot be used with `workflow_definition`; if both are provided, `ai_catalog_item_consumer_id` takes precedence. See [Look up the consumer ID](https://docs.gitlab.com/api/duo_agent_platform_flows/#look-up-the-consumer-id)
. | | `ai_catalog_item_version_id` | integer | No | ID of the AI Catalog item version that sourced the flow configuration. | | `allow_agent_to_request_user` | boolean | No | When `true` (default), the agent may pause to ask the user questions before proceeding. When `false`, the agent runs to completion without user input. | | `environment` | string | No | Execution environment. One of: `ide`, `web`, `chat_partial`, `chat`, `ambient`. | | `goal` | string | No | Description of the task for the agent to complete. Example: `Fix the failing pipeline`. | | `image` | string | No | Container image to use when running the flow in a CI pipeline. Must meet the [custom image requirements](https://docs.gitlab.com/user/duo_agent_platform/flows/execution/#custom-image-requirements)
. Example: `registry.gitlab.com/gitlab-org/duo-workflow/custom-image:latest`. | | `issue_id` | integer | No | IID of the issue to associate the flow with. Requires `project_id`. | | `merge_request_id` | integer | No | IID of the merge request to associate the flow with. Requires `project_id`. | | `namespace_id` | string | No | ID or path of the namespace to associate the flow with. | | `pre_approved_agent_privileges` | integer array | No | Privilege IDs the agent can use without asking for user approval. Must be a subset of `agent_privileges`. | | `project_id` | string | No | ID or path of the project to associate the flow with. | | `shallow_clone` | boolean | No | Whether to use a shallow clone of the repository during execution. Default: `true`. | | `source_branch` | string | No | Source branch for the CI pipeline. Defaults to the project’s default branch. | | `start_workflow` | boolean | No | When `true`, starts the flow immediately after creation. | | `workflow_definition` | string | No | Flow type identifier. Example: `developer/v1`. Cannot be used with `ai_catalog_item_consumer_id`; if both are provided, `ai_catalog_item_consumer_id` takes precedence. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `agent_privileges` | integer array | Privilege IDs assigned to the agent. | | `agent_privileges_names` | string array | Names corresponding to `agent_privileges`. | | `ai_catalog_item_version_id` | integer | ID of the AI Catalog item version. `null` if not set. | | `allow_agent_to_request_user` | boolean | When `true`, the agent may pause for user input. | | `environment` | string | Execution environment. `null` if not set. | | `gitlab_url` | string | Base URL of the GitLab instance. | | `id` | integer | ID of the flow. | | `image` | string | Container image for CI pipeline execution. `null` if not set. | | `mcp_enabled` | boolean | Whether `MCP` (Model Context Protocol) tools are enabled for this flow. | | `namespace_id` | integer | ID of the associated namespace. `null` if not set. | | `pre_approved_agent_privileges` | integer array | Privilege IDs the agent can use without asking for approval. | | `pre_approved_agent_privileges_names` | string array | Names corresponding to `pre_approved_agent_privileges`. | | `project_id` | integer | ID of the associated project. `null` if not set. | | `status` | string | Current flow status. One of `created`, `running`, `paused`, `finished`, `failed`, `stopped`, `input_required`, `plan_approval_required`, or `tool_call_approval_required`. | | `workflow_definition` | string | Flow type identifier. | | `workload` | object | Information about the workload. | | `workload.id` | string | ID of the workload. | | `workload.message` | string | Status message for the workload. | ### Look up the consumer ID Before you can use `ai_catalog_item_consumer_id`, you must use the GraphQL API to retrieve the ID from the [AI Catalog](https://docs.gitlab.com/user/duo_agent_platform/ai_catalog/) . The item must already be enabled for the project. query { aiCatalogConfiguredItems(projectId: "gid://gitlab/Project/") { nodes { id item { name } } } } The `id` field is a Global ID in the format `gid://gitlab/AiCatalogItemConsumer/`. Use the numeric suffix as the `ai_catalog_item_consumer_id` value. Example request using a built-in flow type: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "project_id": "5", "goal": "Fix the failing pipeline by correcting the syntax error in .gitlab-ci.yml", "workflow_definition": "developer/v1", "start_workflow": true }' \ --url "https://gitlab.example.com/api/v4/ai/duo_workflows/workflows" Example request using a catalog-configured flow: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "project_id": "5", "goal": "Fix the failing pipeline by correcting the syntax error in .gitlab-ci.yml", "ai_catalog_item_consumer_id": 12, "start_workflow": true }' \ --url "https://gitlab.example.com/api/v4/ai/duo_workflows/workflows" Example response: { "id": 1, "project_id": 5, "namespace_id": null, "agent_privileges": [1, 2, 3, 4, 5, 6], "agent_privileges_names": [\ "read_write_files",\ "read_only_gitlab",\ "read_write_gitlab",\ "run_commands",\ "use_git",\ "run_mcp_tools"\ ], "pre_approved_agent_privileges": [], "pre_approved_agent_privileges_names": [], "workflow_definition": "developer/v1", "status": "running", "allow_agent_to_request_user": true, "image": null, "environment": null, "ai_catalog_item_version_id": null, "workload": { "id": "abc-123", "message": "Workflow started" }, "mcp_enabled": false, "gitlab_url": "https://gitlab.example.com" } List all agent privileges ------------------------- Lists all available agent privileges with their IDs, names, descriptions, and whether each is enabled by default. GET /ai/duo_workflows/workflows/agent_privileges This endpoint has no supported attributes. If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `all_privileges` | array of objects | All available agent privileges. | | `all_privileges[].default_enabled` | boolean | Whether the privilege is enabled by default. | | `all_privileges[].description` | string | Human-readable description of what the privilege permits. | | `all_privileges[].id` | integer | Privilege ID. | | `all_privileges[].name` | string | Machine-readable privilege name. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/ai/duo_workflows/workflows/agent_privileges" Example response: { "all_privileges": [\ {\ "id": 1,\ "name": "read_write_files",\ "description": "Allow local filesystem read/write access",\ "default_enabled": true\ },\ {\ "id": 2,\ "name": "read_only_gitlab",\ "description": "Allow read only access to GitLab APIs",\ "default_enabled": true\ },\ {\ "id": 3,\ "name": "read_write_gitlab",\ "description": "Allow write access to GitLab APIs",\ "default_enabled": true\ },\ {\ "id": 4,\ "name": "run_commands",\ "description": "Allow running any commands",\ "default_enabled": true\ },\ {\ "id": 5,\ "name": "use_git",\ "description": "Allow git commits, push and other git commands",\ "default_enabled": true\ },\ {\ "id": 6,\ "name": "run_mcp_tools",\ "description": "Allow running MCP tools",\ "default_enabled": true\ }\ ] } --- # GitLab To-Do List API | GitLab Docs * * * GitLab To-Do List API ===================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with [to-do items](https://docs.gitlab.com/user/todos/) . List all to-do items -------------------- Lists all to-do items. When no filter is applied, it returns all pending to-do items for the current user. Different filters allow the user to refine the request. GET /todos Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `action` | string | no | The action to be filtered. Can be `assigned`, `mentioned`, `build_failed`, `marked`, `approval_required`, `unmergeable`, `directly_addressed`, `merge_train_removed` or `member_access_requested`. | | `author_id` | integer | no | The ID of an author | | `project_id` | integer | no | The ID of a project | | `group_id` | integer | no | The ID of a group | | `state` | string | no | The state of the to-do item. Can be either `pending` or `done` | | `type` | string | no | The type of to-do item. Can be either `Issue`, `MergeRequest`, `Commit`, `Epic`, `DesignManagement::Design`, `AlertManagement::Alert`, `Project`, `Namespace`, `Vulnerability` or `WikiPage::Meta` | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/todos" Example Response: [\ {\ "id": 102,\ "project": {\ "id": 2,\ "name": "Gitlab Ce",\ "name_with_namespace": "Gitlab Org / Gitlab Ce",\ "path": "gitlab-foss",\ "path_with_namespace": "gitlab-org/gitlab-foss"\ },\ "author": {\ "name": "Administrator",\ "username": "root",\ "id": 1,\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/root"\ },\ "action_name": "marked",\ "target_type": "MergeRequest",\ "target": {\ "id": 34,\ "iid": 7,\ "project_id": 2,\ "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",\ "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.",\ "state": "opened",\ "created_at": "2016-06-17T07:49:24.419Z",\ "updated_at": "2016-06-17T07:52:43.484Z",\ "target_branch": "tutorials_git_tricks",\ "source_branch": "DNSBL_docs",\ "upvotes": 0,\ "downvotes": 0,\ "author": {\ "name": "Maxie Medhurst",\ "username": "craig_rutherford",\ "id": 12,\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/craig_rutherford"\ },\ "assignee": {\ "name": "Administrator",\ "username": "root",\ "id": 1,\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/root"\ },\ "source_project_id": 2,\ "target_project_id": 2,\ "labels": [],\ "draft": false,\ "work_in_progress": false,\ "milestone": {\ "id": 32,\ "iid": 2,\ "project_id": 2,\ "title": "v1.0",\ "description": "Assumenda placeat ea voluptatem voluptate qui.",\ "state": "active",\ "created_at": "2016-06-17T07:47:34.163Z",\ "updated_at": "2016-06-17T07:47:34.163Z",\ "due_date": null\ },\ "merge_when_pipeline_succeeds": false,\ "merge_status": "cannot_be_merged",\ "user_notes_count": 7\ },\ "target_url": "https://gitlab.example.com/gitlab-org/gitlab-foss/-/merge_requests/7",\ "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",\ "state": "pending",\ "created_at": "2016-06-17T07:52:35.225Z",\ "updated_at": "2016-06-17T07:52:35.225Z"\ },\ {\ "id": 98,\ "project": {\ "id": 2,\ "name": "Gitlab Ce",\ "name_with_namespace": "Gitlab Org / Gitlab Ce",\ "path": "gitlab-foss",\ "path_with_namespace": "gitlab-org/gitlab-foss"\ },\ "author": {\ "name": "Maxie Medhurst",\ "username": "craig_rutherford",\ "id": 12,\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/craig_rutherford"\ },\ "action_name": "assigned",\ "target_type": "MergeRequest",\ "target": {\ "id": 34,\ "iid": 7,\ "project_id": 2,\ "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",\ "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.",\ "state": "opened",\ "created_at": "2016-06-17T07:49:24.419Z",\ "updated_at": "2016-06-17T07:52:43.484Z",\ "target_branch": "tutorials_git_tricks",\ "source_branch": "DNSBL_docs",\ "upvotes": 0,\ "downvotes": 0,\ "author": {\ "name": "Maxie Medhurst",\ "username": "craig_rutherford",\ "id": 12,\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/craig_rutherford"\ },\ "assignee": {\ "name": "Administrator",\ "username": "root",\ "id": 1,\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/root"\ },\ "source_project_id": 2,\ "target_project_id": 2,\ "labels": [],\ "draft": false,\ "work_in_progress": false,\ "milestone": {\ "id": 32,\ "iid": 2,\ "project_id": 2,\ "title": "v1.0",\ "description": "Assumenda placeat ea voluptatem voluptate qui.",\ "state": "active",\ "created_at": "2016-06-17T07:47:34.163Z",\ "updated_at": "2016-06-17T07:47:34.163Z",\ "due_date": null\ },\ "merge_when_pipeline_succeeds": false,\ "merge_status": "cannot_be_merged",\ "user_notes_count": 7\ },\ "target_url": "https://gitlab.example.com/gitlab-org/gitlab-foss/-/merge_requests/7",\ "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",\ "state": "pending",\ "created_at": "2016-06-17T07:49:24.624Z",\ "updated_at": "2016-06-17T07:49:24.624Z"\ }\ ] Mark a to-do item as done ------------------------- Marks a single pending to-do item given by its ID for the current user as done. The to-do item marked as done is returned in the response. POST /todos/:id/mark_as_done Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID of to-do item | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/todos/130/mark_as_done" Example Response: { "id": 102, "project": { "id": 2, "name": "Gitlab Ce", "name_with_namespace": "Gitlab Org / Gitlab Ce", "path": "gitlab-foss", "path_with_namespace": "gitlab-org/gitlab-foss" }, "author": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "https://gitlab.example.com/root" }, "action_name": "marked", "target_type": "MergeRequest", "target": { "id": 34, "iid": 7, "project_id": 2, "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.", "state": "opened", "created_at": "2016-06-17T07:49:24.419Z", "updated_at": "2016-06-17T07:52:43.484Z", "target_branch": "tutorials_git_tricks", "source_branch": "DNSBL_docs", "upvotes": 0, "downvotes": 0, "author": { "name": "Maxie Medhurst", "username": "craig_rutherford", "id": 12, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", "web_url": "https://gitlab.example.com/craig_rutherford" }, "assignee": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "https://gitlab.example.com/root" }, "source_project_id": 2, "target_project_id": 2, "labels": [], "draft": false, "work_in_progress": false, "milestone": { "id": 32, "iid": 2, "project_id": 2, "title": "v1.0", "description": "Assumenda placeat ea voluptatem voluptate qui.", "state": "active", "created_at": "2016-06-17T07:47:34.163Z", "updated_at": "2016-06-17T07:47:34.163Z", "due_date": null }, "merge_when_pipeline_succeeds": false, "merge_status": "cannot_be_merged", "subscribed": true, "user_notes_count": 7 }, "target_url": "https://gitlab.example.com/gitlab-org/gitlab-foss/-/merge_requests/7", "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", "state": "done", "created_at": "2016-06-17T07:52:35.225Z", "updated_at": "2016-06-17T07:52:35.225Z" } Mark all to-do items as done ---------------------------- Marks all pending to-do items for the current user as done. It returns the HTTP status code `204` with an empty response. POST /todos/mark_as_done curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/todos/mark_as_done" --- # GLQL API | GitLab Docs * * * GLQL API ======== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/209517) in GitLab 18.7. Use this API to execute [GitLab Query Language (GLQL)](https://docs.gitlab.com/user/glql/) queries programmatically. GLQL provides a simplified query language for searching and filtering [GitLab resources](https://docs.gitlab.com/user/glql/#supported-areas) such as issues, merge requests, and epics across projects and groups. Prerequisites: * The group or project must allow access to its data. * For private groups and projects, you must use [a personal access token](https://docs.gitlab.com/user/profile/personal_access_tokens/) with appropriate permissions. Execute a GLQL query -------------------- Executes a GLQL query to search and filter GitLab resources. POST /glql This endpoint rate-limits queries based on the query SHA. Identical queries that time out are tracked and might be temporarily blocked if executed too frequently. Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `glql_yaml` | string | Yes | The GLQL query with optional YAML configuration. Maximum size: 10,000 bytes (10 KB). See [Query formats](https://docs.gitlab.com/api/glql/#query-formats)
for details. | | `after` | string | No | Cursor for pagination. Use the `data.pageInfo.endCursor` value from a previous query to fetch the next page of results. | ### Query formats The `glql_yaml` parameter accepts the YAML format with a `query` key: fields: id,title,author group: my-group limit: 10 sort: created desc query: state = opened ### Configuration options The following configuration options can be included in the YAML: | Option | Type | Required | Description | | --- | --- | --- | --- | | `fields` | string | No | Comma-separated list of fields to return. Default: `title`. See [available fields](https://docs.gitlab.com/api/glql/#available-fields)
. | | `group` | string | No | Scope the query to a specific group. Cannot be used with `project`. If `group` is also specified in the query, the query value takes precedence. | | `limit` | integer | No | Maximum number of results to return. Must be between 1 and 100. Default: `100`. | | `project` | string | No | Scope the query to a specific project. Format: `group/project`. If `project` is also specified in the query, the query value takes precedence. | | `sort` | string | No | Sort order for results. Format: `field direction` (for example, `created asc` or `created desc`). | ### Available fields The `fields` configuration option is defined by [GLQL’s available fields](https://docs.gitlab.com/user/glql/fields/) . ### GLQL query syntax The query syntax is defined by [GLQL](https://docs.gitlab.com/user/glql/#query-syntax) . ### Response attributes If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `data` | object | Contains the query results. | | `data.count` | integer | Total number of matching results. | | `data.nodes` | array | Array of matching resources with requested fields. | | `data.pageInfo` | object | Pagination information. | | `data.pageInfo.endCursor` | string | Cursor for fetching the next page of results. | | `data.pageInfo.hasNextPage` | boolean | Indicates if more results are available. | | `data.pageInfo.hasPreviousPage` | boolean | Indicates if previous results are available. | | `data.pageInfo.startCursor` | string | Cursor for fetching the previous page of results. | | `error` | string | Error message if the query failed. | | `fields` | array | Array of field definitions. | | `fields[].key` | string | The unique field identifier. | | `fields[].label` | string | The human-readable field name. | | `fields[].name` | string | The common field name that unifies similar fields. For example, `created` and `createdAt` keys have the name `createdAt`. | | `success` | boolean | Indicates if the query was successful. | ### Example: Basic query Search for opened issues in a group: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "glql_yaml": "query: group = \"my-group\" AND state = opened" }' \ --url "https://gitlab.example.com/api/v4/glql" Example response: { "data": { "count": 1, "nodes": [\ {\ "id": "gid://gitlab/Issue/123",\ "iid": "123",\ "reference": "#123",\ "state": "OPEN",\ "title": "Add an example of GoLang HTTP server",\ "webUrl": "https://gitlab.example.com/my-group/my-project/-/issues/123",\ "widgets": null\ }\ ], "pageInfo": { "endCursor": "eyJpZCI6IjEyMyJ9", "hasNextPage": false, "hasPreviousPage": false, "startCursor": "eyJpZCI6IjEyMyJ9" } }, "error": null, "fields": [\ {\ "key": "title",\ "label": "Title",\ "name": "title"\ }\ ], "success": true } ### Example: Query with front matter configuration Search with custom fields and sorting: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "glql_yaml": "fields: id,title,author,state\ngroup: my-group\nlimit: 5\nsort: created desc\nquery: state = opened" }' \ --url "https://gitlab.example.com/api/v4/glql" Example response: { "data": { "count": 2, "nodes": [\ {\ "author": {\ "avatarUrl": "https://www.gravatar.com/avatar/4a17cff4a15e98966063bd203d88aceac682c623e74943a08cdbe0cce87c6d7c?s=80&d=identicon",\ "id": "gid://gitlab/User/123",\ "name": "John Doe",\ "username": "johndoe",\ "webUrl": "https://gitlab.example.com/johndoe"\ },\ "id": "gid://gitlab/Issue/123",\ "iid": "123",\ "reference": "#123",\ "state": "OPEN",\ "title": "Add an example of GoLang HTTP server",\ "webUrl": "https://gitlab.example.com/my-group/my-project/-/issues/123",\ "widgets": null\ },\ {\ "author": {\ "avatarUrl": "https://www.gravatar.com/avatar/4a17cff4a15e98966063bd203d88aceac682c623e74943a08cdbe0cce87c6d7c?s=80&d=identicon",\ "id": "gid://gitlab/User/122",\ "name": "Jane Doe",\ "username": "janedoe",\ "webUrl": "https://gitlab.example.com/janedoe"\ },\ "id": "gid://gitlab/Issue/122",\ "iid": "122",\ "reference": "#122",\ "state": "OPEN",\ "title": "HTTP server examples for all programming languages",\ "webUrl": "https://gitlab.example.com/groups/my-group/-/issues/122",\ "widgets": null\ }\ ], "pageInfo": { "endCursor": "eyJpZCI6IjEyMyJ9", "hasNextPage": false, "hasPreviousPage": false, "startCursor": "eyJpZCI6IjEyMyJ9" } }, "error": null, "fields": [\ {\ "key": "id",\ "label": "ID",\ "name": "id"\ },\ {\ "key": "title",\ "label": "Title",\ "name": "title"\ },\ {\ "key": "author",\ "label": "Author",\ "name": "author"\ },\ {\ "key": "state",\ "label": "State",\ "name": "state"\ }\ ], "success": true } ### Example: Query with project scope Search in a specific project: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "glql_yaml": "query: project = \"my-group/my-project\" AND state = opened" }' \ --url "https://gitlab.example.com/api/v4/glql" ### Example: Query with `currentUser()` function Search for issues assigned to the current user: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "glql_yaml": "fields: id,title,assignees\nquery: group = \"my-group\" AND assignee = currentUser()" }' \ --url "https://gitlab.example.com/api/v4/glql" Example response: { "data": { "count": 1, "nodes": [\ {\ "assignees": {\ "nodes": [\ {\ "avatarUrl": "https://www.gravatar.com/avatar/4a17cff4a15e98966063bd203d88aceac682c623e74943a08cdbe0cce87c6d7c?s=80&d=identicon",\ "id": "gid://gitlab/User/123",\ "name": "John Doe",\ "username": "johndoe",\ "webUrl": "https://gitlab.example.com/johndoe"\ }\ ]\ },\ "id": "gid://gitlab/Issue/123",\ "iid": "123",\ "reference": "#123",\ "state": "OPEN",\ "title": "Add an example of GoLang HTTP server",\ "webUrl": "https://gitlab.example.com/my-group/my-project/-/issues/123",\ "widgets": null\ }\ ], "pageInfo": { "endCursor": "eyJpZCI6IjEyMyJ9", "hasNextPage": false, "hasPreviousPage": false, "startCursor": "eyJpZCI6IjEyMyJ9" } }, "error": null, "fields": [\ {\ "key": "id",\ "label": "ID",\ "name": "id"\ },\ {\ "key": "title",\ "label": "Title",\ "name": "title"\ },\ {\ "key": "assignees",\ "label": "Assignees",\ "name": "assignees"\ }\ ], "success": true } ### Example: Query with limit and pagination Retrieve a limited number of results and paginate through them: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "glql_yaml": "limit: 2\nquery: group = \"my-group\" AND state = opened" }' \ --url "https://gitlab.example.com/api/v4/glql" Example response: { "data": { "count": 68, "nodes": [\ {\ "id": "gid://gitlab/Issue/321",\ "iid": "321",\ "reference": "#321",\ "state": "OPEN",\ "title": "Corrupti consectetur impedit non blanditiis hic vitae minus.",\ "webUrl": "https://gitlab.example.com/my-group/my-project/-/issues/321",\ "widgets": null\ },\ {\ "id": "gid://gitlab/WorkItem/322",\ "iid": "322",\ "reference": "#322",\ "state": "OPEN",\ "title": "Ipsa cupiditate corrupti vel maxime quasi at assumenda repellat quod.",\ "webUrl": "https://gitlab.example.com/my-group/my-project/-/issues/322",\ "widgets": null\ }\ ], "pageInfo": { "endCursor": "eyJpZCI6IjIifQ==", "hasNextPage": true, "hasPreviousPage": false, "startCursor": "eyJpZCI6IjEyMyJ9" } }, "error": null, "fields": [\ {\ "key": "title",\ "label": "Title",\ "name": "title"\ }\ ], "success": true } To fetch the next page, use the `endCursor` value from the previous response: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "glql_yaml": "limit: 2\nquery: group = \"my-group\" AND state = opened", "after": "eyJpZCI6IjIifQ==" }' \ --url "https://gitlab.example.com/api/v4/glql" Rate limiting ------------- The GLQL API implements rate limiting based on the SHA-256 hash of the query. Queries that time out are tracked. If a particular query that is timing out is executed too frequently, it is temporarily blocked. When rate limited, the API returns a `429 Too Many Requests` status code with an error message: { "error": "Query temporarily blocked due to repeated timeouts. Please try again later or narrow your search scope." } Error handling -------------- The API returns the following HTTP status codes: | Status code | Description | | --- | --- | | `200 Success` | Query executed successfully. | | `400 Bad Request` | Invalid query syntax, missing required parameters, or input exceeds size limit. | | `401 Unauthorized` | Authentication required or invalid credentials. | | `403 Forbidden` | Insufficient permissions or missing required OAuth scope. | | `429 Too Many Requests` | Query rate limit exceeded. | | `500 Internal Server Error` | Server error during query execution. | ### Error response examples * Missing required parameter: { "error": "glql_yaml is missing, glql_yaml is empty" } * Invalid GLQL syntax: { "error": "400 Bad request - Error: Unexpected `invalid syntax @@@ ###`, expected operator (one of IN, =, !=, >, or <)" } * Input size exceeded: { "error": "400 Bad request - Input exceeds maximum size" } * Non-existent project: { "error": "400 Bad request - Error: Project does not exist or you do not have access to it" } * Non-existent group: { "error": "400 Bad request - Error: Group does not exist or you do not have access to it" } * Rate limit exceeded: { "error": "Query temporarily blocked due to repeated timeouts. Please try again later or narrow your search scope." } * Invalid field { "error": "Field 'title' doesn't exist on type 'WorkItem' (Did you mean `title`?)" } GraphQL bad request errors are passed through to the API `error` field when applicable with the `400` error code. Limits and constraints ---------------------- The GLQL API has the following limits: * Maximum input size: 10,000 bytes (10 KB) for the `glql_yaml` parameter. * Maximum query limit: 100 results per request. * Default limit: 100 results when not specified. * Pagination: Only forward pagination is supported using the `after` attribute with the `endCursor` value from a previous response. * Rate limiting: Queries are rate-limited based on query SHA-256 hash. Related topics -------------- * [GLQL query language documentation](https://docs.gitlab.com/user/glql/) * [REST API authentication](https://docs.gitlab.com/api/rest/authentication/) * [OAuth 2.0 authentication](https://docs.gitlab.com/api/oauth2/) --- # Geo sites API | GitLab Docs * * * Geo sites API ============= * Tier: Premium, Ultimate * Offering: GitLab Self-Managed History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369140) in GitLab 16.0. Use this API to manage [Geo sites](https://docs.gitlab.com/administration/geo/) . Prerequisites: * You must be an administrator. Create a Geo site ----------------- History * `blob_download_timeout` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/work_items/569919) in GitLab 18.10. Creates a Geo site. POST /geo_sites curl --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_sites" \ --request POST \ -d "name=himynameissomething" \ -d "url=https://another-node.example.com/" | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `primary` | boolean | no | Specifying whether this site should be primary. Defaults to false. | | `enabled` | boolean | no | Flag indicating if the Geo site is enabled. Defaults to true. | | `name` | string | yes | The unique identifier for the Geo site. Must match `geo_node_name` if it is set in `gitlab.rb`, otherwise it must match `external_url` | | `url` | string | yes | The user-facing URL for the Geo site. | | `internal_url` | string | no | The URL defined on the primary site that secondary sites should use to contact it. Returns `url` if not set. | | `files_max_capacity` | integer | no | Control the maximum concurrency of LFS/attachment backfill for this secondary site. Defaults to 10. | | `repos_max_capacity` | integer | no | Control the maximum concurrency of repository backfill for this secondary site. Defaults to 25. | | `verification_max_capacity` | integer | no | Control the maximum concurrency of repository verification for this site. Defaults to 100. | | `container_repositories_max_capacity` | integer | no | Control the maximum concurrency of container repository sync for this site. Defaults to 10. | | `sync_object_storage` | boolean | no | Flag indicating if the secondary Geo site should replicate blobs in Object Storage. Defaults to false. | | `selective_sync_type` | string | no | Limit syncing to only specific groups or shards. Valid values: `"namespaces"`, `"shards"`, or `null`. | | `selective_sync_shards` | array | no | The repository storage for the projects synced if `selective_sync_type` == `shards`. | | `selective_sync_namespace_ids` | array | no | The IDs of groups that should be synced, if `selective_sync_type` == `namespaces`. | | `minimum_reverification_interval` | integer | no | The interval (in days) in which the repository verification is valid. Once expired, it is reverified. This has no effect when set on a secondary site. | | `blob_download_timeout` | integer | no | The timeout (in seconds) for blob replication. Defaults to 28800. Maximum is 86400. | Example response: { "id": 3, "name": "Test Site 1", "url": "https://secondary.example.com/", "internal_url": "https://secondary.example.com/", "primary": false, "enabled": true, "current": false, "files_max_capacity": 10, "repos_max_capacity": 25, "verification_max_capacity": 100, "container_repositories_max_capacity": 10, "selective_sync_type": "namespaces", "selective_sync_shards": [], "selective_sync_namespace_ids": [1, 25], "minimum_reverification_interval": 7, "sync_object_storage": false, "blob_download_timeout": 28800, "web_edit_url": "https://primary.example.com/admin/geo/sites/3/edit", "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/3/replication/lfs_objects", "_links": { "self": "https://primary.example.com/api/v4/geo_sites/3", "status": "https://primary.example.com/api/v4/geo_sites/3/status", "repair": "https://primary.example.com/api/v4/geo_sites/3/repair" } } List all Geo sites ------------------ Lists all Geo sites. GET /geo_sites curl --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_sites" Example response: [\ {\ "id": 1,\ "name": "us-site",\ "url": "https://primary.example.com/",\ "internal_url": "https://internal.example.com/",\ "primary": true,\ "enabled": true,\ "current": true,\ "files_max_capacity": 10,\ "repos_max_capacity": 25,\ "verification_max_capacity": 100,\ "container_repositories_max_capacity": 10,\ "selective_sync_type": "namespaces",\ "selective_sync_shards": [],\ "selective_sync_namespace_ids": [1, 25],\ "minimum_reverification_interval": 7,\ "blob_download_timeout": 28800,\ "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit",\ "_links": {\ "self": "https://primary.example.com/api/v4/geo_sites/1",\ "status":"https://primary.example.com/api/v4/geo_sites/1/status",\ "repair":"https://primary.example.com/api/v4/geo_sites/1/repair"\ }\ },\ {\ "id": 2,\ "name": "cn-site",\ "url": "https://secondary.example.com/",\ "internal_url": "https://secondary.example.com/",\ "primary": false,\ "enabled": true,\ "current": false,\ "files_max_capacity": 10,\ "repos_max_capacity": 25,\ "verification_max_capacity": 100,\ "container_repositories_max_capacity": 10,\ "selective_sync_type": "namespaces",\ "selective_sync_shards": [],\ "selective_sync_namespace_ids": [1, 25],\ "minimum_reverification_interval": 7,\ "sync_object_storage": true,\ "blob_download_timeout": 28800,\ "web_edit_url": "https://primary.example.com/admin/geo/sites/2/edit",\ "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/2/replication/lfs_objects",\ "_links": {\ "self":"https://primary.example.com/api/v4/geo_sites/2",\ "status":"https://primary.example.com/api/v4/geo_sites/2/status",\ "repair":"https://primary.example.com/api/v4/geo_sites/2/repair"\ }\ }\ ] Retrieve a Geo site ------------------- Retrieves a specified Geo site. GET /geo_sites/:id curl --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_sites/1" Example response: { "id": 1, "name": "us-site", "url": "https://primary.example.com/", "internal_url": "https://primary.example.com/", "primary": true, "enabled": true, "current": true, "files_max_capacity": 10, "repos_max_capacity": 25, "verification_max_capacity": 100, "container_repositories_max_capacity": 10, "selective_sync_type": "namespaces", "selective_sync_shards": [], "selective_sync_namespace_ids": [1, 25], "minimum_reverification_interval": 7, "blob_download_timeout": 28800, "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit", "_links": { "self": "https://primary.example.com/api/v4/geo_sites/1", "status":"https://primary.example.com/api/v4/geo_sites/1/status", "repair":"https://primary.example.com/api/v4/geo_sites/1/repair" } } Update a Geo site ----------------- History * `blob_download_timeout` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/work_items/569919) in GitLab 18.10. Updates a specified Geo site. PUT /geo_sites/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID of the Geo site. | | `enabled` | boolean | no | Flag indicating if the Geo site is enabled. | | `name` | string | no | The unique identifier for the Geo site. Must match `geo_node_name` if it is set in `gitlab.rb`, otherwise it must match `external_url`. | | `url` | string | no | The user-facing URL of the Geo site. | | `internal_url` | string | no | The URL defined on the primary site that secondary sites should use to contact it. Returns `url` if not set. | | `files_max_capacity` | integer | no | Control the maximum concurrency of LFS/attachment backfill for this secondary site. | | `repos_max_capacity` | integer | no | Control the maximum concurrency of repository backfill for this secondary site. | | `verification_max_capacity` | integer | no | Control the maximum concurrency of verification for this site. | | `container_repositories_max_capacity` | integer | no | Control the maximum concurrency of container repository sync for this site. | | `selective_sync_type` | string | no | Limit syncing to only specific groups or shards. Valid values: `"namespaces"`, `"shards"`, or `null`. | | `selective_sync_shards` | array | no | The repository storage for the projects synced if `selective_sync_type` == `shards`. | | `selective_sync_namespace_ids` | array | no | The IDs of groups that should be synced, if `selective_sync_type` == `namespaces`. | | `minimum_reverification_interval` | integer | no | The interval (in days) in which the repository verification is valid. Once expired, it is reverified. This has no effect when set on a secondary site. | | `blob_download_timeout` | integer | no | The timeout (in seconds) for blob replication. Defaults to 28800. Maximum is 86400. | Example response: { "id": 1, "name": "us-site", "url": "https://primary.example.com/", "internal_url": "https://internal.example.com/", "primary": true, "enabled": true, "current": true, "files_max_capacity": 10, "repos_max_capacity": 25, "verification_max_capacity": 100, "container_repositories_max_capacity": 10, "selective_sync_type": "namespaces", "selective_sync_shards": [], "selective_sync_namespace_ids": [1, 25], "minimum_reverification_interval": 7, "blob_download_timeout": 28800, "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit", "_links": { "self": "https://primary.example.com/api/v4/geo_sites/1", "status": "https://primary.example.com/api/v4/geo_sites/1/status", "repair": "https://primary.example.com/api/v4/geo_sites/1/repair" } } Delete a Geo site ----------------- Deletes a Geo site. DELETE /geo_sites/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID of the Geo site. | Repair a Geo site ----------------- Repairs the OAuth authentication of a Geo site in the event that there is an OAuth synchronization problem between the primary or secondary Geo sites. In that case, this message may be displayed: There are no OAuth application defined for this Geo node. POST /geo_sites/:id/repair Example response: { "id": 1, "name": "us-site", "url": "https://primary.example.com/", "internal_url": "https://primary.example.com/", "primary": true, "enabled": true, "current": true, "files_max_capacity": 10, "repos_max_capacity": 25, "verification_max_capacity": 100, "container_repositories_max_capacity": 10, "blob_download_timeout": 28800, "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit", "_links": { "self": "https://primary.example.com/api/v4/geo_sites/1", "status":"https://primary.example.com/api/v4/geo_sites/1/status", "repair":"https://primary.example.com/api/v4/geo_sites/1/repair" } } List all Geo site statuses -------------------------- Lists all Geo site statuses. GET /geo_sites/status curl --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_sites/status" Example response: [\ {\ "geo_node_id": 1,\ "projects_count": null,\ "container_repositories_replication_enabled": null,\ "ci_secure_files_count": 0,\ "ci_secure_files_checksum_total_count": 0,\ "ci_secure_files_checksummed_count": 0,\ "ci_secure_files_checksum_failed_count": 0,\ "ci_secure_files_synced_count": null,\ "ci_secure_files_failed_count": null,\ "ci_secure_files_registry_count": null,\ "ci_secure_files_verification_total_count": null,\ "ci_secure_files_verified_count": null,\ "ci_secure_files_verification_failed_count": null,\ "container_repositories_count": 0,\ "container_repositories_checksum_total_count": 0,\ "container_repositories_checksummed_count": 0,\ "container_repositories_checksum_failed_count": 0,\ "container_repositories_synced_count": null,\ "container_repositories_failed_count": null,\ "container_repositories_registry_count": null,\ "container_repositories_verification_total_count": null,\ "container_repositories_verified_count": null,\ "container_repositories_verification_failed_count": null,\ "dependency_proxy_blobs_count": 0,\ "dependency_proxy_blobs_checksum_total_count": 0,\ "dependency_proxy_blobs_checksummed_count": 0,\ "dependency_proxy_blobs_checksum_failed_count": 0,\ "dependency_proxy_blobs_synced_count": null,\ "dependency_proxy_blobs_failed_count": null,\ "dependency_proxy_blobs_registry_count": null,\ "dependency_proxy_blobs_verification_total_count": null,\ "dependency_proxy_blobs_verified_count": null,\ "dependency_proxy_blobs_verification_failed_count": null,\ "dependency_proxy_manifests_count": 0,\ "dependency_proxy_manifests_checksum_total_count": 0,\ "dependency_proxy_manifests_checksummed_count": 0,\ "dependency_proxy_manifests_checksum_failed_count": 0,\ "dependency_proxy_manifests_synced_count": null,\ "dependency_proxy_manifests_failed_count": null,\ "dependency_proxy_manifests_registry_count": null,\ "dependency_proxy_manifests_verification_total_count": null,\ "dependency_proxy_manifests_verified_count": null,\ "dependency_proxy_manifests_verification_failed_count": null,\ "design_management_repositories_count": 0,\ "design_management_repositories_checksum_total_count": 0,\ "design_management_repositories_checksummed_count": 0,\ "design_management_repositories_checksum_failed_count": 0,\ "design_management_repositories_synced_count": null,\ "design_management_repositories_failed_count": null,\ "design_management_repositories_registry_count": null,\ "design_management_repositories_verification_total_count": null,\ "design_management_repositories_verified_count": null,\ "design_management_repositories_verification_failed_count": null,\ "group_wiki_repositories_count": 0,\ "group_wiki_repositories_checksum_total_count": 0,\ "group_wiki_repositories_checksummed_count": 0,\ "group_wiki_repositories_checksum_failed_count": 0,\ "group_wiki_repositories_synced_count": null,\ "group_wiki_repositories_failed_count": null,\ "group_wiki_repositories_registry_count": null,\ "group_wiki_repositories_verification_total_count": null,\ "group_wiki_repositories_verified_count": null,\ "group_wiki_repositories_verification_failed_count": null,\ "job_artifacts_count": 100,\ "job_artifacts_checksum_total_count": 100,\ "job_artifacts_checksummed_count": 100,\ "job_artifacts_checksum_failed_count": 0,\ "job_artifacts_synced_count": null,\ "job_artifacts_failed_count": null,\ "job_artifacts_registry_count": null,\ "job_artifacts_verification_total_count": null,\ "job_artifacts_verified_count": null,\ "job_artifacts_verification_failed_count": null,\ "lfs_objects_count": 9,\ "lfs_objects_checksum_total_count": 9,\ "lfs_objects_checksummed_count": 9,\ "lfs_objects_checksum_failed_count": 0,\ "lfs_objects_synced_count": null,\ "lfs_objects_failed_count": null,\ "lfs_objects_registry_count": null,\ "lfs_objects_verification_total_count": null,\ "lfs_objects_verified_count": null,\ "lfs_objects_verification_failed_count": null,\ "merge_request_diffs_count": 0,\ "merge_request_diffs_checksum_total_count": 0,\ "merge_request_diffs_checksummed_count": 0,\ "merge_request_diffs_checksum_failed_count": 0,\ "merge_request_diffs_synced_count": null,\ "merge_request_diffs_failed_count": null,\ "merge_request_diffs_registry_count": null,\ "merge_request_diffs_verification_total_count": null,\ "merge_request_diffs_verified_count": null,\ "merge_request_diffs_verification_failed_count": null,\ "package_files_count": 25,\ "package_files_checksum_total_count": 25,\ "package_files_checksummed_count": 25,\ "package_files_checksum_failed_count": 0,\ "package_files_synced_count": null,\ "package_files_failed_count": null,\ "package_files_registry_count": null,\ "package_files_verification_total_count": null,\ "package_files_verified_count": null,\ "package_files_verification_failed_count": null,\ "pages_deployments_count": 0,\ "pages_deployments_checksum_total_count": 0,\ "pages_deployments_checksummed_count": 0,\ "pages_deployments_checksum_failed_count": 0,\ "pages_deployments_synced_count": null,\ "pages_deployments_failed_count": null,\ "pages_deployments_registry_count": null,\ "pages_deployments_verification_total_count": null,\ "pages_deployments_verified_count": null,\ "pages_deployments_verification_failed_count": null,\ "pipeline_artifacts_count": 0,\ "pipeline_artifacts_checksum_total_count": 0,\ "pipeline_artifacts_checksummed_count": 0,\ "pipeline_artifacts_checksum_failed_count": 0,\ "pipeline_artifacts_synced_count": null,\ "pipeline_artifacts_failed_count": null,\ "pipeline_artifacts_registry_count": null,\ "pipeline_artifacts_verification_total_count": null,\ "pipeline_artifacts_verified_count": null,\ "pipeline_artifacts_verification_failed_count": null,\ "project_repositories_count": 19,\ "project_repositories_checksum_total_count": 19,\ "project_repositories_checksummed_count": 19,\ "project_repositories_checksum_failed_count": 0,\ "project_repositories_synced_count": null,\ "project_repositories_failed_count": null,\ "project_repositories_registry_count": null,\ "project_repositories_verification_total_count": null,\ "project_repositories_verified_count": null,\ "project_repositories_verification_failed_count": null,\ "project_wiki_repositories_count": 19,\ "project_wiki_repositories_checksum_total_count": 19,\ "project_wiki_repositories_checksummed_count": 19,\ "project_wiki_repositories_checksum_failed_count": 0,\ "project_wiki_repositories_synced_count": null,\ "project_wiki_repositories_failed_count": null,\ "project_wiki_repositories_registry_count": null,\ "project_wiki_repositories_verification_total_count": null,\ "project_wiki_repositories_verified_count": null,\ "project_wiki_repositories_verification_failed_count": null,\ "snippet_repositories_count": 20,\ "snippet_repositories_checksum_total_count": 20,\ "snippet_repositories_checksummed_count": 20,\ "snippet_repositories_checksum_failed_count": 0,\ "snippet_repositories_synced_count": null,\ "snippet_repositories_failed_count": null,\ "snippet_repositories_registry_count": null,\ "snippet_repositories_verification_total_count": null,\ "snippet_repositories_verified_count": null,\ "snippet_repositories_verification_failed_count": null,\ "terraform_state_versions_count": 18,\ "terraform_state_versions_checksum_total_count": 18,\ "terraform_state_versions_checksummed_count": 18,\ "terraform_state_versions_checksum_failed_count": 0,\ "terraform_state_versions_synced_count": null,\ "terraform_state_versions_failed_count": null,\ "terraform_state_versions_registry_count": null,\ "terraform_state_versions_verification_total_count": null,\ "terraform_state_versions_verified_count": null,\ "terraform_state_versions_verification_failed_count": null,\ "uploads_count": 55,\ "uploads_checksum_total_count": 55,\ "uploads_checksummed_count": 55,\ "uploads_checksum_failed_count": 0,\ "uploads_synced_count": null,\ "uploads_failed_count": null,\ "uploads_registry_count": null,\ "uploads_verification_total_count": null,\ "uploads_verified_count": null,\ "uploads_verification_failed_count": null,\ "abuse_report_uploads_count": 0,\ "abuse_report_uploads_checksum_total_count": 0,\ "abuse_report_uploads_checksummed_count": 0,\ "abuse_report_uploads_checksum_failed_count": 0,\ "abuse_report_uploads_synced_count": null,\ "abuse_report_uploads_failed_count": null,\ "abuse_report_uploads_registry_count": null,\ "abuse_report_uploads_verification_total_count": null,\ "abuse_report_uploads_verified_count": null,\ "abuse_report_uploads_verification_failed_count": null,\ "abuse_report_uploads_synced_in_percentage": "0.00%",\ "abuse_report_uploads_verified_in_percentage": "0.00%",\ "project_uploads_count": 0,\ "project_uploads_checksum_total_count": 0,\ "project_uploads_checksummed_count": 0,\ "project_uploads_checksum_failed_count": 0,\ "project_uploads_synced_count": null,\ "project_uploads_failed_count": null,\ "project_uploads_registry_count": null,\ "project_uploads_verification_total_count": null,\ "project_uploads_verified_count": null,\ "project_uploads_verification_failed_count": null,\ "project_uploads_synced_in_percentage": "0.00%",\ "project_uploads_verified_in_percentage": "0.00%",\ "group_uploads_count": 0,\ "group_uploads_checksum_total_count": 0,\ "group_uploads_checksummed_count": 0,\ "group_uploads_checksum_failed_count": 0,\ "group_uploads_synced_count": null,\ "group_uploads_failed_count": null,\ "group_uploads_registry_count": null,\ "group_uploads_verification_total_count": null,\ "group_uploads_verified_count": null,\ "group_uploads_verification_failed_count": null,\ "group_uploads_synced_in_percentage": "0.00%",\ "group_uploads_verified_in_percentage": "0.00%",\ "user_uploads_count": 0,\ "user_uploads_checksum_total_count": 0,\ "user_uploads_checksummed_count": 0,\ "user_uploads_checksum_failed_count": 0,\ "user_uploads_synced_count": null,\ "user_uploads_failed_count": null,\ "user_uploads_registry_count": null,\ "user_uploads_verification_total_count": null,\ "user_uploads_verified_count": null,\ "user_uploads_verification_failed_count": null,\ "user_uploads_synced_in_percentage": "0.00%",\ "user_uploads_verified_in_percentage": "0.00%",\ "design_management_action_uploads_count": 0,\ "design_management_action_uploads_checksum_total_count": 0,\ "design_management_action_uploads_checksummed_count": 0,\ "design_management_action_uploads_checksum_failed_count": 0,\ "design_management_action_uploads_synced_count": null,\ "design_management_action_uploads_failed_count": null,\ "design_management_action_uploads_registry_count": null,\ "design_management_action_uploads_verification_total_count": null,\ "design_management_action_uploads_verified_count": null,\ "design_management_action_uploads_verification_failed_count": null,\ "design_management_action_uploads_synced_in_percentage": "0.00%",\ "design_management_action_uploads_verified_in_percentage": "0.00%",\ "achievement_uploads_count": 0,\ "achievement_uploads_checksum_total_count": 0,\ "achievement_uploads_checksummed_count": 0,\ "achievement_uploads_checksum_failed_count": 0,\ "achievement_uploads_synced_count": null,\ "achievement_uploads_failed_count": null,\ "achievement_uploads_registry_count": null,\ "achievement_uploads_verification_total_count": null,\ "achievement_uploads_verified_count": null,\ "achievement_uploads_verification_failed_count": null,\ "achievement_uploads_synced_in_percentage": "0.00%",\ "achievement_uploads_verified_in_percentage": "0.00%",\ "git_fetch_event_count_weekly": null,\ "git_push_event_count_weekly": null,\ "proxy_remote_requests_event_count_weekly": null,\ "proxy_local_requests_event_count_weekly": null,\ "repositories_checked_in_percentage": "0.00%",\ "replication_slots_used_in_percentage": "100.00%",\ "ci_secure_files_synced_in_percentage": "0.00%",\ "ci_secure_files_verified_in_percentage": "0.00%",\ "container_repositories_synced_in_percentage": "0.00%",\ "container_repositories_verified_in_percentage": "0.00%",\ "dependency_proxy_blobs_synced_in_percentage": "0.00%",\ "dependency_proxy_blobs_verified_in_percentage": "0.00%",\ "dependency_proxy_manifests_synced_in_percentage": "0.00%",\ "dependency_proxy_manifests_verified_in_percentage": "0.00%",\ "design_management_repositories_synced_in_percentage": "0.00%",\ "design_management_repositories_verified_in_percentage": "0.00%",\ "group_wiki_repositories_synced_in_percentage": "0.00%",\ "group_wiki_repositories_verified_in_percentage": "0.00%",\ "job_artifacts_synced_in_percentage": "0.00%",\ "job_artifacts_verified_in_percentage": "0.00%",\ "lfs_objects_synced_in_percentage": "0.00%",\ "lfs_objects_verified_in_percentage": "0.00%",\ "merge_request_diffs_synced_in_percentage": "0.00%",\ "merge_request_diffs_verified_in_percentage": "0.00%",\ "package_files_synced_in_percentage": "0.00%",\ "package_files_verified_in_percentage": "0.00%",\ "pages_deployments_synced_in_percentage": "0.00%",\ "pages_deployments_verified_in_percentage": "0.00%",\ "pipeline_artifacts_synced_in_percentage": "0.00%",\ "pipeline_artifacts_verified_in_percentage": "0.00%",\ "project_repositories_synced_in_percentage": "0.00%",\ "project_repositories_verified_in_percentage": "0.00%",\ "project_wiki_repositories_synced_in_percentage": "0.00%",\ "project_wiki_repositories_verified_in_percentage": "0.00%",\ "snippet_repositories_synced_in_percentage": "0.00%",\ "snippet_repositories_verified_in_percentage": "0.00%",\ "terraform_state_versions_synced_in_percentage": "0.00%",\ "terraform_state_versions_verified_in_percentage": "0.00%",\ "uploads_synced_in_percentage": "0.00%",\ "uploads_verified_in_percentage": "0.00%",\ "repositories_count": 19,\ "replication_slots_count": 1,\ "replication_slots_used_count": 1,\ "healthy": true,\ "health": "Healthy",\ "health_status": "Healthy",\ "missing_oauth_application": false,\ "db_replication_lag_seconds": null,\ "replication_slots_max_retained_wal_bytes": 0,\ "repositories_checked_count": null,\ "repositories_checked_failed_count": null,\ "last_event_id": 534,\ "last_event_timestamp": 1746370442,\ "cursor_last_event_id": null,\ "cursor_last_event_timestamp": 0,\ "last_successful_status_check_timestamp": 1746469565,\ "version": "18.0.0-pre",\ "revision": "bff6f8c6c04",\ "selective_sync_type": null,\ "namespaces": [],\ "updated_at": "2025-05-05T18:26:07.379Z",\ "storage_shards_match": true,\ "_links": {\ "self": "https://primary.example.com/api/v4/geo_sites/1/status",\ "site": "https://primary.example.com/api/v4/geo_sites/1"\ }\ },\ {\ "geo_node_id": 2,\ "projects_count": null,\ "container_repositories_replication_enabled": true,\ "ci_secure_files_count": 0,\ "ci_secure_files_checksum_total_count": null,\ "ci_secure_files_checksummed_count": null,\ "ci_secure_files_checksum_failed_count": null,\ "ci_secure_files_synced_count": 0,\ "ci_secure_files_failed_count": 0,\ "ci_secure_files_registry_count": 0,\ "ci_secure_files_verification_total_count": 0,\ "ci_secure_files_verified_count": 0,\ "ci_secure_files_verification_failed_count": 0,\ "container_repositories_count": 0,\ "container_repositories_checksum_total_count": null,\ "container_repositories_checksummed_count": null,\ "container_repositories_checksum_failed_count": null,\ "container_repositories_synced_count": 0,\ "container_repositories_failed_count": 0,\ "container_repositories_registry_count": 0,\ "container_repositories_verification_total_count": 0,\ "container_repositories_verified_count": 0,\ "container_repositories_verification_failed_count": 0,\ "dependency_proxy_blobs_count": 0,\ "dependency_proxy_blobs_checksum_total_count": null,\ "dependency_proxy_blobs_checksummed_count": null,\ "dependency_proxy_blobs_checksum_failed_count": null,\ "dependency_proxy_blobs_synced_count": 0,\ "dependency_proxy_blobs_failed_count": 0,\ "dependency_proxy_blobs_registry_count": 0,\ "dependency_proxy_blobs_verification_total_count": 0,\ "dependency_proxy_blobs_verified_count": 0,\ "dependency_proxy_blobs_verification_failed_count": 0,\ "dependency_proxy_manifests_count": 0,\ "dependency_proxy_manifests_checksum_total_count": null,\ "dependency_proxy_manifests_checksummed_count": null,\ "dependency_proxy_manifests_checksum_failed_count": null,\ "dependency_proxy_manifests_synced_count": 0,\ "dependency_proxy_manifests_failed_count": 0,\ "dependency_proxy_manifests_registry_count": 0,\ "dependency_proxy_manifests_verification_total_count": 0,\ "dependency_proxy_manifests_verified_count": 0,\ "dependency_proxy_manifests_verification_failed_count": 0,\ "design_management_repositories_count": 0,\ "design_management_repositories_checksum_total_count": null,\ "design_management_repositories_checksummed_count": null,\ "design_management_repositories_checksum_failed_count": null,\ "design_management_repositories_synced_count": 0,\ "design_management_repositories_failed_count": 0,\ "design_management_repositories_registry_count": 0,\ "design_management_repositories_verification_total_count": 0,\ "design_management_repositories_verified_count": 0,\ "design_management_repositories_verification_failed_count": 0,\ "group_wiki_repositories_count": 0,\ "group_wiki_repositories_checksum_total_count": null,\ "group_wiki_repositories_checksummed_count": null,\ "group_wiki_repositories_checksum_failed_count": null,\ "group_wiki_repositories_synced_count": 0,\ "group_wiki_repositories_failed_count": 0,\ "group_wiki_repositories_registry_count": 0,\ "group_wiki_repositories_verification_total_count": 0,\ "group_wiki_repositories_verified_count": 0,\ "group_wiki_repositories_verification_failed_count": 0,\ "job_artifacts_count": 100,\ "job_artifacts_checksum_total_count": null,\ "job_artifacts_checksummed_count": null,\ "job_artifacts_checksum_failed_count": null,\ "job_artifacts_synced_count": 100,\ "job_artifacts_failed_count": 0,\ "job_artifacts_registry_count": 100,\ "job_artifacts_verification_total_count": 100,\ "job_artifacts_verified_count": 100,\ "job_artifacts_verification_failed_count": 0,\ "lfs_objects_count": 9,\ "lfs_objects_checksum_total_count": null,\ "lfs_objects_checksummed_count": null,\ "lfs_objects_checksum_failed_count": null,\ "lfs_objects_synced_count": 9,\ "lfs_objects_failed_count": 0,\ "lfs_objects_registry_count": 9,\ "lfs_objects_verification_total_count": 9,\ "lfs_objects_verified_count": 9,\ "lfs_objects_verification_failed_count": 0,\ "merge_request_diffs_count": 0,\ "merge_request_diffs_checksum_total_count": null,\ "merge_request_diffs_checksummed_count": null,\ "merge_request_diffs_checksum_failed_count": null,\ "merge_request_diffs_synced_count": 0,\ "merge_request_diffs_failed_count": 0,\ "merge_request_diffs_registry_count": 0,\ "merge_request_diffs_verification_total_count": 0,\ "merge_request_diffs_verified_count": 0,\ "merge_request_diffs_verification_failed_count": 0,\ "package_files_count": 25,\ "package_files_checksum_total_count": null,\ "package_files_checksummed_count": null,\ "package_files_checksum_failed_count": null,\ "package_files_synced_count": 25,\ "package_files_failed_count": 0,\ "package_files_registry_count": 25,\ "package_files_verification_total_count": 25,\ "package_files_verified_count": 25,\ "package_files_verification_failed_count": 0,\ "pages_deployments_count": 0,\ "pages_deployments_checksum_total_count": null,\ "pages_deployments_checksummed_count": null,\ "pages_deployments_checksum_failed_count": null,\ "pages_deployments_synced_count": 0,\ "pages_deployments_failed_count": 0,\ "pages_deployments_registry_count": 0,\ "pages_deployments_verification_total_count": 0,\ "pages_deployments_verified_count": 0,\ "pages_deployments_verification_failed_count": 0,\ "pipeline_artifacts_count": 0,\ "pipeline_artifacts_checksum_total_count": null,\ "pipeline_artifacts_checksummed_count": null,\ "pipeline_artifacts_checksum_failed_count": null,\ "pipeline_artifacts_synced_count": 0,\ "pipeline_artifacts_failed_count": 0,\ "pipeline_artifacts_registry_count": 0,\ "pipeline_artifacts_verification_total_count": 0,\ "pipeline_artifacts_verified_count": 0,\ "pipeline_artifacts_verification_failed_count": 0,\ "project_repositories_count": 19,\ "project_repositories_checksum_total_count": null,\ "project_repositories_checksummed_count": null,\ "project_repositories_checksum_failed_count": null,\ "project_repositories_synced_count": 19,\ "project_repositories_failed_count": 0,\ "project_repositories_registry_count": 19,\ "project_repositories_verification_total_count": 19,\ "project_repositories_verified_count": 19,\ "project_repositories_verification_failed_count": 0,\ "project_wiki_repositories_count": 19,\ "project_wiki_repositories_checksum_total_count": null,\ "project_wiki_repositories_checksummed_count": null,\ "project_wiki_repositories_checksum_failed_count": null,\ "project_wiki_repositories_synced_count": 19,\ "project_wiki_repositories_failed_count": 0,\ "project_wiki_repositories_registry_count": 19,\ "project_wiki_repositories_verification_total_count": 19,\ "project_wiki_repositories_verified_count": 19,\ "project_wiki_repositories_verification_failed_count": 0,\ "snippet_repositories_count": 20,\ "snippet_repositories_checksum_total_count": null,\ "snippet_repositories_checksummed_count": null,\ "snippet_repositories_checksum_failed_count": null,\ "snippet_repositories_synced_count": 20,\ "snippet_repositories_failed_count": 0,\ "snippet_repositories_registry_count": 20,\ "snippet_repositories_verification_total_count": 20,\ "snippet_repositories_verified_count": 20,\ "snippet_repositories_verification_failed_count": 0,\ "terraform_state_versions_count": 18,\ "terraform_state_versions_checksum_total_count": null,\ "terraform_state_versions_checksummed_count": null,\ "terraform_state_versions_checksum_failed_count": null,\ "terraform_state_versions_synced_count": 18,\ "terraform_state_versions_failed_count": 0,\ "terraform_state_versions_registry_count": 18,\ "terraform_state_versions_verification_total_count": 18,\ "terraform_state_versions_verified_count": 18,\ "terraform_state_versions_verification_failed_count": 0,\ "uploads_count": 55,\ "uploads_checksum_total_count": null,\ "uploads_checksummed_count": null,\ "uploads_checksum_failed_count": null,\ "uploads_synced_count": 55,\ "uploads_failed_count": 0,\ "uploads_registry_count": 55,\ "uploads_verification_total_count": 55,\ "uploads_verified_count": 55,\ "uploads_verification_failed_count": 0,\ "abuse_report_uploads_count": 0,\ "abuse_report_uploads_checksum_total_count": 0,\ "abuse_report_uploads_checksummed_count": 0,\ "abuse_report_uploads_checksum_failed_count": 0,\ "abuse_report_uploads_synced_count": null,\ "abuse_report_uploads_failed_count": null,\ "abuse_report_uploads_registry_count": null,\ "abuse_report_uploads_verification_total_count": null,\ "abuse_report_uploads_verified_count": null,\ "abuse_report_uploads_verification_failed_count": null,\ "abuse_report_uploads_synced_in_percentage": "0.00%",\ "abuse_report_uploads_verified_in_percentage": "0.00%",\ "project_uploads_count": 0,\ "project_uploads_checksum_total_count": 0,\ "project_uploads_checksummed_count": 0,\ "project_uploads_checksum_failed_count": 0,\ "project_uploads_synced_count": null,\ "project_uploads_failed_count": null,\ "project_uploads_registry_count": null,\ "project_uploads_verification_total_count": null,\ "project_uploads_verified_count": null,\ "project_uploads_verification_failed_count": null,\ "project_uploads_synced_in_percentage": "0.00%",\ "project_uploads_verified_in_percentage": "0.00%",\ "group_uploads_count": 0,\ "group_uploads_checksum_total_count": 0,\ "group_uploads_checksummed_count": 0,\ "group_uploads_checksum_failed_count": 0,\ "group_uploads_synced_count": null,\ "group_uploads_failed_count": null,\ "group_uploads_registry_count": null,\ "group_uploads_verification_total_count": null,\ "group_uploads_verified_count": null,\ "group_uploads_verification_failed_count": null,\ "group_uploads_synced_in_percentage": "0.00%",\ "group_uploads_verified_in_percentage": "0.00%",\ "user_uploads_count": 0,\ "user_uploads_checksum_total_count": 0,\ "user_uploads_checksummed_count": 0,\ "user_uploads_checksum_failed_count": 0,\ "user_uploads_synced_count": null,\ "user_uploads_failed_count": null,\ "user_uploads_registry_count": null,\ "user_uploads_verification_total_count": null,\ "user_uploads_verified_count": null,\ "user_uploads_verification_failed_count": null,\ "user_uploads_synced_in_percentage": "0.00%",\ "user_uploads_verified_in_percentage": "0.00%",\ "design_management_action_uploads_count": 0,\ "design_management_action_uploads_checksum_total_count": 0,\ "design_management_action_uploads_checksummed_count": 0,\ "design_management_action_uploads_checksum_failed_count": 0,\ "design_management_action_uploads_synced_count": null,\ "design_management_action_uploads_failed_count": null,\ "design_management_action_uploads_registry_count": null,\ "design_management_action_uploads_verification_total_count": null,\ "design_management_action_uploads_verified_count": null,\ "design_management_action_uploads_verification_failed_count": null,\ "design_management_action_uploads_synced_in_percentage": "0.00%",\ "design_management_action_uploads_verified_in_percentage": "0.00%",\ "achievement_uploads_count": 0,\ "achievement_uploads_checksum_total_count": 0,\ "achievement_uploads_checksummed_count": 0,\ "achievement_uploads_checksum_failed_count": 0,\ "achievement_uploads_synced_count": null,\ "achievement_uploads_failed_count": null,\ "achievement_uploads_registry_count": null,\ "achievement_uploads_verification_total_count": null,\ "achievement_uploads_verified_count": null,\ "achievement_uploads_verification_failed_count": null,\ "achievement_uploads_synced_in_percentage": "0.00%",\ "achievement_uploads_verified_in_percentage": "0.00%",\ "git_fetch_event_count_weekly": 0,\ "git_push_event_count_weekly": 0,\ "proxy_remote_requests_event_count_weekly": 0,\ "proxy_local_requests_event_count_weekly": 0,\ "repositories_checked_in_percentage": "0.00%",\ "replication_slots_used_in_percentage": "0.00%",\ "ci_secure_files_synced_in_percentage": "0.00%",\ "ci_secure_files_verified_in_percentage": "0.00%",\ "container_repositories_synced_in_percentage": "0.00%",\ "container_repositories_verified_in_percentage": "0.00%",\ "dependency_proxy_blobs_synced_in_percentage": "0.00%",\ "dependency_proxy_blobs_verified_in_percentage": "0.00%",\ "dependency_proxy_manifests_synced_in_percentage": "0.00%",\ "dependency_proxy_manifests_verified_in_percentage": "0.00%",\ "design_management_repositories_synced_in_percentage": "0.00%",\ "design_management_repositories_verified_in_percentage": "0.00%",\ "group_wiki_repositories_synced_in_percentage": "0.00%",\ "group_wiki_repositories_verified_in_percentage": "0.00%",\ "job_artifacts_synced_in_percentage": "100.00%",\ "job_artifacts_verified_in_percentage": "100.00%",\ "lfs_objects_synced_in_percentage": "100.00%",\ "lfs_objects_verified_in_percentage": "100.00%",\ "merge_request_diffs_synced_in_percentage": "0.00%",\ "merge_request_diffs_verified_in_percentage": "0.00%",\ "package_files_synced_in_percentage": "100.00%",\ "package_files_verified_in_percentage": "100.00%",\ "pages_deployments_synced_in_percentage": "0.00%",\ "pages_deployments_verified_in_percentage": "0.00%",\ "pipeline_artifacts_synced_in_percentage": "0.00%",\ "pipeline_artifacts_verified_in_percentage": "0.00%",\ "project_repositories_synced_in_percentage": "100.00%",\ "project_repositories_verified_in_percentage": "100.00%",\ "project_wiki_repositories_synced_in_percentage": "100.00%",\ "project_wiki_repositories_verified_in_percentage": "100.00%",\ "snippet_repositories_synced_in_percentage": "100.00%",\ "snippet_repositories_verified_in_percentage": "100.00%",\ "terraform_state_versions_synced_in_percentage": "100.00%",\ "terraform_state_versions_verified_in_percentage": "100.00%",\ "uploads_synced_in_percentage": "100.00%",\ "uploads_verified_in_percentage": "100.00%",\ "repositories_count": 19,\ "replication_slots_count": null,\ "replication_slots_used_count": null,\ "healthy": true,\ "health": "Healthy",\ "health_status": "Healthy",\ "missing_oauth_application": false,\ "db_replication_lag_seconds": 0,\ "replication_slots_max_retained_wal_bytes": null,\ "repositories_checked_count": null,\ "repositories_checked_failed_count": null,\ "last_event_id": 534,\ "last_event_timestamp": 1746370442,\ "cursor_last_event_id": 534,\ "cursor_last_event_timestamp": 1746370442,\ "last_successful_status_check_timestamp": 1746469624,\ "version": "18.0.0-pre",\ "revision": "60237485299",\ "selective_sync_type": null,\ "namespaces": [],\ "updated_at": "2025-05-05T18:26:05.000Z",\ "storage_shards_match": true,\ "_links": {\ "self": "https://primary.example.com/api/v4/geo_sites/2/status",\ "site": "https://primary.example.com/api/v4/geo_sites/2"\ }\ }\ ] Retrieve a Geo site status -------------------------- Retrieves a specified Geo site status. GET /geo_sites/:id/status curl --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_sites/2/status" Example response: { "geo_node_id": 2, "projects_count": null, "container_repositories_replication_enabled": true, "ci_secure_files_count": 0, "ci_secure_files_checksum_total_count": null, "ci_secure_files_checksummed_count": null, "ci_secure_files_checksum_failed_count": null, "ci_secure_files_synced_count": 0, "ci_secure_files_failed_count": 0, "ci_secure_files_registry_count": 0, "ci_secure_files_verification_total_count": 0, "ci_secure_files_verified_count": 0, "ci_secure_files_verification_failed_count": 0, "container_repositories_count": 0, "container_repositories_checksum_total_count": null, "container_repositories_checksummed_count": null, "container_repositories_checksum_failed_count": null, "container_repositories_synced_count": 0, "container_repositories_failed_count": 0, "container_repositories_registry_count": 0, "container_repositories_verification_total_count": 0, "container_repositories_verified_count": 0, "container_repositories_verification_failed_count": 0, "dependency_proxy_blobs_count": 0, "dependency_proxy_blobs_checksum_total_count": null, "dependency_proxy_blobs_checksummed_count": null, "dependency_proxy_blobs_checksum_failed_count": null, "dependency_proxy_blobs_synced_count": 0, "dependency_proxy_blobs_failed_count": 0, "dependency_proxy_blobs_registry_count": 0, "dependency_proxy_blobs_verification_total_count": 0, "dependency_proxy_blobs_verified_count": 0, "dependency_proxy_blobs_verification_failed_count": 0, "dependency_proxy_manifests_count": 0, "dependency_proxy_manifests_checksum_total_count": null, "dependency_proxy_manifests_checksummed_count": null, "dependency_proxy_manifests_checksum_failed_count": null, "dependency_proxy_manifests_synced_count": 0, "dependency_proxy_manifests_failed_count": 0, "dependency_proxy_manifests_registry_count": 0, "dependency_proxy_manifests_verification_total_count": 0, "dependency_proxy_manifests_verified_count": 0, "dependency_proxy_manifests_verification_failed_count": 0, "design_management_repositories_count": 0, "design_management_repositories_checksum_total_count": null, "design_management_repositories_checksummed_count": null, "design_management_repositories_checksum_failed_count": null, "design_management_repositories_synced_count": 0, "design_management_repositories_failed_count": 0, "design_management_repositories_registry_count": 0, "design_management_repositories_verification_total_count": 0, "design_management_repositories_verified_count": 0, "design_management_repositories_verification_failed_count": 0, "group_wiki_repositories_count": 0, "group_wiki_repositories_checksum_total_count": null, "group_wiki_repositories_checksummed_count": null, "group_wiki_repositories_checksum_failed_count": null, "group_wiki_repositories_synced_count": 0, "group_wiki_repositories_failed_count": 0, "group_wiki_repositories_registry_count": 0, "group_wiki_repositories_verification_total_count": 0, "group_wiki_repositories_verified_count": 0, "group_wiki_repositories_verification_failed_count": 0, "job_artifacts_count": 100, "job_artifacts_checksum_total_count": null, "job_artifacts_checksummed_count": null, "job_artifacts_checksum_failed_count": null, "job_artifacts_synced_count": 100, "job_artifacts_failed_count": 0, "job_artifacts_registry_count": 100, "job_artifacts_verification_total_count": 100, "job_artifacts_verified_count": 100, "job_artifacts_verification_failed_count": 0, "lfs_objects_count": 9, "lfs_objects_checksum_total_count": null, "lfs_objects_checksummed_count": null, "lfs_objects_checksum_failed_count": null, "lfs_objects_synced_count": 9, "lfs_objects_failed_count": 0, "lfs_objects_registry_count": 9, "lfs_objects_verification_total_count": 9, "lfs_objects_verified_count": 9, "lfs_objects_verification_failed_count": 0, "merge_request_diffs_count": 0, "merge_request_diffs_checksum_total_count": null, "merge_request_diffs_checksummed_count": null, "merge_request_diffs_checksum_failed_count": null, "merge_request_diffs_synced_count": 0, "merge_request_diffs_failed_count": 0, "merge_request_diffs_registry_count": 0, "merge_request_diffs_verification_total_count": 0, "merge_request_diffs_verified_count": 0, "merge_request_diffs_verification_failed_count": 0, "package_files_count": 25, "package_files_checksum_total_count": null, "package_files_checksummed_count": null, "package_files_checksum_failed_count": null, "package_files_synced_count": 25, "package_files_failed_count": 0, "package_files_registry_count": 25, "package_files_verification_total_count": 25, "package_files_verified_count": 25, "package_files_verification_failed_count": 0, "pages_deployments_count": 0, "pages_deployments_checksum_total_count": null, "pages_deployments_checksummed_count": null, "pages_deployments_checksum_failed_count": null, "pages_deployments_synced_count": 0, "pages_deployments_failed_count": 0, "pages_deployments_registry_count": 0, "pages_deployments_verification_total_count": 0, "pages_deployments_verified_count": 0, "pages_deployments_verification_failed_count": 0, "pipeline_artifacts_count": 0, "pipeline_artifacts_checksum_total_count": null, "pipeline_artifacts_checksummed_count": null, "pipeline_artifacts_checksum_failed_count": null, "pipeline_artifacts_synced_count": 0, "pipeline_artifacts_failed_count": 0, "pipeline_artifacts_registry_count": 0, "pipeline_artifacts_verification_total_count": 0, "pipeline_artifacts_verified_count": 0, "pipeline_artifacts_verification_failed_count": 0, "project_repositories_count": 19, "project_repositories_checksum_total_count": null, "project_repositories_checksummed_count": null, "project_repositories_checksum_failed_count": null, "project_repositories_synced_count": 19, "project_repositories_failed_count": 0, "project_repositories_registry_count": 19, "project_repositories_verification_total_count": 19, "project_repositories_verified_count": 19, "project_repositories_verification_failed_count": 0, "project_wiki_repositories_count": 19, "project_wiki_repositories_checksum_total_count": null, "project_wiki_repositories_checksummed_count": null, "project_wiki_repositories_checksum_failed_count": null, "project_wiki_repositories_synced_count": 19, "project_wiki_repositories_failed_count": 0, "project_wiki_repositories_registry_count": 19, "project_wiki_repositories_verification_total_count": 19, "project_wiki_repositories_verified_count": 19, "project_wiki_repositories_verification_failed_count": 0, "snippet_repositories_count": 20, "snippet_repositories_checksum_total_count": null, "snippet_repositories_checksummed_count": null, "snippet_repositories_checksum_failed_count": null, "snippet_repositories_synced_count": 20, "snippet_repositories_failed_count": 0, "snippet_repositories_registry_count": 20, "snippet_repositories_verification_total_count": 20, "snippet_repositories_verified_count": 20, "snippet_repositories_verification_failed_count": 0, "terraform_state_versions_count": 18, "terraform_state_versions_checksum_total_count": null, "terraform_state_versions_checksummed_count": null, "terraform_state_versions_checksum_failed_count": null, "terraform_state_versions_synced_count": 18, "terraform_state_versions_failed_count": 0, "terraform_state_versions_registry_count": 18, "terraform_state_versions_verification_total_count": 18, "terraform_state_versions_verified_count": 18, "terraform_state_versions_verification_failed_count": 0, "uploads_count": 55, "uploads_checksum_total_count": null, "uploads_checksummed_count": null, "uploads_checksum_failed_count": null, "uploads_synced_count": 55, "uploads_failed_count": 0, "uploads_registry_count": 55, "uploads_verification_total_count": 55, "uploads_verified_count": 55, "uploads_verification_failed_count": 0, "abuse_report_uploads_count": 0, "abuse_report_uploads_checksum_total_count": 0, "abuse_report_uploads_checksummed_count": 0, "abuse_report_uploads_checksum_failed_count": 0, "abuse_report_uploads_synced_count": null, "abuse_report_uploads_failed_count": null, "abuse_report_uploads_registry_count": null, "abuse_report_uploads_verification_total_count": null, "abuse_report_uploads_verified_count": null, "abuse_report_uploads_verification_failed_count": null, "abuse_report_uploads_synced_in_percentage": "0.00%", "abuse_report_uploads_verified_in_percentage": "0.00%", "project_uploads_count": 0, "project_uploads_checksum_total_count": 0, "project_uploads_checksummed_count": 0, "project_uploads_checksum_failed_count": 0, "project_uploads_synced_count": null, "project_uploads_failed_count": null, "project_uploads_registry_count": null, "project_uploads_verification_total_count": null, "project_uploads_verified_count": null, "project_uploads_verification_failed_count": null, "project_uploads_synced_in_percentage": "0.00%", "project_uploads_verified_in_percentage": "0.00%", "group_uploads_count": 0, "group_uploads_checksum_total_count": 0, "group_uploads_checksummed_count": 0, "group_uploads_checksum_failed_count": 0, "group_uploads_synced_count": null, "group_uploads_failed_count": null, "group_uploads_registry_count": null, "group_uploads_verification_total_count": null, "group_uploads_verified_count": null, "group_uploads_verification_failed_count": null, "group_uploads_synced_in_percentage": "0.00%", "group_uploads_verified_in_percentage": "0.00%", "user_uploads_count": 0, "user_uploads_checksum_total_count": 0, "user_uploads_checksummed_count": 0, "user_uploads_checksum_failed_count": 0, "user_uploads_synced_count": null, "user_uploads_failed_count": null, "user_uploads_registry_count": null, "user_uploads_verification_total_count": null, "user_uploads_verified_count": null, "user_uploads_verification_failed_count": null, "user_uploads_synced_in_percentage": "0.00%", "user_uploads_verified_in_percentage": "0.00%", "design_management_action_uploads_count": 0, "design_management_action_uploads_checksum_total_count": 0, "design_management_action_uploads_checksummed_count": 0, "design_management_action_uploads_checksum_failed_count": 0, "design_management_action_uploads_synced_count": null, "design_management_action_uploads_failed_count": null, "design_management_action_uploads_registry_count": null, "design_management_action_uploads_verification_total_count": null, "design_management_action_uploads_verified_count": null, "design_management_action_uploads_verification_failed_count": null, "design_management_action_uploads_synced_in_percentage": "0.00%", "design_management_action_uploads_verified_in_percentage": "0.00%", "achievement_uploads_count": 0, "achievement_uploads_checksum_total_count": 0, "achievement_uploads_checksummed_count": 0, "achievement_uploads_checksum_failed_count": 0, "achievement_uploads_synced_count": null, "achievement_uploads_failed_count": null, "achievement_uploads_registry_count": null, "achievement_uploads_verification_total_count": null, "achievement_uploads_verified_count": null, "achievement_uploads_verification_failed_count": null, "achievement_uploads_synced_in_percentage": "0.00%", "achievement_uploads_verified_in_percentage": "0.00%", "git_fetch_event_count_weekly": 0, "git_push_event_count_weekly": 0, "proxy_remote_requests_event_count_weekly": 0, "proxy_local_requests_event_count_weekly": 0, "repositories_checked_in_percentage": "0.00%", "replication_slots_used_in_percentage": "0.00%", "ci_secure_files_synced_in_percentage": "0.00%", "ci_secure_files_verified_in_percentage": "0.00%", "container_repositories_synced_in_percentage": "0.00%", "container_repositories_verified_in_percentage": "0.00%", "dependency_proxy_blobs_synced_in_percentage": "0.00%", "dependency_proxy_blobs_verified_in_percentage": "0.00%", "dependency_proxy_manifests_synced_in_percentage": "0.00%", "dependency_proxy_manifests_verified_in_percentage": "0.00%", "design_management_repositories_synced_in_percentage": "0.00%", "design_management_repositories_verified_in_percentage": "0.00%", "group_wiki_repositories_synced_in_percentage": "0.00%", "group_wiki_repositories_verified_in_percentage": "0.00%", "job_artifacts_synced_in_percentage": "100.00%", "job_artifacts_verified_in_percentage": "100.00%", "lfs_objects_synced_in_percentage": "100.00%", "lfs_objects_verified_in_percentage": "100.00%", "merge_request_diffs_synced_in_percentage": "0.00%", "merge_request_diffs_verified_in_percentage": "0.00%", "package_files_synced_in_percentage": "100.00%", "package_files_verified_in_percentage": "100.00%", "pages_deployments_synced_in_percentage": "0.00%", "pages_deployments_verified_in_percentage": "0.00%", "pipeline_artifacts_synced_in_percentage": "0.00%", "pipeline_artifacts_verified_in_percentage": "0.00%", "project_repositories_synced_in_percentage": "100.00%", "project_repositories_verified_in_percentage": "100.00%", "project_wiki_repositories_synced_in_percentage": "100.00%", "project_wiki_repositories_verified_in_percentage": "100.00%", "snippet_repositories_synced_in_percentage": "100.00%", "snippet_repositories_verified_in_percentage": "100.00%", "terraform_state_versions_synced_in_percentage": "100.00%", "terraform_state_versions_verified_in_percentage": "100.00%", "uploads_synced_in_percentage": "100.00%", "uploads_verified_in_percentage": "100.00%", "repositories_count": 19, "replication_slots_count": null, "replication_slots_used_count": null, "healthy": true, "health": "Healthy", "health_status": "Healthy", "missing_oauth_application": false, "db_replication_lag_seconds": 0, "replication_slots_max_retained_wal_bytes": null, "repositories_checked_count": null, "repositories_checked_failed_count": null, "last_event_id": 534, "last_event_timestamp": 1746370442, "cursor_last_event_id": 534, "cursor_last_event_timestamp": 1746370442, "last_successful_status_check_timestamp": 1746469624, "version": "18.0.0-pre", "revision": "60237485299", "selective_sync_type": null, "namespaces": [], "updated_at": "2025-05-05T18:26:05.000Z", "storage_shards_match": true, "_links": { "self": "https://primary.example.com/api/v4/geo_sites/2/status", "site": "https://primary.example.com/api/v4/geo_sites/2" } } The `health_status` parameter can only be in a “Healthy” or “Unhealthy” state, while the `health` parameter can be empty, “Healthy”, or contain the actual error message. --- # Geo Nodes API (deprecated) | GitLab Docs * * * Geo Nodes API (deprecated) ========================== * Tier: Premium, Ultimate * Offering: GitLab Self-Managed The Geo Nodes API was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/369140) in GitLab 16.0 and is planned for removal in v5 of the API. Use the [Geo Sites API](https://docs.gitlab.com/api/geo_sites/) instead. This change is a breaking change. Use this API to manage [Geo nodes](https://docs.gitlab.com/administration/geo/) . Prerequisites: * You must be an administrator. Create a Geo node ----------------- Creates a Geo node. POST /geo_nodes curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_nodes" \ -d "name=himynameissomething" \ -d "url=https://another-node.example.com/" | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `primary` | boolean | no | Specifying whether this node should be primary. Defaults to false. | | `enabled` | boolean | no | Flag indicating if the Geo node is enabled. Defaults to true. | | `name` | string | yes | The unique identifier for the Geo node. Must match `geo_node_name` if it is set in `gitlab.rb`, otherwise it must match `external_url` | | `url` | string | yes | The user-facing URL for the Geo node. | | `internal_url` | string | no | The URL defined on the primary node that secondary nodes should use to contact it. Returns `url` if not set. | | `files_max_capacity` | integer | no | Control the maximum concurrency of LFS/attachment backfill for this secondary node. Defaults to 10. | | `repos_max_capacity` | integer | no | Control the maximum concurrency of repository backfill for this secondary node. Defaults to 25. | | `verification_max_capacity` | integer | no | Control the maximum concurrency of repository verification for this node. Defaults to 100. | | `container_repositories_max_capacity` | integer | no | Control the maximum concurrency of container repository sync for this node. Defaults to 10. | | `sync_object_storage` | boolean | no | Flag indicating if the secondary Geo node should replicate blobs in Object Storage. Defaults to false. | | `selective_sync_type` | string | no | Limit syncing to only specific groups or shards. Valid values: `"namespaces"`, `"shards"`, or `null`. | | `selective_sync_shards` | array | no | The repository storage for the projects synced if `selective_sync_type` == `shards`. | | `selective_sync_namespace_ids` | array | no | The IDs of groups that should be synced, if `selective_sync_type` == `namespaces`. | | `minimum_reverification_interval` | integer | no | The interval (in days) in which the repository verification is valid. Once expired, it is reverified. This has no effect when set on a secondary node. | | `blob_download_timeout` | integer | no | The timeout (in seconds) for blob replication. Defaults to 28800. Maximum is 86400. | Example response: { "id": 3, "name": "Test Node 1", "url": "https://secondary.example.com/", "internal_url": "https://secondary.example.com/", "primary": false, "enabled": true, "current": false, "files_max_capacity": 10, "repos_max_capacity": 25, "verification_max_capacity": 100, "selective_sync_type": "namespaces", "selective_sync_shards": [], "selective_sync_namespace_ids": [1, 25], "minimum_reverification_interval": 7, "container_repositories_max_capacity": 10, "sync_object_storage": false, "blob_download_timeout": 28800, "clone_protocol": "http", "web_edit_url": "https://primary.example.com/admin/geo/sites/3/edit", "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/3/replication/lfs_objects", "_links": { "self": "https://primary.example.com/api/v4/geo_nodes/3", "status": "https://primary.example.com/api/v4/geo_nodes/3/status", "repair": "https://primary.example.com/api/v4/geo_nodes/3/repair" } } List all Geo nodes ------------------ Lists all Geo nodes. GET /geo_nodes curl \ --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_nodes" Example response: [\ {\ "id": 1,\ "name": "us-node",\ "url": "https://primary.example.com/",\ "internal_url": "https://internal.example.com/",\ "primary": true,\ "enabled": true,\ "current": true,\ "files_max_capacity": 10,\ "repos_max_capacity": 25,\ "container_repositories_max_capacity": 10,\ "verification_max_capacity": 100,\ "selective_sync_type": "namespaces",\ "selective_sync_shards": [],\ "selective_sync_namespace_ids": [1, 25],\ "minimum_reverification_interval": 7,\ "blob_download_timeout": 28800,\ "clone_protocol": "http",\ "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit",\ "_links": {\ "self": "https://primary.example.com/api/v4/geo_nodes/1",\ "status":"https://primary.example.com/api/v4/geo_nodes/1/status",\ "repair":"https://primary.example.com/api/v4/geo_nodes/1/repair"\ }\ },\ {\ "id": 2,\ "name": "cn-node",\ "url": "https://secondary.example.com/",\ "internal_url": "https://secondary.example.com/",\ "primary": false,\ "enabled": true,\ "current": false,\ "files_max_capacity": 10,\ "repos_max_capacity": 25,\ "container_repositories_max_capacity": 10,\ "verification_max_capacity": 100,\ "selective_sync_type": "namespaces",\ "selective_sync_shards": [],\ "selective_sync_namespace_ids": [1, 25],\ "minimum_reverification_interval": 7,\ "sync_object_storage": true,\ "blob_download_timeout": 28800,\ "clone_protocol": "http",\ "web_edit_url": "https://primary.example.com/admin/geo/sites/2/edit",\ "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/2/replication/lfs_objects",\ "_links": {\ "self":"https://primary.example.com/api/v4/geo_nodes/2",\ "status":"https://primary.example.com/api/v4/geo_nodes/2/status",\ "repair":"https://primary.example.com/api/v4/geo_nodes/2/repair"\ }\ }\ ] Retrieve a Geo node ------------------- Retrieves a specified Geo node. curl \ --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_nodes/1" Example response: { "id": 1, "name": "us-node", "url": "https://primary.example.com/", "internal_url": "https://primary.example.com/", "primary": true, "enabled": true, "current": true, "files_max_capacity": 10, "repos_max_capacity": 25, "container_repositories_max_capacity": 10, "verification_max_capacity": 100, "selective_sync_type": "namespaces", "selective_sync_shards": [], "selective_sync_namespace_ids": [1, 25], "minimum_reverification_interval": 7, "blob_download_timeout": 28800, "clone_protocol": "http", "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit", "_links": { "self": "https://primary.example.com/api/v4/geo_nodes/1", "status":"https://primary.example.com/api/v4/geo_nodes/1/status", "repair":"https://primary.example.com/api/v4/geo_nodes/1/repair" } } Update a Geo node ----------------- Updates a specified Geo node. PUT /geo_nodes/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID of the Geo node. | | `enabled` | boolean | no | Flag indicating if the Geo node is enabled. | | `name` | string | no | The unique identifier for the Geo node. Must match `geo_node_name` if it is set in `gitlab.rb`, otherwise it must match `external_url`. | | `url` | string | no | The user-facing URL of the Geo node. | | `internal_url` | string | no | The URL defined on the primary node that secondary nodes should use to contact it. Returns `url` if not set. | | `files_max_capacity` | integer | no | Control the maximum concurrency of LFS/attachment backfill for this secondary node. | | `repos_max_capacity` | integer | no | Control the maximum concurrency of repository backfill for this secondary node. | | `verification_max_capacity` | integer | no | Control the maximum concurrency of verification for this node. | | `container_repositories_max_capacity` | integer | no | Control the maximum concurrency of container repository sync for this node. | | `sync_object_storage` | boolean | no | Flag indicating if the secondary Geo node should replicate blobs in Object Storage. | | `selective_sync_type` | string | no | Limit syncing to only specific groups or shards. Valid values: `"namespaces"`, `"shards"`, or `null`. | | `selective_sync_shards` | array | no | The repository storage for the projects synced if `selective_sync_type` == `shards`. | | `selective_sync_namespace_ids` | array | no | The IDs of groups that should be synced, if `selective_sync_type` == `namespaces`. | | `minimum_reverification_interval` | integer | no | The interval (in days) in which the repository verification is valid. Once expired, it is reverified. This has no effect when set on a secondary node. | | `blob_download_timeout` | integer | no | The timeout (in seconds) for blob replication. Defaults to 28800. Maximum is 86400. | Example response: { "id": 1, "name": "cn-node", "url": "https://secondary.example.com/", "internal_url": "https://secondary.example.com/", "primary": false, "enabled": true, "current": true, "files_max_capacity": 10, "repos_max_capacity": 25, "container_repositories_max_capacity": 10, "verification_max_capacity": 100, "selective_sync_type": "namespaces", "selective_sync_shards": [], "selective_sync_namespace_ids": [1, 25], "minimum_reverification_interval": 7, "sync_object_storage": true, "blob_download_timeout": 28800, "clone_protocol": "http", "web_edit_url": "https://primary.example.com/admin/geo/sites/2/edit", "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/2/replication/lfs_objects", "_links": { "self":"https://primary.example.com/api/v4/geo_nodes/2", "status":"https://primary.example.com/api/v4/geo_nodes/2/status", "repair":"https://primary.example.com/api/v4/geo_nodes/2/repair" } } Delete a Geo node ----------------- Deletes a Geo node. DELETE /geo_nodes/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID of the Geo node. | Repair a Geo node ----------------- To repair the OAuth authentication of a Geo node. _This can only be run against a primary Geo node._ POST /geo_nodes/:id/repair Example response: { "id": 1, "name": "us-node", "url": "https://primary.example.com/", "internal_url": "https://primary.example.com/", "primary": true, "enabled": true, "current": true, "files_max_capacity": 10, "repos_max_capacity": 25, "container_repositories_max_capacity": 10, "verification_max_capacity": 100, "blob_download_timeout": 28800, "clone_protocol": "http", "web_edit_url": "https://primary.example.com/admin/geo/sites/1/edit", "_links": { "self": "https://primary.example.com/api/v4/geo_nodes/1", "status":"https://primary.example.com/api/v4/geo_nodes/1/status", "repair":"https://primary.example.com/api/v4/geo_nodes/1/repair" } } List all Geo node statuses -------------------------- Lists all Geo node statuses. GET /geo_nodes/status curl \ --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_nodes/status" Example response: [\ {\ "geo_node_id": 1,\ "healthy": true,\ "health": "Healthy",\ "health_status": "Healthy",\ "missing_oauth_application": false,\ "db_replication_lag_seconds": null,\ "lfs_objects_count": 5,\ "lfs_objects_checksum_total_count": 5,\ "lfs_objects_checksummed_count": 5,\ "lfs_objects_checksum_failed_count": 0,\ "lfs_objects_synced_count": null,\ "lfs_objects_failed_count": null,\ "lfs_objects_registry_count": null,\ "lfs_objects_verification_total_count": null,\ "lfs_objects_verified_count": null,\ "lfs_objects_verification_failed_count": null,\ "lfs_objects_synced_in_percentage": "0.00%",\ "lfs_objects_verified_in_percentage": "0.00%",\ "job_artifacts_count": 2,\ "job_artifacts_synced_count": null,\ "job_artifacts_failed_count": null,\ "job_artifacts_synced_in_percentage": "0.00%",\ "projects_count": 41,\ "repositories_count": 41,\ "replication_slots_count": 1,\ "replication_slots_used_count": 1,\ "replication_slots_used_in_percentage": "100.00%",\ "replication_slots_max_retained_wal_bytes": 0,\ "repositories_checked_count": 20,\ "repositories_checked_failed_count": 20,\ "repositories_checked_in_percentage": "100.00%",\ "achievement_uploads_count": 0,\ "achievement_uploads_checksum_total_count": 0,\ "achievement_uploads_checksummed_count": 0,\ "achievement_uploads_checksum_failed_count": 0,\ "achievement_uploads_synced_count": null,\ "achievement_uploads_failed_count": null,\ "achievement_uploads_registry_count": null,\ "achievement_uploads_verification_total_count": null,\ "achievement_uploads_verified_count": null,\ "achievement_uploads_verification_failed_count": null,\ "achievement_uploads_synced_in_percentage": "0.00%",\ "achievement_uploads_verified_in_percentage": "0.00%",\ "git_fetch_event_count_weekly": 0,\ "git_push_event_count_weekly": 0,\ "proxy_remote_requests_event_count_weekly": 0,\ "proxy_local_requests_event_count_weekly": 0,\ "last_event_id": 23,\ "last_event_timestamp": 1509681166,\ "cursor_last_event_id": null,\ "cursor_last_event_timestamp": 0,\ "last_successful_status_check_timestamp": 1510125024,\ "version": "10.3.0",\ "revision": "33d33a096a",\ "merge_request_diffs_count": 5,\ "merge_request_diffs_checksum_total_count": 5,\ "merge_request_diffs_checksummed_count": 5,\ "merge_request_diffs_checksum_failed_count": 0,\ "merge_request_diffs_synced_count": null,\ "merge_request_diffs_failed_count": null,\ "merge_request_diffs_registry_count": null,\ "merge_request_diffs_verification_total_count": null,\ "merge_request_diffs_verified_count": null,\ "merge_request_diffs_verification_failed_count": null,\ "merge_request_diffs_synced_in_percentage": "0.00%",\ "merge_request_diffs_verified_in_percentage": "0.00%",\ "package_files_count": 5,\ "package_files_checksum_total_count": 5,\ "package_files_checksummed_count": 5,\ "package_files_checksum_failed_count": 0,\ "package_files_synced_count": null,\ "package_files_failed_count": null,\ "package_files_registry_count": null,\ "package_files_verification_total_count": null,\ "package_files_verified_count": null,\ "package_files_verification_failed_count": null,\ "package_files_synced_in_percentage": "0.00%",\ "package_files_verified_in_percentage": "0.00%",\ "pages_deployments_count": 5,\ "pages_deployments_checksum_total_count": 5,\ "pages_deployments_checksummed_count": 5,\ "pages_deployments_checksum_failed_count": 0,\ "pages_deployments_synced_count": null,\ "pages_deployments_failed_count": null,\ "pages_deployments_registry_count": null,\ "pages_deployments_verification_total_count": null,\ "pages_deployments_verified_count": null,\ "pages_deployments_verification_failed_count": null,\ "pages_deployments_synced_in_percentage": "0.00%",\ "pages_deployments_verified_in_percentage": "0.00%",\ "terraform_state_versions_count": 5,\ "terraform_state_versions_checksum_total_count": 5,\ "terraform_state_versions_checksummed_count": 5,\ "terraform_state_versions_checksum_failed_count": 0,\ "terraform_state_versions_synced_count": null,\ "terraform_state_versions_failed_count": null,\ "terraform_state_versions_registry_count": null,\ "terraform_state_versions_verification_total_count": null,\ "terraform_state_versions_verified_count": null,\ "terraform_state_versions_verification_failed_count": null,\ "terraform_state_versions_synced_in_percentage": "0.00%",\ "terraform_state_versions_verified_in_percentage": "0.00%",\ "snippet_repositories_count": 5,\ "snippet_repositories_checksum_total_count": 5,\ "snippet_repositories_checksummed_count": 5,\ "snippet_repositories_checksum_failed_count": 0,\ "snippet_repositories_synced_count": null,\ "snippet_repositories_failed_count": null,\ "snippet_repositories_registry_count": null,\ "snippet_repositories_verification_total_count": null,\ "snippet_repositories_verified_count": null,\ "snippet_repositories_verification_failed_count": null,\ "snippet_repositories_synced_in_percentage": "0.00%",\ "snippet_repositories_verified_in_percentage": "0.00%",\ "project_wiki_repositories_count": 3,\ "project_wiki_repositories_checksum_total_count": 3,\ "project_wiki_repositories_checksummed_count": 3,\ "project_wiki_repositories_checksum_failed_count": 0,\ "project_wiki_repositories_synced_count": null,\ "project_wiki_repositories_failed_count": null,\ "project_wiki_repositories_registry_count": null,\ "project_wiki_repositories_verification_total_count": null,\ "project_wiki_repositories_verified_count": null,\ "project_wiki_repositories_verification_failed_count": null,\ "project_wiki_repositories_synced_in_percentage": "0.00%",\ "project_wiki_repositories_verified_in_percentage": "0.00%",\ "group_wiki_repositories_count": 5,\ "group_wiki_repositories_checksum_total_count": 5,\ "group_wiki_repositories_checksummed_count": 5,\ "group_wiki_repositories_checksum_failed_count": 0,\ "group_wiki_repositories_synced_count": null,\ "group_wiki_repositories_failed_count": null,\ "group_wiki_repositories_registry_count": null,\ "group_wiki_repositories_verification_total_count": null,\ "group_wiki_repositories_verified_count": null,\ "group_wiki_repositories_verification_failed_count": null,\ "group_wiki_repositories_synced_in_percentage": "0.00%",\ "group_wiki_repositories_verified_in_percentage": "0.00%",\ "pipeline_artifacts_count": 5,\ "pipeline_artifacts_checksum_total_count": 5,\ "pipeline_artifacts_checksummed_count": 5,\ "pipeline_artifacts_checksum_failed_count": 0,\ "pipeline_artifacts_synced_count": null,\ "pipeline_artifacts_failed_count": null,\ "pipeline_artifacts_registry_count": null,\ "pipeline_artifacts_verification_total_count": null,\ "pipeline_artifacts_verified_count": null,\ "pipeline_artifacts_verification_failed_count": null,\ "pipeline_artifacts_synced_in_percentage": "0.00%",\ "pipeline_artifacts_verified_in_percentage": "0.00%",\ "uploads_count": 5,\ "uploads_synced_count": null,\ "uploads_failed_count": 0,\ "uploads_registry_count": null,\ "uploads_synced_in_percentage": "0.00%",\ "uploads_checksum_total_count": 5,\ "uploads_checksummed_count": 5,\ "uploads_checksum_failed_count": null,\ "uploads_verification_total_count": null,\ "uploads_verified_count": null,\ "uploads_verification_failed_count": null,\ "uploads_verified_in_percentage": "0.00%",\ "job_artifacts_count": 5,\ "job_artifacts_checksum_total_count": 5,\ "job_artifacts_checksummed_count": 5,\ "job_artifacts_checksum_failed_count": 0,\ "job_artifacts_synced_count": 5,\ "job_artifacts_failed_count": 0,\ "job_artifacts_registry_count": 5,\ "job_artifacts_verification_total_count": 5,\ "job_artifacts_verified_count": 5,\ "job_artifacts_verification_failed_count": 0,\ "job_artifacts_synced_in_percentage": "100.00%",\ "job_artifacts_verified_in_percentage": "100.00%",\ "ci_secure_files_count": 5,\ "ci_secure_files_checksum_total_count": 5,\ "ci_secure_files_checksummed_count": 5,\ "ci_secure_files_checksum_failed_count": 0,\ "ci_secure_files_synced_count": 5,\ "ci_secure_files_failed_count": 0,\ "ci_secure_files_registry_count": 5,\ "ci_secure_files_verification_total_count": 5,\ "ci_secure_files_verified_count": 5,\ "ci_secure_files_verification_failed_count": 0,\ "ci_secure_files_synced_in_percentage": "100.00%",\ "ci_secure_files_verified_in_percentage": "100.00%",\ "dependency_proxy_blobs_count": 5,\ "dependency_proxy_blobs_checksum_total_count": 5,\ "dependency_proxy_blobs_checksummed_count": 5,\ "dependency_proxy_blobs_checksum_failed_count": 0,\ "dependency_proxy_blobs_synced_count": 5,\ "dependency_proxy_blobs_failed_count": 0,\ "dependency_proxy_blobs_registry_count": 5,\ "dependency_proxy_blobs_verification_total_count": 5,\ "dependency_proxy_blobs_verified_count": 5,\ "dependency_proxy_blobs_verification_failed_count": 0,\ "dependency_proxy_blobs_synced_in_percentage": "100.00%",\ "dependency_proxy_blobs_verified_in_percentage": "100.00%",\ "container_repositories_count": 5,\ "container_repositories_synced_count": 5,\ "container_repositories_failed_count": 0,\ "container_repositories_registry_count": 5,\ "container_repositories_synced_in_percentage": "100.00%",\ "container_repositories_checksum_total_count": 0,\ "container_repositories_checksummed_count": 0,\ "container_repositories_checksum_failed_count": 0,\ "container_repositories_verification_total_count": 0,\ "container_repositories_verified_count": 0,\ "container_repositories_verification_failed_count": 0,\ "container_repositories_verified_in_percentage": "100.00%",\ "dependency_proxy_manifests_count": 5,\ "dependency_proxy_manifests_checksum_total_count": 5,\ "dependency_proxy_manifests_checksummed_count": 5,\ "dependency_proxy_manifests_checksum_failed_count": 5,\ "dependency_proxy_manifests_synced_count": 5,\ "dependency_proxy_manifests_failed_count": 0,\ "dependency_proxy_manifests_registry_count": 5,\ "dependency_proxy_manifests_verification_total_count": 5,\ "dependency_proxy_manifests_verified_count": 5,\ "dependency_proxy_manifests_verification_failed_count": 5,\ "dependency_proxy_manifests_synced_in_percentage": "100.00%",\ "dependency_proxy_manifests_verified_in_percentage": "100.00%",\ "design_management_repositories_count": 5,\ "design_management_repositories_checksum_total_count": 5,\ "design_management_repositories_checksummed_count": 5,\ "design_management_repositories_checksum_failed_count": 5,\ "design_management_repositories_synced_count": 5,\ "design_management_repositories_failed_count": 0,\ "design_management_repositories_registry_count": 5,\ "design_management_repositories_verification_total_count": 5,\ "design_management_repositories_verified_count": 5,\ "design_management_repositories_verification_failed_count": 5,\ "design_management_repositories_synced_in_percentage": "100.00%",\ "design_management_repositories_verified_in_percentage": "100.00%",\ "project_repositories_count": 5,\ "project_repositories_checksum_total_count": 5,\ "project_repositories_checksummed_count": 5,\ "project_repositories_checksum_failed_count": 0,\ "project_repositories_synced_count": 5,\ "project_repositories_failed_count": 0,\ "project_repositories_registry_count": 5,\ "project_repositories_verification_total_count": 5,\ "project_repositories_verified_count": 5,\ "project_repositories_verification_failed_count": 0,\ "project_repositories_synced_in_percentage": "100.00%",\ "project_repositories_verified_in_percentage": "100.00%",\ "container_repositories_replication_enabled": null,\ "abuse_report_uploads_count": 0,\ "abuse_report_uploads_checksum_total_count": 0,\ "abuse_report_uploads_checksummed_count": 0,\ "abuse_report_uploads_checksum_failed_count": 0,\ "abuse_report_uploads_synced_count": null,\ "abuse_report_uploads_failed_count": null,\ "abuse_report_uploads_registry_count": null,\ "abuse_report_uploads_verification_total_count": null,\ "abuse_report_uploads_verified_count": null,\ "abuse_report_uploads_verification_failed_count": null,\ "abuse_report_uploads_synced_in_percentage": "0.00%",\ "abuse_report_uploads_verified_in_percentage": "0.00%",\ "project_uploads_count": 0,\ "project_uploads_checksum_total_count": 0,\ "project_uploads_checksummed_count": 0,\ "project_uploads_checksum_failed_count": 0,\ "project_uploads_synced_count": null,\ "project_uploads_failed_count": null,\ "project_uploads_registry_count": null,\ "project_uploads_verification_total_count": null,\ "project_uploads_verified_count": null,\ "project_uploads_verification_failed_count": null,\ "project_uploads_synced_in_percentage": "0.00%",\ "project_uploads_verified_in_percentage": "0.00%",\ "group_uploads_count": 0,\ "group_uploads_checksum_total_count": 0,\ "group_uploads_checksummed_count": 0,\ "group_uploads_checksum_failed_count": 0,\ "group_uploads_synced_count": null,\ "group_uploads_failed_count": null,\ "group_uploads_registry_count": null,\ "group_uploads_verification_total_count": null,\ "group_uploads_verified_count": null,\ "group_uploads_verification_failed_count": null,\ "group_uploads_synced_in_percentage": "0.00%",\ "group_uploads_verified_in_percentage": "0.00%",\ "user_uploads_count": 0,\ "user_uploads_checksum_total_count": 0,\ "user_uploads_checksummed_count": 0,\ "user_uploads_checksum_failed_count": 0,\ "user_uploads_synced_count": null,\ "user_uploads_failed_count": null,\ "user_uploads_registry_count": null,\ "user_uploads_verification_total_count": null,\ "user_uploads_verified_count": null,\ "user_uploads_verification_failed_count": null,\ "user_uploads_synced_in_percentage": "0.00%",\ "user_uploads_verified_in_percentage": "0.00%",\ "design_management_action_uploads_count": 0,\ "design_management_action_uploads_checksum_total_count": 0,\ "design_management_action_uploads_checksummed_count": 0,\ "design_management_action_uploads_checksum_failed_count": 0,\ "design_management_action_uploads_synced_count": null,\ "design_management_action_uploads_failed_count": null,\ "design_management_action_uploads_registry_count": null,\ "design_management_action_uploads_verification_total_count": null,\ "design_management_action_uploads_verified_count": null,\ "design_management_action_uploads_verification_failed_count": null,\ "design_management_action_uploads_synced_in_percentage": "0.00%",\ "design_management_action_uploads_verified_in_percentage": "0.00%",\ "selective_sync_type": null,\ "namespaces": [],\ "updated_at": "2024-04-01T00:00:00.000Z",\ "storage_shards_match": true,\ "_links": {\ "self": "https://primary.example.com/api/v4/geo_nodes/1/status",\ "node": "https://primary.example.com/api/v4/geo_nodes/1"\ }\ },\ {\ "geo_node_id": 2,\ "healthy": true,\ "health": "Healthy",\ "health_status": "Healthy",\ "missing_oauth_application": false,\ "db_replication_lag_seconds": 0,\ "lfs_objects_count": 5,\ "lfs_objects_checksum_total_count": 5,\ "lfs_objects_checksummed_count": 5,\ "lfs_objects_checksum_failed_count": 0,\ "lfs_objects_synced_count": null,\ "lfs_objects_failed_count": null,\ "lfs_objects_registry_count": null,\ "lfs_objects_verification_total_count": null,\ "lfs_objects_verified_count": null,\ "lfs_objects_verification_failed_count": null,\ "lfs_objects_synced_in_percentage": "0.00%",\ "lfs_objects_verified_in_percentage": "0.00%",\ "job_artifacts_count": 2,\ "job_artifacts_synced_count": 1,\ "job_artifacts_failed_count": 1,\ "job_artifacts_synced_in_percentage": "50.00%",\ "design_management_repositories_count": 5,\ "design_management_repositories_synced_count": 5,\ "design_management_repositories_failed_count": 5,\ "design_management_repositories_synced_in_percentage": "100.00%",\ "design_management_repositories_checksum_total_count": 5,\ "design_management_repositories_checksummed_count": 5,\ "design_management_repositories_checksum_failed_count": 5,\ "design_management_repositories_registry_count": 5,\ "design_management_repositories_verification_total_count": 5,\ "design_management_repositories_verified_count": 5,\ "design_management_repositories_verification_failed_count": 5,\ "design_management_repositories_verified_in_percentage": "100.00%",\ "projects_count": 41,\ "repositories_count": 41,\ "replication_slots_count": null,\ "replication_slots_used_count": null,\ "replication_slots_used_in_percentage": "0.00%",\ "replication_slots_max_retained_wal_bytes": null,\ "achievement_uploads_count": 0,\ "achievement_uploads_checksum_total_count": 0,\ "achievement_uploads_checksummed_count": 0,\ "achievement_uploads_checksum_failed_count": 0,\ "achievement_uploads_synced_count": null,\ "achievement_uploads_failed_count": null,\ "achievement_uploads_registry_count": null,\ "achievement_uploads_verification_total_count": null,\ "achievement_uploads_verified_count": null,\ "achievement_uploads_verification_failed_count": null,\ "achievement_uploads_synced_in_percentage": "0.00%",\ "achievement_uploads_verified_in_percentage": "0.00%",\ "git_fetch_event_count_weekly": 0,\ "git_push_event_count_weekly": 0,\ "proxy_remote_requests_event_count_weekly": 0,\ "proxy_local_requests_event_count_weekly": 0,\ "repositories_checked_count": 5,\ "repositories_checked_failed_count": 1,\ "repositories_checked_in_percentage": "12.20%",\ "last_event_id": 23,\ "last_event_timestamp": 1509681166,\ "cursor_last_event_id": 23,\ "cursor_last_event_timestamp": 1509681166,\ "last_successful_status_check_timestamp": 1510125024,\ "version": "10.3.0",\ "revision": "33d33a096a",\ "merge_request_diffs_count": 5,\ "merge_request_diffs_checksum_total_count": 5,\ "merge_request_diffs_checksummed_count": 5,\ "merge_request_diffs_checksum_failed_count": 0,\ "merge_request_diffs_synced_count": 5,\ "merge_request_diffs_failed_count": 0,\ "merge_request_diffs_registry_count": 5,\ "merge_request_diffs_verification_total_count": 5,\ "merge_request_diffs_verified_count": 5,\ "merge_request_diffs_verification_failed_count": 0,\ "merge_request_diffs_synced_in_percentage": "100.00%",\ "merge_request_diffs_verified_in_percentage": "100.00%",\ "package_files_count": 5,\ "package_files_checksum_total_count": 5,\ "package_files_checksummed_count": 5,\ "package_files_checksum_failed_count": 0,\ "package_files_synced_count": 5,\ "package_files_failed_count": 0,\ "package_files_registry_count": 5,\ "package_files_verification_total_count": 5,\ "package_files_verified_count": 5,\ "package_files_verification_failed_count": 0,\ "package_files_synced_in_percentage": "100.00%",\ "package_files_verified_in_percentage": "100.00%",\ "packages_nuget_symbols_count": 5,\ "packages_nuget_symbols_checksum_total_count": 5,\ "packages_nuget_symbols_checksummed_count": 5,\ "packages_nuget_symbols_checksum_failed_count": 0,\ "packages_nuget_symbols_synced_count": 5,\ "packages_nuget_symbols_failed_count": 0,\ "packages_nuget_symbols_registry_count": 5,\ "packages_nuget_symbols_verification_total_count": 5,\ "packages_nuget_symbols_verified_count": 5,\ "packages_nuget_symbols_verification_failed_count": 0,\ "packages_nuget_symbols_synced_in_percentage": "100.00%",\ "packages_nuget_symbols_verified_in_percentage": "100.00%",\ "terraform_state_versions_count": 5,\ "terraform_state_versions_checksum_total_count": 5,\ "terraform_state_versions_checksummed_count": 5,\ "terraform_state_versions_checksum_failed_count": 0,\ "terraform_state_versions_synced_count": 5,\ "terraform_state_versions_failed_count": 0,\ "terraform_state_versions_registry_count": 5,\ "terraform_state_versions_verification_total_count": 5,\ "terraform_state_versions_verified_count": 5,\ "terraform_state_versions_verification_failed_count": 0,\ "terraform_state_versions_synced_in_percentage": "100.00%",\ "terraform_state_versions_verified_in_percentage": "100.00%",\ "snippet_repositories_count": 5,\ "snippet_repositories_checksum_total_count": 5,\ "snippet_repositories_checksummed_count": 5,\ "snippet_repositories_checksum_failed_count": 0,\ "snippet_repositories_synced_count": 5,\ "snippet_repositories_failed_count": 0,\ "snippet_repositories_registry_count": 5,\ "snippet_repositories_verification_total_count": 5,\ "snippet_repositories_verified_count": 5,\ "snippet_repositories_verification_failed_count": 0,\ "snippet_repositories_synced_in_percentage": "100.00%",\ "snippet_repositories_verified_in_percentage": "100.00%",\ "group_wiki_repositories_count": 5,\ "group_wiki_repositories_checksum_total_count": 5,\ "group_wiki_repositories_checksummed_count": 5,\ "group_wiki_repositories_checksum_failed_count": 0,\ "group_wiki_repositories_synced_count": 5,\ "group_wiki_repositories_failed_count": 0,\ "group_wiki_repositories_registry_count": 5,\ "group_wiki_repositories_verification_total_count": 5,\ "group_wiki_repositories_verified_count": 5,\ "group_wiki_repositories_verification_failed_count": 0,\ "group_wiki_repositories_synced_in_percentage": "100.00%",\ "group_wiki_repositories_verified_in_percentage": "100.00%",\ "pipeline_artifacts_count": 5,\ "pipeline_artifacts_checksum_total_count": 5,\ "pipeline_artifacts_checksummed_count": 5,\ "pipeline_artifacts_checksum_failed_count": 0,\ "pipeline_artifacts_synced_count": 5,\ "pipeline_artifacts_failed_count": 0,\ "pipeline_artifacts_registry_count": 5,\ "pipeline_artifacts_verification_total_count": 5,\ "pipeline_artifacts_verified_count": 5,\ "pipeline_artifacts_verification_failed_count": 0,\ "pipeline_artifacts_synced_in_percentage": "100.00%",\ "pipeline_artifacts_verified_in_percentage": "100.00%",\ "uploads_count": 5,\ "uploads_synced_count": null,\ "uploads_failed_count": 0,\ "uploads_registry_count": null,\ "uploads_synced_in_percentage": "0.00%",\ "uploads_checksum_total_count": 5,\ "uploads_checksummed_count": 5,\ "uploads_checksum_failed_count": null,\ "uploads_verification_total_count": null,\ "uploads_verified_count": null,\ "uploads_verification_failed_count": null,\ "uploads_verified_in_percentage": "0.00%",\ "job_artifacts_count": 5,\ "job_artifacts_checksum_total_count": 5,\ "job_artifacts_checksummed_count": 5,\ "job_artifacts_checksum_failed_count": 0,\ "job_artifacts_synced_count": 5,\ "job_artifacts_failed_count": 0,\ "job_artifacts_registry_count": 5,\ "job_artifacts_verification_total_count": 5,\ "job_artifacts_verified_count": 5,\ "job_artifacts_verification_failed_count": 0,\ "job_artifacts_synced_in_percentage": "100.00%",\ "job_artifacts_verified_in_percentage": "100.00%",\ "dependency_proxy_blobs_count": 5,\ "dependency_proxy_blobs_checksum_total_count": 5,\ "dependency_proxy_blobs_checksummed_count": 5,\ "dependency_proxy_blobs_checksum_failed_count": 0,\ "dependency_proxy_blobs_synced_count": 5,\ "dependency_proxy_blobs_failed_count": 0,\ "dependency_proxy_blobs_registry_count": 5,\ "dependency_proxy_blobs_verification_total_count": 5,\ "dependency_proxy_blobs_verified_count": 5,\ "dependency_proxy_blobs_verification_failed_count": 0,\ "dependency_proxy_blobs_synced_in_percentage": "100.00%",\ "dependency_proxy_blobs_verified_in_percentage": "100.00%",\ "container_repositories_count": 5,\ "container_repositories_synced_count": 5,\ "container_repositories_failed_count": 0,\ "container_repositories_registry_count": 5,\ "container_repositories_synced_in_percentage": "100.00%",\ "container_repositories_checksum_total_count": 0,\ "container_repositories_checksummed_count": 0,\ "container_repositories_checksum_failed_count": 0,\ "container_repositories_verification_total_count": 0,\ "container_repositories_verified_count": 0,\ "container_repositories_verification_failed_count": 0,\ "container_repositories_verified_in_percentage": "100.00%",\ "dependency_proxy_manifests_count": 5,\ "dependency_proxy_manifests_checksum_total_count": 5,\ "dependency_proxy_manifests_checksummed_count": 5,\ "dependency_proxy_manifests_checksum_failed_count": 5,\ "dependency_proxy_manifests_synced_count": 5,\ "dependency_proxy_manifests_failed_count": 0,\ "dependency_proxy_manifests_registry_count": 5,\ "dependency_proxy_manifests_verification_total_count": 5,\ "dependency_proxy_manifests_verified_count": 5,\ "dependency_proxy_manifests_verification_failed_count": 5,\ "dependency_proxy_manifests_synced_in_percentage": "100.00%",\ "dependency_proxy_manifests_verified_in_percentage": "100.00%",\ "project_repositories_count": 5,\ "project_repositories_checksum_total_count": 5,\ "project_repositories_checksummed_count": 5,\ "project_repositories_checksum_failed_count": 0,\ "project_repositories_synced_count": 5,\ "project_repositories_failed_count": 0,\ "project_repositories_registry_count": 5,\ "project_repositories_verification_total_count": 5,\ "project_repositories_verified_count": 5,\ "project_repositories_verification_failed_count": 0,\ "project_repositories_synced_in_percentage": "100.00%",\ "project_repositories_verified_in_percentage": "100.00%",\ "ci_secure_files_count": 5,\ "ci_secure_files_checksum_total_count": 5,\ "ci_secure_files_checksummed_count": 5,\ "ci_secure_files_checksum_failed_count": 0,\ "ci_secure_files_synced_count": 5,\ "ci_secure_files_failed_count": 0,\ "ci_secure_files_registry_count": 5,\ "ci_secure_files_verification_total_count": 5,\ "ci_secure_files_verified_count": 5,\ "ci_secure_files_verification_failed_count": 0,\ "ci_secure_files_synced_in_percentage": "100.00%",\ "ci_secure_files_verified_in_percentage": "100.00%",\ "pages_deployments_count": 5,\ "pages_deployments_checksum_total_count": 5,\ "pages_deployments_checksummed_count": 5,\ "pages_deployments_checksum_failed_count": 0,\ "pages_deployments_synced_count": 5,\ "pages_deployments_failed_count": 0,\ "pages_deployments_registry_count": 5,\ "pages_deployments_verification_total_count": 5,\ "pages_deployments_verified_count": 5,\ "pages_deployments_verification_failed_count": 0,\ "pages_deployments_synced_in_percentage": "100.00%",\ "pages_deployments_verified_in_percentage": "100.00%",\ "project_wiki_repositories_count": 5,\ "project_wiki_repositories_checksum_total_count": 5,\ "project_wiki_repositories_checksummed_count": 5,\ "project_wiki_repositories_checksum_failed_count": 0,\ "project_wiki_repositories_synced_count": 5,\ "project_wiki_repositories_failed_count": 0,\ "project_wiki_repositories_registry_count": 5,\ "project_wiki_repositories_verification_total_count": 5,\ "project_wiki_repositories_verified_count": 5,\ "project_wiki_repositories_verification_failed_count": 0,\ "project_wiki_repositories_synced_in_percentage": "100.00%",\ "project_wiki_repositories_verified_in_percentage": "100.00%",\ "container_repositories_replication_enabled": true,\ "abuse_report_uploads_count": 0,\ "abuse_report_uploads_checksum_total_count": 0,\ "abuse_report_uploads_checksummed_count": 0,\ "abuse_report_uploads_checksum_failed_count": 0,\ "abuse_report_uploads_synced_count": null,\ "abuse_report_uploads_failed_count": null,\ "abuse_report_uploads_registry_count": null,\ "abuse_report_uploads_verification_total_count": null,\ "abuse_report_uploads_verified_count": null,\ "abuse_report_uploads_verification_failed_count": null,\ "abuse_report_uploads_synced_in_percentage": "0.00%",\ "abuse_report_uploads_verified_in_percentage": "0.00%",\ "project_uploads_count": 0,\ "project_uploads_checksum_total_count": 0,\ "project_uploads_checksummed_count": 0,\ "project_uploads_checksum_failed_count": 0,\ "project_uploads_synced_count": null,\ "project_uploads_failed_count": null,\ "project_uploads_registry_count": null,\ "project_uploads_verification_total_count": null,\ "project_uploads_verified_count": null,\ "project_uploads_verification_failed_count": null,\ "project_uploads_synced_in_percentage": "0.00%",\ "project_uploads_verified_in_percentage": "0.00%",\ "group_uploads_count": 0,\ "group_uploads_checksum_total_count": 0,\ "group_uploads_checksummed_count": 0,\ "group_uploads_checksum_failed_count": 0,\ "group_uploads_synced_count": null,\ "group_uploads_failed_count": null,\ "group_uploads_registry_count": null,\ "group_uploads_verification_total_count": null,\ "group_uploads_verified_count": null,\ "group_uploads_verification_failed_count": null,\ "group_uploads_synced_in_percentage": "0.00%",\ "group_uploads_verified_in_percentage": "0.00%",\ "user_uploads_count": 0,\ "user_uploads_checksum_total_count": 0,\ "user_uploads_checksummed_count": 0,\ "user_uploads_checksum_failed_count": 0,\ "user_uploads_synced_count": null,\ "user_uploads_failed_count": null,\ "user_uploads_registry_count": null,\ "user_uploads_verification_total_count": null,\ "user_uploads_verified_count": null,\ "user_uploads_verification_failed_count": null,\ "user_uploads_synced_in_percentage": "0.00%",\ "user_uploads_verified_in_percentage": "0.00%",\ "design_management_action_uploads_count": 0,\ "design_management_action_uploads_checksum_total_count": 0,\ "design_management_action_uploads_checksummed_count": 0,\ "design_management_action_uploads_checksum_failed_count": 0,\ "design_management_action_uploads_synced_count": null,\ "design_management_action_uploads_failed_count": null,\ "design_management_action_uploads_registry_count": null,\ "design_management_action_uploads_verification_total_count": null,\ "design_management_action_uploads_verified_count": null,\ "design_management_action_uploads_verification_failed_count": null,\ "design_management_action_uploads_synced_in_percentage": "0.00%",\ "design_management_action_uploads_verified_in_percentage": "0.00%",\ "selective_sync_type": null,\ "namespaces": [],\ "updated_at": "2024-04-01T00:00:00.000Z",\ "storage_shards_match": true,\ "_links": {\ "self": "https://primary.example.com/api/v4/geo_nodes/2/status",\ "node": "https://primary.example.com/api/v4/geo_nodes/2"\ }\ }\ ] Retrieve a Geo node status -------------------------- Retrieves a specified Geo node status. curl \ --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/geo_nodes/2/status" Example response: { "geo_node_id": 2, "healthy": true, "health": "Healthy", "health_status": "Healthy", "missing_oauth_application": false, "db_replication_lag_seconds": 0, "lfs_objects_count": 5, "lfs_objects_checksum_total_count": 5, "lfs_objects_checksummed_count": 5, "lfs_objects_checksum_failed_count": 0, "lfs_objects_synced_count": null, "lfs_objects_failed_count": null, "lfs_objects_registry_count": null, "lfs_objects_verification_total_count": null, "lfs_objects_verified_count": null, "lfs_objects_verification_failed_count": null, "lfs_objects_synced_in_percentage": "0.00%", "lfs_objects_verified_in_percentage": "0.00%", "job_artifacts_count": 2, "job_artifacts_synced_count": 1, "job_artifacts_failed_count": 1, "job_artifacts_synced_in_percentage": "50.00%", "projects_count": 41, "repositories_count": 41, "replication_slots_count": null, "replication_slots_used_count": null, "replication_slots_used_in_percentage": "0.00%", "replication_slots_max_retained_wal_bytes": null, "last_event_id": 23, "last_event_timestamp": 1509681166, "cursor_last_event_id": 23, "cursor_last_event_timestamp": 1509681166, "last_successful_status_check_timestamp": 1510125268, "version": "10.3.0", "revision": "33d33a096a", "merge_request_diffs_count": 5, "merge_request_diffs_checksum_total_count": 5, "merge_request_diffs_checksummed_count": 5, "merge_request_diffs_checksum_failed_count": 0, "merge_request_diffs_synced_count": 5, "merge_request_diffs_failed_count": 0, "merge_request_diffs_registry_count": 5, "merge_request_diffs_verification_total_count": 5, "merge_request_diffs_verified_count": 5, "merge_request_diffs_verification_failed_count": 0, "merge_request_diffs_synced_in_percentage": "100.00%", "merge_request_diffs_verified_in_percentage": "100.00%", "package_files_count": 5, "package_files_checksum_total_count": 5, "package_files_checksummed_count": 5, "package_files_checksum_failed_count": 0, "package_files_synced_count": 5, "package_files_failed_count": 0, "package_files_registry_count": 5, "package_files_verification_total_count": 5, "package_files_verified_count": 5, "package_files_verification_failed_count": 0, "package_files_synced_in_percentage": "100.00%", "package_files_verified_in_percentage": "100.00%", "terraform_state_versions_count": 5, "terraform_state_versions_checksum_total_count": 5, "terraform_state_versions_checksummed_count": 5, "terraform_state_versions_checksum_failed_count": 0, "terraform_state_versions_synced_count": 5, "terraform_state_versions_failed_count": 0, "terraform_state_versions_registry_count": 5, "terraform_state_versions_verification_total_count": 5, "terraform_state_versions_verified_count": 5, "terraform_state_versions_verification_failed_count": 0, "terraform_state_versions_synced_in_percentage": "100.00%", "terraform_state_versions_verified_in_percentage": "100.00%", "snippet_repositories_count": 5, "snippet_repositories_checksum_total_count": 5, "snippet_repositories_checksummed_count": 5, "snippet_repositories_checksum_failed_count": 0, "snippet_repositories_synced_count": 5, "snippet_repositories_failed_count": 0, "snippet_repositories_registry_count": 5, "snippet_repositories_verification_total_count": 5, "snippet_repositories_verified_count": 5, "snippet_repositories_verification_failed_count": 0, "snippet_repositories_synced_in_percentage": "100.00%", "snippet_repositories_verified_in_percentage": "100.00%", "group_wiki_repositories_count": 5, "group_wiki_repositories_checksum_total_count": 5, "group_wiki_repositories_checksummed_count": 5, "group_wiki_repositories_checksum_failed_count": 0, "group_wiki_repositories_synced_count": 5, "group_wiki_repositories_failed_count": 0, "group_wiki_repositories_registry_count": 5, "group_wiki_repositories_verification_total_count": 5, "group_wiki_repositories_verified_count": 5, "group_wiki_repositories_verification_failed_count": 0, "group_wiki_repositories_synced_in_percentage": "100.00%", "group_wiki_repositories_verified_in_percentage": "100.00%", "pipeline_artifacts_count": 5, "pipeline_artifacts_checksum_total_count": 5, "pipeline_artifacts_checksummed_count": 5, "pipeline_artifacts_checksum_failed_count": 0, "pipeline_artifacts_synced_count": 5, "pipeline_artifacts_failed_count": 0, "pipeline_artifacts_registry_count": 5, "pipeline_artifacts_verification_total_count": 5, "pipeline_artifacts_verified_count": 5, "pipeline_artifacts_verification_failed_count": 0, "pipeline_artifacts_synced_in_percentage": "100.00%", "pipeline_artifacts_verified_in_percentage": "100.00%", "uploads_count": 5, "uploads_synced_count": null, "uploads_failed_count": 0, "uploads_registry_count": null, "uploads_synced_in_percentage": "0.00%", "uploads_checksum_total_count": 5, "uploads_checksummed_count": 5, "uploads_checksum_failed_count": null, "uploads_verification_total_count": null, "uploads_verified_count": null, "uploads_verification_failed_count": null, "uploads_verified_in_percentage": "0.00%", "job_artifacts_count": 5, "job_artifacts_checksum_total_count": 5, "job_artifacts_checksummed_count": 5, "job_artifacts_checksum_failed_count": 0, "job_artifacts_synced_count": 5, "job_artifacts_failed_count": 0, "job_artifacts_registry_count": 5, "job_artifacts_verification_total_count": 5, "job_artifacts_verified_count": 5, "job_artifacts_verification_failed_count": 0, "job_artifacts_synced_in_percentage": "100.00%", "job_artifacts_verified_in_percentage": "100.00%", "ci_secure_files_count": 5, "ci_secure_files_checksum_total_count": 5, "ci_secure_files_checksummed_count": 5, "ci_secure_files_checksum_failed_count": 0, "ci_secure_files_synced_count": 5, "ci_secure_files_failed_count": 0, "ci_secure_files_registry_count": 5, "ci_secure_files_verification_total_count": 5, "ci_secure_files_verified_count": 5, "ci_secure_files_verification_failed_count": 0, "ci_secure_files_synced_in_percentage": "100.00%", "ci_secure_files_verified_in_percentage": "100.00%", "dependency_proxy_blobs_count": 5, "dependency_proxy_blobs_checksum_total_count": 5, "dependency_proxy_blobs_checksummed_count": 5, "dependency_proxy_blobs_checksum_failed_count": 0, "dependency_proxy_blobs_synced_count": 5, "dependency_proxy_blobs_failed_count": 0, "dependency_proxy_blobs_registry_count": 5, "dependency_proxy_blobs_verification_total_count": 5, "dependency_proxy_blobs_verified_count": 5, "dependency_proxy_blobs_verification_failed_count": 0, "dependency_proxy_blobs_synced_in_percentage": "100.00%", "dependency_proxy_blobs_verified_in_percentage": "100.00%", "container_repositories_count": 5, "container_repositories_synced_count": 5, "container_repositories_failed_count": 0, "container_repositories_registry_count": 5, "container_repositories_synced_in_percentage": "100.00%", "container_repositories_checksum_total_count": 0, "container_repositories_checksummed_count": 0, "container_repositories_checksum_failed_count": 0, "container_repositories_verification_total_count": 0, "container_repositories_verified_count": 0, "container_repositories_verification_failed_count": 0, "container_repositories_verified_in_percentage": "100.00%", "dependency_proxy_manifests_count": 5, "dependency_proxy_manifests_checksum_total_count": 5, "dependency_proxy_manifests_checksummed_count": 5, "dependency_proxy_manifests_checksum_failed_count": 5, "dependency_proxy_manifests_synced_count": 5, "dependency_proxy_manifests_failed_count": 0, "dependency_proxy_manifests_registry_count": 5, "dependency_proxy_manifests_verification_total_count": 5, "dependency_proxy_manifests_verified_count": 5, "dependency_proxy_manifests_verification_failed_count": 5, "dependency_proxy_manifests_synced_in_percentage": "100.00%", "dependency_proxy_manifests_verified_in_percentage": "100.00%", "design_management_repositories_count": 5, "design_management_repositories_checksum_total_count": 5, "design_management_repositories_checksummed_count": 5, "design_management_repositories_checksum_failed_count": 5, "design_management_repositories_synced_count": 5, "design_management_repositories_failed_count": 0, "design_management_repositories_registry_count": 5, "design_management_repositories_verification_total_count": 5, "design_management_repositories_verified_count": 5, "design_management_repositories_verification_failed_count": 5, "design_management_repositories_synced_in_percentage": "100.00%", "design_management_repositories_verified_in_percentage": "100.00%", "project_repositories_count": 5, "project_repositories_checksum_total_count": 5, "project_repositories_checksummed_count": 5, "project_repositories_checksum_failed_count": 0, "project_repositories_synced_count": 5, "project_repositories_failed_count": 0, "project_repositories_registry_count": 5, "project_repositories_verification_total_count": 5, "project_repositories_verified_count": 5, "project_repositories_verification_failed_count": 0, "project_repositories_synced_in_percentage": "100.00%", "project_repositories_verified_in_percentage": "100.00%", "achievement_uploads_count": 0, "achievement_uploads_checksum_total_count": 0, "achievement_uploads_checksummed_count": 0, "achievement_uploads_checksum_failed_count": 0, "achievement_uploads_synced_count": null, "achievement_uploads_failed_count": null, "achievement_uploads_registry_count": null, "achievement_uploads_verification_total_count": null, "achievement_uploads_verified_count": null, "achievement_uploads_verification_failed_count": null, "achievement_uploads_synced_in_percentage": "0.00%", "achievement_uploads_verified_in_percentage": "0.00%", "git_fetch_event_count_weekly": 0, "git_push_event_count_weekly": 0, "proxy_remote_requests_event_count_weekly": 0, "proxy_local_requests_event_count_weekly": 0, "pages_deployments_count": 5, "pages_deployments_checksum_total_count": 5, "pages_deployments_checksummed_count": 5, "pages_deployments_checksum_failed_count": 0, "pages_deployments_synced_count": null, "pages_deployments_failed_count": null, "pages_deployments_registry_count": null, "pages_deployments_verification_total_count": null, "pages_deployments_verified_count": null, "pages_deployments_verification_failed_count": null, "pages_deployments_synced_in_percentage": "0.00%", "pages_deployments_verified_in_percentage": "0.00%", "project_wiki_repositories_count": 3, "project_wiki_repositories_checksum_total_count": 3, "project_wiki_repositories_checksummed_count": 3, "project_wiki_repositories_checksum_failed_count": 0, "project_wiki_repositories_synced_count": null, "project_wiki_repositories_failed_count": null, "project_wiki_repositories_registry_count": null, "project_wiki_repositories_verification_total_count": null, "project_wiki_repositories_verified_count": null, "project_wiki_repositories_verification_failed_count": null, "project_wiki_repositories_synced_in_percentage": "0.00%", "project_wiki_repositories_verified_in_percentage": "0.00%", "container_repositories_replication_enabled": true, "abuse_report_uploads_count": 0, "abuse_report_uploads_checksum_total_count": 0, "abuse_report_uploads_checksummed_count": 0, "abuse_report_uploads_checksum_failed_count": 0, "abuse_report_uploads_synced_count": null, "abuse_report_uploads_failed_count": null, "abuse_report_uploads_registry_count": null, "abuse_report_uploads_verification_total_count": null, "abuse_report_uploads_verified_count": null, "abuse_report_uploads_verification_failed_count": null, "abuse_report_uploads_synced_in_percentage": "0.00%", "abuse_report_uploads_verified_in_percentage": "0.00%", "project_uploads_count": 0, "project_uploads_checksum_total_count": 0, "project_uploads_checksummed_count": 0, "project_uploads_checksum_failed_count": 0, "project_uploads_synced_count": null, "project_uploads_failed_count": null, "project_uploads_registry_count": null, "project_uploads_verification_total_count": null, "project_uploads_verified_count": null, "project_uploads_verification_failed_count": null, "project_uploads_synced_in_percentage": "0.00%", "project_uploads_verified_in_percentage": "0.00%", "group_uploads_count": 0, "group_uploads_checksum_total_count": 0, "group_uploads_checksummed_count": 0, "group_uploads_checksum_failed_count": 0, "group_uploads_synced_count": null, "group_uploads_failed_count": null, "group_uploads_registry_count": null, "group_uploads_verification_total_count": null, "group_uploads_verified_count": null, "group_uploads_verification_failed_count": null, "group_uploads_synced_in_percentage": "0.00%", "group_uploads_verified_in_percentage": "0.00%", "user_uploads_count": 0, "user_uploads_checksum_total_count": 0, "user_uploads_checksummed_count": 0, "user_uploads_checksum_failed_count": 0, "user_uploads_synced_count": null, "user_uploads_failed_count": null, "user_uploads_registry_count": null, "user_uploads_verification_total_count": null, "user_uploads_verified_count": null, "user_uploads_verification_failed_count": null, "user_uploads_synced_in_percentage": "0.00%", "user_uploads_verified_in_percentage": "0.00%", "design_management_action_uploads_count": 0, "design_management_action_uploads_checksum_total_count": 0, "design_management_action_uploads_checksummed_count": 0, "design_management_action_uploads_checksum_failed_count": 0, "design_management_action_uploads_synced_count": null, "design_management_action_uploads_failed_count": null, "design_management_action_uploads_registry_count": null, "design_management_action_uploads_verification_total_count": null, "design_management_action_uploads_verified_count": null, "design_management_action_uploads_verification_failed_count": null, "design_management_action_uploads_synced_in_percentage": "0.00%", "design_management_action_uploads_verified_in_percentage": "0.00%", "selective_sync_type": null, "namespaces": [], "updated_at": "2024-04-01T00:00:00.000Z", "storage_shards_match": true, "_links": { "self": "https://primary.example.com/api/v4/geo_nodes/2/status", "node": "https://primary.example.com/api/v4/geo_nodes/2" } } The `health_status` parameter can only be in a “Healthy” or “Unhealthy” state, while the `health` parameter can be empty, “Healthy”, or contain the actual error message. --- # GraphQL API | GitLab Docs * * * GraphQL API =========== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated [GraphQL](https://graphql.org/) is a query language for APIs. You can use it to request the exact data you need, and therefore limit the number of requests you need. GraphQL data is arranged in types, so your client can use [client-side GraphQL libraries](https://graphql.org/community/tools-and-libraries/) to consume the API and avoid manual parsing. The GraphQL API is [versionless](https://graphql.org/learn/schema-design/#versioning) . Getting started --------------- If you’re new to the GitLab GraphQL API, see [Get started with GitLab GraphQL API](https://docs.gitlab.com/api/graphql/getting_started/) . You can view the available resources in the [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) . The GitLab GraphQL API endpoint is located at `/api/graphql`. ### Interactive GraphQL explorer Explore the GraphQL API using the interactive GraphQL explorer, either: * [On GitLab.com](https://gitlab.com/-/graphql-explorer) . * On GitLab Self-Managed on `https:///-/graphql-explorer`. For more information, see [GraphiQL](https://docs.gitlab.com/api/graphql/getting_started/#graphiql) . ### View GraphQL examples You can work with sample queries that pull data from public projects on GitLab.com: * [Create an audit report](https://docs.gitlab.com/api/graphql/audit_report/) * [Identify issue boards](https://docs.gitlab.com/api/graphql/sample_issue_boards/) * [Query users](https://docs.gitlab.com/api/graphql/users_example/) * [Use custom emoji](https://docs.gitlab.com/api/graphql/custom_emoji/) The [get started](https://docs.gitlab.com/api/graphql/getting_started/) page includes different methods to customize GraphQL queries. ### Authentication You can access some queries without authentication, but others require authentication. Mutations always require authentication. You can authenticate by using either a: * [Token](https://docs.gitlab.com/api/graphql/#token-authentication) * [Session cookie](https://docs.gitlab.com/api/graphql/#session-cookie-authentication) If the authentication information is not valid, GitLab returns an error message with a status code of `401`: {"errors":[{"message":"Invalid token"}]} #### Token authentication Use any of the following tokens to authenticate with the GraphQL API: * [OAuth 2.0 tokens](https://docs.gitlab.com/api/oauth2/) * [Personal access tokens](https://docs.gitlab.com/user/profile/personal_access_tokens/) * [Project access tokens](https://docs.gitlab.com/user/project/settings/project_access_tokens/) * [Group access tokens](https://docs.gitlab.com/user/group/settings/group_access_tokens/) Authenticate with a token by passing it through in a [request header](https://docs.gitlab.com/api/graphql/#header-authentication) or as a [parameter](https://docs.gitlab.com/api/graphql/#parameter-authentication) . Tokens require the correct [scope](https://docs.gitlab.com/api/graphql/#token-scopes) . ##### Header authentication Example of token authentication using an `Authorization: Bearer ` request header: curl --request POST \ --url "https://gitlab.com/api/graphql" \ --header "Authorization: Bearer " \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}" ##### Parameter authentication Example of using an OAuth 2.0 token in the `access_token` parameter: curl --request POST \ --url "https://gitlab.com/api/graphql?access_token=" \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}" You can pass in personal, project, or group access tokens using the `private_token` parameter: curl --request POST \ --url "https://gitlab.com/api/graphql?private_token=" \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}" ##### Token scopes Tokens must have the correct scope to access the GraphQL API, either: | Scope | Access | | --- | --- | | `read_api` | Grants read access to the API. Sufficient for queries. | | `api` | Grants read and write access to the API. Required by mutations. | #### Session cookie authentication Signing in to the main GitLab application sets a `_gitlab_session` session cookie. The [interactive GraphQL explorer](https://docs.gitlab.com/api/graphql/#interactive-graphql-explorer) and the web frontend of GitLab itself use this method of authentication. ### Authorization After you authenticate, the GraphQL API checks your permissions for each requested resource. How the API reports authorization failures depends on the operation type. #### Query fields Query fields return `null` when you do not have permission to access a resource. The response does not include an error message. This behavior is intentional. The API returns the same `null` response for unauthorized and nonexistent resources, so that clients cannot enumerate which resources exist on the server. For example, if you query a field that requires a role or add-on that you do not have, no entry is displayed in the `errors` array: { "data": { "group": { "fieldRequiringPermission": null } } } For [connection fields](https://docs.gitlab.com/api/graphql/getting_started/#pagination) that use the Relay pagination pattern, you can distinguish between an authorization failure and an empty result: * `"field": null` means you do not have permission to access this resource. * `"field": { "nodes": [] }` means you have permission, but no data matches your query. If you receive an unexpected `null`, verify that: * Your token has the required [scopes](https://docs.gitlab.com/api/graphql/#token-scopes) . * Your role meets the minimum access level documented in the [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) . * Your instance has the required subscription tier, features, or add-ons enabled. #### Mutations Mutations return an error message when authorization fails. The error appears in the top-level `errors` array alongside a `null` data field: { "data": { "mutationName": null }, "errors": [\ {\ "message": "The resource that you are attempting to access does not exist or you don't have permission to perform this action",\ "locations": [{ "line": 2, "column": 3 }],\ "path": ["mutationName"]\ }\ ] } The error message may differ depending on the resource type. Object identifiers ------------------ The GitLab GraphQL API uses a mix of identifiers. [Global IDs](https://docs.gitlab.com/api/graphql/#global-ids) , full paths, and internal IDs (IIDs) are all used as arguments in the GitLab GraphQL API, but often a particular part of schema does not accept all of these at the same time. Although the GitLab GraphQL API has historically not been consistent on this, in general you can expect: * If the object is a project, group, or namespace, you use the object’s full path. * If an object has an IID, you use a combination of full path and IID. * For other objects, you use a [Global ID](https://docs.gitlab.com/api/graphql/#global-ids) . For example, finding a project by its full path `"gitlab-org/gitlab"`: { project(fullPath: "gitlab-org/gitlab") { id fullPath } } Another example, locking an issue by its project’s full path `"gitlab-org/gitlab"` and the issue’s IID `"1"`: mutation { issueSetLocked(input: { projectPath: "gitlab-org/gitlab", iid: "1", locked: true }) { issue { id iid } } } An example of finding a CI runner by its Global ID: { runner(id: "gid://gitlab/Ci::Runner/1") { id } } Historically, the GitLab GraphQL API has been inconsistent with typing of full path and IID fields and arguments, but generally: * Full path fields and arguments are a GraphQL `ID` type. * IID fields and arguments are a GraphQL `String` type. ### Global IDs In the GitLab GraphQL API, a field or argument named `id` is nearly always a [Global ID](https://graphql.org/learn/global-object-identification/) and never a database primary key ID. A Global ID in the GitLab GraphQL API begins with `"gid://gitlab/"`. For example, `"gid://gitlab/Issue/123"`. Global IDs are a convention used for caching and fetching in some client-side libraries. GitLab Global IDs are subject to change. If changed, the use of the old Global ID as an argument is deprecated and supported according to the [deprecation and breaking change](https://docs.gitlab.com/api/graphql/#breaking-changes) process. You should not expect that a cached Global ID will be valid beyond the time of a GitLab GraphQL deprecation cycle. Available top-level queries --------------------------- The top-level entry points for all queries are defined in the [`Query` type](https://docs.gitlab.com/api/graphql/reference/#query-type) in the GraphQL reference. ### Multiplex queries GitLab supports batching queries into a single request. For more information, see [Multiplex](https://graphql-ruby.org/queries/multiplex.html) . Breaking changes ---------------- The GitLab GraphQL API is [versionless](https://graphql.org/learn/best-practices/#versioning) and changes to the API are primarily backward-compatible. However, GitLab sometimes changes the GraphQL API in a way that is not backward-compatible. These changes are considered breaking changes, and can include removing or renaming fields, arguments, or other parts of the schema. When creating a breaking change, GitLab follows a [deprecation and removal process](https://docs.gitlab.com/api/graphql/#deprecation-and-removal-process) . To avoid having a breaking change affect your integrations, you should: * Familiarize yourself with the [deprecation and removal process](https://docs.gitlab.com/api/graphql/#deprecation-and-removal-process) . * Frequently [verify your API calls against the future breaking-change schema](https://docs.gitlab.com/api/graphql/#verify-against-the-future-breaking-change-schema) . For GitLab Self-Managed, [reverting](https://docs.gitlab.com/update/convert_to_ee/revert/) from an EE instance to CE causes breaking changes. ### Breaking change exemptions Schema items labeled as experiments in the [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) are exempt from the deprecation process. These items can be removed or changed at any time without notice. Fields behind a feature flag and disabled by default do not follow the deprecation and removal process. These fields can be removed at any time without notice. GitLab makes all attempts to follow the [deprecation and removal process](https://docs.gitlab.com/api/graphql/#deprecation-and-removal-process) . GitLab might make immediate breaking changes to the GraphQL API to patch critical security or performance concerns if the deprecation process would pose significant risk. ### Verify against the future breaking-change schema History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353642) in GitLab 15.6. You can make calls against the GraphQL API as if all deprecated items were already removed. This way, you can verify API calls ahead of a [breaking-change release](https://docs.gitlab.com/api/graphql/#deprecation-and-removal-process) before the items are actually removed from the schema. To make these calls, add a `remove_deprecated=true` query parameter to the GraphQL API endpoint. For example, `https://gitlab.com/api/graphql?remove_deprecated=true` for GraphQL on GitLab.com. ### Deprecation and removal process Parts of the schema marked for removal from the GitLab GraphQL API are first deprecated but still available for at least six releases. They are then removed entirely during the next `XX.0` major release. Items are marked as deprecated in: * The [schema](https://spec.graphql.org/October2021/#sec--deprecated) . * The [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) . * The [deprecation feature removal schedule](https://docs.gitlab.com/update/deprecations/) , which is linked from release posts. * Introspection queries of the GraphQL API. The deprecation message provides an alternative for the deprecated schema item, if applicable. To avoid experiencing breaking changes, you should remove the deprecated schema from your GraphQL API calls as soon as possible. You should [verify your API calls against the schema without the deprecated schema items](https://docs.gitlab.com/api/graphql/#verify-against-the-future-breaking-change-schema) . #### Deprecation example The following fields are deprecated in different minor releases, but both removed in GitLab 17.0: | Field deprecated in | Reason | | --- | --- | | 15.7 | GitLab traditionally has 12 minor releases per major release. To ensure the field is available for 6 more releases, it is removed in the 17.0 major release (and not 16.0). | | 16.6 | The removal in 17.0 allows for 6 months of availability. | ### List of removed items View the [list of items removed](https://docs.gitlab.com/api/graphql/removed_items/) in previous releases. Limits ------ The following limits apply to the GitLab GraphQL API. | Limit | Default | | --- | --- | | Maximum page size | 100 records (nodes) per page. Applies to most connections in the API. Particular connections may have different max page size limits that are higher or lower. | | [Maximum query complexity](https://docs.gitlab.com/api/graphql/#maximum-query-complexity) | 200 for unauthenticated requests and 250 for authenticated requests. | | Maximum query size | 10,000 characters per query or mutation. If this limit is reached, use [variables](https://graphql.org/learn/queries/#variables)
and [fragments](https://graphql.org/learn/queries/#fragments)
to reduce the query or mutation size. Remove white spaces as last resort. | | Rate limits | For GitLab.com, see [GitLab.com-specific rate limits](https://docs.gitlab.com/user/gitlab_com/#rate-limits-on-gitlabcom)
. | | [Data limits](https://docs.gitlab.com/api/graphql/#data-limits) | Blob requests are limited to 20 MB when more than one blob path is specified. | | Request timeout | 30 seconds. | ### Maximum query complexity The GitLab GraphQL API scores the complexity of a query. Generally, larger queries have a higher complexity score. This limit is designed to protecting the API from performing queries that could negatively impact its overall performance. You can [query](https://docs.gitlab.com/api/graphql/getting_started/#query-complexity) the complexity score of a query and the limit for the request. If a query exceeds the complexity limit, an error message response is returned. In general, each field in a query adds `1` to the complexity score, although this can be higher or lower for particular fields. Sometimes, adding certain arguments may also increase the complexity of a query. ### Data limits Blob requests are limited to: * A single blob of any size. * Multiple blobs with a total size of 20 MB or less. Blobs larger than 20 MB must be requested individually. This limit applies only when you request fields that contain blob data. You might need to limit the number of paths in your requests to stay within the data limit. Make a request for the `size` field while excluding the data fields: { project(fullPath: "gitlab-org/gitlab") { repository { blobs(paths: ["big_file.rb", "small_file.rb", "huge_file.rb", ..., etc.], ref: "master") { nodes { path size } } } } } Use the response to calculate the total size and ensure subsequent requests do not exceed the 20 MB data limit. Resolve mutations detected as spam ---------------------------------- GraphQL mutations can be detected as spam. If a mutation is detected as spam and: * A CAPTCHA service is not configured, a [GraphQL top-level error](https://spec.graphql.org/June2018/#sec-Errors) is raised. For example: { "errors": [\ {\ "message": "Request denied. Spam detected",\ "locations": [ { "line": 6, "column": 7 } ],\ "path": [ "updateSnippet" ],\ "extensions": {\ "spam": true\ }\ }\ ], "data": { "updateSnippet": { "snippet": null } } } * A CAPTCHA service is configured, you receive a response with: * `needsCaptchaResponse` set to `true`. * The `spamLogId` and `captchaSiteKey` fields set. For example: { "errors": [\ {\ "message": "Request denied. Solve CAPTCHA challenge and retry",\ "locations": [ { "line": 6, "column": 7 } ],\ "path": [ "updateSnippet" ],\ "extensions": {\ "needsCaptchaResponse": true,\ "captchaSiteKey": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",\ "spamLogId": 67\ }\ }\ ], "data": { "updateSnippet": { "snippet": null, } } } * Use the `captchaSiteKey` to obtain a CAPTCHA response value using the appropriate CAPTCHA API. Only [Google reCAPTCHA v2](https://developers.google.com/recaptcha/docs/display) is supported. * Resubmit the request with the `X-GitLab-Captcha-Response` and `X-GitLab-Spam-Log-Id` headers set. The GitLab GraphiQL implementation doesn’t permit passing of headers, so the request must be a cURL query. `--data-binary` is used to properly handle escaped double quotes in the JSON-embedded query. export CAPTCHA_RESPONSE="" export SPAM_LOG_ID="" curl --request POST \ --header "Authorization: Bearer $PRIVATE_TOKEN" \ --header "Content-Type: application/json" \ --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" \ --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" \ --data-binary '{"query": "mutation {createSnippet(input: {title: \"Title\" visibilityLevel: public blobActions: [ { action: create filePath: \"BlobPath\" content: \"BlobContent\" } ] }) { snippet { id title } errors }}"}' "https://gitlab.example.com/api/graphql" --- # GraphQL API removed items | GitLab Docs * * * GraphQL API removed items ========================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated GraphQL is a versionless API, unlike the REST API. Occasionally, items have to be updated or removed from the GraphQL API. According to our [process for removing items](https://docs.gitlab.com/api/graphql/#deprecation-and-removal-process) , here are the items that have been removed. For deprecations, see the [Deprecations by version page](https://docs.gitlab.com/update/deprecations/) . GitLab 17.0 ----------- Fields removed in GitLab 17.0. ### GraphQL Fields | Field name | GraphQL type | Deprecated in | Removal MR | Use instead | | --- | --- | --- | --- | --- | | `architectureName` | `CiRunner` | 16.2 | [!124751](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124751) | Use this field in `manager` object instead. | | `executorName` | `CiRunner` | 16.2 | [!124751](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124751) | Use this field in `manager` object instead. | | `ipAddress` | `CiRunner` | 16.2 | [!124751](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124751) | Use this field in `manager` object instead. | | `platformName` | `CiRunner` | 16.2 | [!124751](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124751) | Use this field in `manager` object instead. | | `revision` | `CiRunner` | 16.2 | [!124751](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124751) | Use this field in `manager` object instead. | | `version` | `CiRunner` | 16.2 | [!124751](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124751) | Use this field in `manager` object instead. | GitLab 16.0 ----------- Fields removed in GitLab 16.0. ### GraphQL Fields | Field name | GraphQL type | Deprecated in | Removal MR | Use instead | | --- | --- | --- | --- | --- | | `name` | `PipelineSecurityReportFinding` | [15.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89571) | [!119055](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119055) | `title` | | `external` | `ReleaseAssetLink` | 15.9 | [!111750](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/111750) | None | | `confidence` | `PipelineSecurityReportFinding` | 15.4 | [!118617](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118617) | None | | `PAUSED` | `CiRunnerStatus` | 14.8 | [!118635](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118635) | `CiRunner.paused: true` | | `ACTIVE` | `CiRunnerStatus` | 14.8 | [!118635](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118635) | `CiRunner.paused: false` | ### GraphQL Mutations | Argument name | Mutation | Deprecated in | Use instead | | --- | --- | --- | --- | | \- | `vulnerabilityFindingDismiss` | [15.5](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/99170) | `vulnerabilityDismiss` or `securityFindingDismiss` | | \- | `apiFuzzingCiConfigurationCreate` | [15.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87241) | `todos` | | \- | `CiCdSettingsUpdate` | [15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/361801) | `ProjectCiCdSettingsUpdate` | GitLab 15.0 ----------- Fields removed in GitLab 15.0. ### GraphQL Mutations [Removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85382) in GitLab 15.0: | Argument name | Mutation | Deprecated in | Use instead | | --- | --- | --- | --- | | \- | `clusterAgentTokenDelete` | 14.7 | `clusterAgentTokenRevoke` | ### GraphQL Fields [Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/342882) in GitLab 15.0: | Argument name | Field name | Deprecated in | Use instead | | --- | --- | --- | --- | | \- | `pipelines` | 14.5 | None | ### GraphQL Types | Field name | GraphQL type | Deprecated in | Use instead | | --- | --- | --- | --- | | `defaultMergeCommitMessageWithDescription` | `GraphQL::Types::String` | 14.5 | None. Define a [merge commit template](https://docs.gitlab.com/user/project/merge_requests/commit_templates/)
in your project and use `defaultMergeCommitMessage`. | --- # Group Markdown uploads API | GitLab Docs * * * Group Markdown uploads API ========================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [Markdown uploads](https://docs.gitlab.com/security/user_file_uploads/) that can be referenced in Markdown text in epics or wiki pages. List all uploads for a group ---------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2. Lists all uploads for a specified group sorted by `created_at` in descending order. You must have the Maintainer or Owner role to use this endpoint. GET /groups/:id/uploads | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/uploads" Example response: [\ {\ "id": 1,\ "size": 1024,\ "filename": "image.png",\ "created_at":"2024-06-20T15:53:03.067Z",\ "uploaded_by": {\ "id": 18,\ "name" : "Alexandra Bashirian",\ "username" : "eileen.lowe"\ }\ },\ {\ "id": 2,\ "size": 512,\ "filename": "other-image.png",\ "created_at":"2024-06-19T15:53:03.067Z",\ "uploaded_by": null\ }\ ] Download an uploaded file by ID ------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2. Downloads an uploaded file with the specified ID. You must have the Maintainer or Owner role to use this endpoint. GET /groups/:id/uploads/:upload_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `upload_id` | integer | Yes | The ID of the upload. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/uploads/1" If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the uploaded file in the response body. Download an uploaded file by secret and filename ------------------------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4. Downloads an uploaded file with the specified secret and filename. You must have the Guest, Planner, Reporter, Developer, Maintainer, or Owner role to use this endpoint. GET /groups/:id/uploads/:secret/:filename Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `secret` | string | Yes | The 32-character secret of the upload. | | `filename` | string | Yes | The filename of the upload. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg" If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the uploaded file in the response body. Delete an uploaded file by ID ----------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2. Deletes an uploaded file with the specified ID. You must have the Maintainer or Owner role to use this endpoint. DELETE /groups/:id/uploads/:upload_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `upload_id` | integer | Yes | The ID of the upload. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/uploads/1" If successful, returns [`204`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) status code without any response body. Delete an uploaded file by secret and filename ---------------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4. Deletes an uploaded file with the specified secret and filename. You must have the Maintainer or Owner role to use this endpoint. DELETE /groups/:id/uploads/:secret/:filename Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `secret` | string | Yes | The 32-character secret of the upload. | | `filename` | string | Yes | The filename of the upload. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg" If successful, returns [`204`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) status code without any response body. --- # Group iterations API | GitLab Docs * * * Group iterations API ==================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to access [group iterations](https://docs.gitlab.com/user/group/iterations/) . For project iterations, use the [project iterations API](https://docs.gitlab.com/api/iterations/) . List all group iterations ------------------------- Lists all iterations for a specified group. Iterations created by **Enable automatic scheduling** in [iteration cadences](https://docs.gitlab.com/user/group/iterations/#iteration-cadences) return `null` for the `title` and `description` fields. GET /groups/:id/iterations GET /groups/:id/iterations?state=opened GET /groups/:id/iterations?state=closed GET /groups/:id/iterations?search=version GET /groups/:id/iterations?include_ancestors=false GET /groups/:id/iterations?include_descendants=true GET /groups/:id/iterations?updated_before=2013-10-02T09%3A24%3A18Z GET /groups/:id/iterations?updated_after=2013-10-02T09%3A24%3A18Z | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `state` | string | no | ‘Return `opened`, `upcoming`, `current`, `closed`, or `all` iterations.’ | | `search` | string | no | Return only iterations with a title matching the provided string. | | `in` | array of strings | no | Fields in which fuzzy search should be performed with the query given in the argument `search`. The available options are `title` and `cadence_title`. Default is `[title]`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350991)
in GitLab 16.2. | | `include_ancestors` | boolean | no | Include iterations for group and its ancestors. Defaults to `true`. | | `include_descendants` | boolean | no | Include iterations for group and its descendants. Defaults to `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135764)
in GitLab 16.7. | | `updated_before` | datetime | no | Return only iterations updated before the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378662)
in GitLab 15.10. | | `updated_after` | datetime | no | Return only iterations updated after the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378662)
in GitLab 15.10. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/iterations" Example response: [\ {\ "id": 53,\ "iid": 13,\ "sequence": 1,\ "group_id": 5,\ "title": "Iteration II",\ "description": "Ipsum Lorem ipsum",\ "state": 2,\ "created_at": "2020-01-27T05:07:12.573Z",\ "updated_at": "2020-01-27T05:07:12.573Z",\ "due_date": "2020-02-01",\ "start_date": "2020-02-14",\ "web_url": "http://gitlab.example.com/groups/my-group/-/iterations/13"\ }\ ] --- # Group milestones API | GitLab Docs * * * Group milestones API ==================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [group milestones](https://docs.gitlab.com/user/project/milestones/) . For project milestones, use the [project milestones API](https://docs.gitlab.com/api/milestones/) . List group milestones --------------------- Returns a list of group milestones. GET /groups/:id/milestones GET /groups/:id/milestones?iids[]=42 GET /groups/:id/milestones?iids[]=42&iids[]=43 GET /groups/:id/milestones?state=active GET /groups/:id/milestones?state=closed GET /groups/:id/milestones?title=1.0 GET /groups/:id/milestones?search=version GET /groups/:id/milestones?search_title=17.3+17.4 GET /groups/:id/milestones?search_title=17.3%2017.4 GET /groups/:id/milestones?updated_before=2013-10-02T09%3A24%3A18Z GET /groups/:id/milestones?updated_after=2013-10-02T09%3A24%3A18Z GET /groups/:id/milestones?containing_date=2013-10-02T09%3A24%3A18Z GET /groups/:id/milestones?start_date=2013-10-02T09%3A24%3A18Z&end_date=2013-11-02T09%3A24%3A18Z Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `iids[]` | integer array | no | Return only the milestones having the given `iid`. Ignored if `include_ancestors` is `true`. | | `state` | string | no | Return only `active` or `closed` milestones. | | `title` | string | no | Return only the milestones having the given `title` (case-sensitive). | | `search` | string | no | Return only milestones with a title or description matching the provided string (case-insensitive). | | `search_title` | string | no | Return only milestones with a title matching the provided string (case-insensitive). Multiple terms can be provided, separated by an escaped space, either `+` or `%20`, and will be ANDed together. Example: `17.4+17.5` will match substrings `17.4` and `17.5` (in any order). Introduced in GitLab 11.8. | | `include_parent_milestones` | boolean | no | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/433298)
in GitLab 16.7. Use `include_ancestors` instead. | | `include_ancestors` | boolean | no | Include milestones for all parent groups. | | `include_descendants` | boolean | no | Include milestones for group and its descendants. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/421030)
in GitLab 16.7. | | `updated_before` | datetime | no | Return only milestones updated before the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10. | | `updated_after` | datetime | no | Return only milestones updated after the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10. | | `containing_date` | datetime | no | Return only milestones where `start_date <= containing_date <= due_date`. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 13.5. | | `start_date` | datetime | no | Return only milestones where `due_date >=` the provided `start_date`. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Note: only valid if `end_date` is also provided. Introduced in GitLab 12.8. | | `end_date` | datetime | no | Return only milestones where `start_date <=` the provided `end_date`. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Note: only valid if `start_date` is also provided. Introduced in GitLab 12.8. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/milestones" Example Response: [\ {\ "id": 12,\ "iid": 3,\ "group_id": 16,\ "title": "10.0",\ "description": "Version",\ "due_date": "2013-11-29",\ "start_date": "2013-11-10",\ "state": "active",\ "updated_at": "2013-10-02T09:24:18Z",\ "created_at": "2013-10-02T09:24:18Z",\ "expired": false,\ "web_url": "https://gitlab.com/groups/gitlab-org/-/milestones/42"\ }\ ] Get single milestone -------------------- Gets a single group milestone. GET /groups/:id/milestones/:milestone_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `milestone_id` | integer | yes | The ID of the group milestone | Create new milestone -------------------- Creates a new group milestone. POST /groups/:id/milestones Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `title` | string | yes | The title of a milestone | | `description` | string | no | The description of the milestone | | `due_date` | date | no | The due date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) | | `start_date` | date | no | The start date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) | Edit milestone -------------- Updates an existing group milestone. PUT /groups/:id/milestones/:milestone_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `milestone_id` | integer | yes | The ID of a group milestone | | `title` | string | no | The title of a milestone | | `description` | string | no | The description of a milestone | | `due_date` | date | no | The due date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) | | `start_date` | date | no | The start date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) | | `state_event` | string | no | The state event of the milestone _(`close` or `activate`)_ | Delete group milestone ---------------------- Only for users with the Developer role for the group. DELETE /groups/:id/milestones/:milestone_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `milestone_id` | integer | yes | The ID of the group’s milestone | Get all issues assigned to a single milestone --------------------------------------------- Gets all issues assigned to a single group milestone. GET /groups/:id/milestones/:milestone_id/issues Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `milestone_id` | integer | yes | The ID of a group milestone | Currently, this API endpoint doesn’t return issues from any subgroups. If you want to get all the milestones’ issues, you can instead use the [List issues API](https://docs.gitlab.com/api/issues/#list-all-issues) and filter for a particular milestone (for example, `GET /issues?milestone=1.0.0&state=opened`). Get all merge requests assigned to a single milestone ----------------------------------------------------- Gets all merge requests assigned to a single group milestone. GET /groups/:id/milestones/:milestone_id/merge_requests Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `milestone_id` | integer | yes | The ID of a group milestone | Get all burndown chart events for a single milestone ---------------------------------------------------- * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Get all burndown chart events for a single milestone. GET /groups/:id/milestones/:milestone_id/burndown_events Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `milestone_id` | integer | yes | The ID of a group milestone | --- # Group labels API | GitLab Docs * * * Group labels API ================ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * `archived` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4233) in GitLab 18.3 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `labels_archive`. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/556700) in GitLab 18.10. Feature flag `labels_archive` removed. Use this API to manage [group labels](https://docs.gitlab.com/user/project/labels/#types-of-labels) . For project labels, use the [project labels API](https://docs.gitlab.com/api/labels/) . List group labels ----------------- Get all labels for a given group. GET /groups/:id/labels | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. | | `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. | | `include_descendant_groups` | boolean | no | Include descendant groups. Defaults to `false`. | | `only_group_labels` | boolean | no | Toggle to include only group labels or also project labels. Defaults to `true`. | | `search` | string | no | Keyword to filter labels by. | | `archived` | boolean | no | If `true`, returns only archived labels. If unset, returns all labels. | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/labels?with_counts=true" Example response: [\ {\ "id": 7,\ "name": "bug",\ "color": "#FF0000",\ "text_color" : "#FFFFFF",\ "description": null,\ "description_html": null,\ "open_issues_count": 0,\ "closed_issues_count": 0,\ "open_merge_requests_count": 0,\ "subscribed": false,\ "archived": false\ },\ {\ "id": 4,\ "name": "feature",\ "color": "#228B22",\ "text_color" : "#FFFFFF",\ "description": null,\ "description_html": null,\ "open_issues_count": 0,\ "closed_issues_count": 0,\ "open_merge_requests_count": 0,\ "subscribed": false,\ "archived": false\ }\ ] Get a single group label ------------------------ Get a single label for a given group. GET /groups/:id/labels/:label_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `label_id` | integer or string | yes | The ID or title of a group’s label. | | `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. | | `include_descendant_groups` | boolean | no | Include descendant groups. Defaults to `false`. | | `only_group_labels` | boolean | no | Toggle to include only group labels or also project labels. Defaults to `true`. | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/labels/bug" Example response: { "id": 7, "name": "bug", "color": "#FF0000", "text_color" : "#FFFFFF", "description": null, "description_html": null, "open_issues_count": 0, "closed_issues_count": 0, "open_merge_requests_count": 0, "subscribed": false, "archived": false } Create a new group label ------------------------ Create a new group label for a given group. POST /groups/:id/labels | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `name` | string | yes | The name of the label | | `color` | string | yes | The color of the label given in 6-digit hex notation with leading ‘#’ sign (for example, #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) | | `description` | string | no | The description of the label, | | `archived` | boolean | no | If `true`, marks the label as archived. Default value: `false`. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "name": "Feature Proposal", "color": "#FFA500", "description": "Describes new ideas" }' \ --url "https://gitlab.example.com/api/v4/groups/5/labels" Example response: { "id": 9, "name": "Feature Proposal", "color": "#FFA500", "text_color" : "#FFFFFF", "description": "Describes new ideas", "description_html": "Describes new ideas", "open_issues_count": 0, "closed_issues_count": 0, "open_merge_requests_count": 0, "subscribed": false, "archived": false } Update a group label -------------------- Updates an existing group label. At least one parameter is required, to update the group label. PUT /groups/:id/labels/:label_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `label_id` | integer or string | yes | The ID or title of a group’s label. | | `new_name` | string | no | The new name of the label | | `color` | string | no | The color of the label given in 6-digit hex notation with leading ‘#’ sign (for example, #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) | | `description` | string | no | The description of the label. | | `archived` | boolean | no | If `true`, marks the label as archived. Default value: `false`. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"new_name": "Feature Idea"}' \ --url "https://gitlab.example.com/api/v4/groups/5/labels/Feature%20Proposal" Example response: { "id": 9, "name": "Feature Idea", "color": "#FFA500", "text_color" : "#FFFFFF", "description": "Describes new ideas", "description_html": "Describes new ideas", "open_issues_count": 0, "closed_issues_count": 0, "open_merge_requests_count": 0, "subscribed": false, "archived": false } An older endpoint `PUT /groups/:id/labels` with `name` in the parameters is still available, but deprecated. Delete a group label -------------------- Deletes a group label with a given name. DELETE /groups/:id/labels/:label_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `label_id` | integer or string | yes | The ID or title of a group’s label. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/labels/bug" An older endpoint `DELETE /groups/:id/labels` with `name` in the parameters is still available, but deprecated. Subscribe to a group label -------------------------- Subscribes the authenticated user to a group label to receive notifications. If the user is already subscribed to the label, the status code `304` is returned. POST /groups/:id/labels/:label_id/subscribe | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `label_id` | integer or string | yes | The ID or title of a group’s label. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/labels/9/subscribe" Example response: { "id": 9, "name": "Feature Idea", "color": "#FFA500", "text_color" : "#FFFFFF", "description": "Describes new ideas", "description_html": "Describes new ideas", "open_issues_count": 0, "closed_issues_count": 0, "open_merge_requests_count": 0, "subscribed": true, "archived": false } Unsubscribe from a group label ------------------------------ Unsubscribes the authenticated user from a group label to not receive notifications from it. If the user is not subscribed to the label, the status code `304` is returned. POST /groups/:id/labels/:label_id/unsubscribe | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `label_id` | integer or string | yes | The ID or title of a group’s label. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/labels/9/unsubscribe" Example response: { "id": 9, "name": "Feature Idea", "color": "#FFA500", "text_color" : "#FFFFFF", "description": "Describes new ideas", "description_html": "Describes new ideas", "open_issues_count": 0, "closed_issues_count": 0, "open_merge_requests_count": 0, "subscribed": false, "archived": false } --- # Group placeholder reassignments API | GitLab Docs * * * Group placeholder reassignments API =================================== * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/513794) in GitLab 17.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `importer_user_mapping_reassignment_csv`. Enabled by default. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/478022) in GitLab 18.0. Feature flag `importer_user_mapping_reassignment_csv` removed. * Reassigning contributions to a personal namespace owner when importing to a personal namespace [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/525342) in GitLab 18.3 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `user_mapping_to_personal_namespace_owner`. Disabled by default. * Reassigning contributions to a personal namespace owner when importing to a personal namespace [generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/211626) in GitLab 18.6. Feature flag `user_mapping_to_personal_namespace_owner` removed. The availability of this feature is controlled by a feature flag. For more information, see the history. Use this API to [reassign placeholder users in bulk](https://docs.gitlab.com/user/import/mapping/reassignment/#request-reassignment-by-using-a-csv-file) . Prerequisites: * You must have the Owner role for the group. User contribution mapping is not supported when you import projects to a [personal namespace](https://docs.gitlab.com/user/namespace/#types-of-namespaces) . When you import to a personal namespace, all contributions are assigned to the personal namespace owner and they cannot be reassigned. Retrieve pending reassignments ------------------------------ Retrieves a CSV file with a list of pending reassignments. GET /groups/:id/placeholder_reassignments Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID of the group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/2/placeholder_reassignments" Example response: Source host,Import type,Source user identifier,Source user name,Source username,GitLab username,GitLab public email http://gitlab.example,gitlab_migration,11,Bob,bob,"","" http://gitlab.example,gitlab_migration,9,Alice,alice,"","" Reassign placeholders --------------------- Reassigns placeholder users with an uploaded CSV file. POST /groups/:id/placeholder_reassignments Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID of the group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --form "file=@placeholder_reassignments_for_group_2_1741253695.csv" \ --url "http://gdk.test:3000/api/v4/groups/2/placeholder_reassignments" Example response: {"message":"The file is being processed and you will receive an email when completed."} --- # Group issue boards API | GitLab Docs * * * Group issue boards API ====================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [group issue boards](https://docs.gitlab.com/user/project/issue_board/#group-issue-boards) . Every call to this API requires authentication. If a user is not a member of a group and the group is private, a `GET` request results in `404` status code. List all group issue boards in a group -------------------------------------- Lists all group issue boards for a specified group. GET /groups/:id/boards | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards" Example response: [\ {\ "id": 1,\ "name": "group issue board",\ "hide_backlog_list": false,\ "hide_closed_list": false,\ "group": {\ "id": 5,\ "name": "Documentcloud",\ "web_url": "http://example.com/groups/documentcloud"\ },\ "milestone": {\ "id": 12,\ "title": "10.0"\ },\ "lists" : [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3\ }\ ]\ }\ ] Users on [GitLab Premium or Ultimate](https://about.gitlab.com/pricing/) see different parameters, due to the ability to have multiple group boards. Example response: [\ {\ "id": 1,\ "name": "group issue board",\ "hide_backlog_list": false,\ "hide_closed_list": false,\ "group": {\ "id": 5,\ "name": "Documentcloud",\ "web_url": "http://example.com/groups/documentcloud"\ },\ "milestone": {\ "id": 12,\ "title": "10.0"\ },\ "lists" : [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3\ }\ ]\ }\ ] Retrieve a group issue board ---------------------------- Retrieves a specified group issue board. GET /groups/:id/boards/:board_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/1" Example response: { "id": 1, "name": "group issue board", "hide_backlog_list": false, "hide_closed_list": false, "group": { "id": 5, "name": "Documentcloud", "web_url": "http://example.com/groups/documentcloud" }, "milestone": { "id": 12, "title": "10.0" }, "lists" : [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3\ }\ ] } Users on [GitLab Premium or Ultimate](https://about.gitlab.com/pricing/) see different parameters, due to the ability to have multiple group issue boards. Example response: { "id": 1, "name": "group issue board", "hide_backlog_list": false, "hide_closed_list": false, "group": { "id": 5, "name": "Documentcloud", "web_url": "http://example.com/groups/documentcloud" }, "milestone": { "id": 12, "title": "10.0" }, "lists" : [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3\ }\ ] } Create a group issue board -------------------------- * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Creates a group issue board for a specified group. POST /groups/:id/boards | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `name` | string | yes | The name of the new board. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards?name=newboard" Example response: { "id": 1, "name": "newboard", "hide_backlog_list": false, "hide_closed_list": false, "project": null, "lists" : [], "group": { "id": 5, "name": "Documentcloud", "web_url": "http://example.com/groups/documentcloud" }, "milestone": null, "assignee" : null, "labels" : [], "weight" : null } Update a group issue board -------------------------- Updates a specified group issue board. PUT /groups/:id/boards/:board_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | | `name` | string | no | The new name of the board. | | `hide_backlog_list` | boolean | no | Hide the Open list. | | `hide_closed_list` | boolean | no | Hide the Closed list. | | `assignee_id` | integer | no | The assignee the board should be scoped to. Premium and Ultimate only. | | `milestone_id` | integer | no | The milestone the board should be scoped to. Premium and Ultimate only. | | `labels` | string | no | Comma-separated list of label names which the board should be scoped to. Premium and Ultimate only. | | `weight` | integer | no | The weight range from 0 to 9, to which the board should be scoped to. Premium and Ultimate only. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/1?name=new_name&milestone_id=44&assignee_id=1&labels=GroupLabel&weight=4" Example response: { "id": 1, "name": "new_name", "hide_backlog_list": false, "hide_closed_list": false, "project": null, "lists": [], "group": { "id": 5, "name": "Documentcloud", "web_url": "http://example.com/groups/documentcloud" }, "milestone": { "id": 44, "iid": 1, "group_id": 5, "title": "Group Milestone", "description": "Group Milestone Desc", "state": "active", "created_at": "2018-07-03T07:15:19.271Z", "updated_at": "2018-07-03T07:15:19.271Z", "due_date": null, "start_date": null, "web_url": "http://example.com/groups/documentcloud/-/milestones/1" }, "assignee": { "id": 1, "name": "Administrator", "username": "root", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://example.com/root" }, "labels": [{\ "id": 11,\ "name": "GroupLabel",\ "color": "#428BCA",\ "description": ""\ }], "weight": 4 } Delete a group issue board -------------------------- * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Deletes a specified group issue board. DELETE /groups/:id/boards/:board_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/1" List group issue board lists ---------------------------- Lists all group issue board lists for a specified board. Does not include `open` and `closed` lists. GET /groups/:id/boards/:board_id/lists | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/1/lists" Example response: [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3\ }\ ] Retrieve a group issue board list --------------------------------- Retrieves a specified group issue board list. GET /groups/:id/boards/:board_id/lists/:list_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | | `list_id` | integer | yes | The ID of a board’s list. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/1/lists/1" Example response: { "id" : 1, "label" : { "name" : "Testing", "color" : "#F0AD4E", "description" : null }, "position" : 1 } Create a group issue board list ------------------------------- Creates a group issue board list for a specified board. POST /groups/:id/boards/:board_id/lists | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | | `label_id` | integer | no | The ID of a label. | | `assignee_id` | integer | no | The ID of a user. Premium and Ultimate only. | | `milestone_id` | integer | no | The ID of a milestone. Premium and Ultimate only. | | `iteration_id` | integer | no | The ID of a iteration. Premium and Ultimate only. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/12/lists?milestone_id=7" Example response: { "id": 9, "label": null, "position": 0, "milestone": { "id": 7, "iid": 3, "group_id": 12, "title": "Milestone with due date", "description": "", "state": "active", "created_at": "2017-09-03T07:16:28.596Z", "updated_at": "2017-09-03T07:16:49.521Z", "due_date": null, "start_date": null, "web_url": "https://gitlab.example.com/groups/issue-reproduce/-/milestones/3" } } Update a group issue board list ------------------------------- Updates a specified group issue board list. This call is used to change list position. PUT /groups/:id/boards/:board_id/lists/:list_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | | `list_id` | integer | yes | The ID of a board’s list. | | `position` | integer | yes | The position of the list. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/1/lists/1?position=2" Example response: { "id" : 1, "label" : { "name" : "Testing", "color" : "#F0AD4E", "description" : null }, "position" : 1 } Delete a group issue board list ------------------------------- Deletes a specified group issue board list. Only for administrators and group owners. DELETE /groups/:id/boards/:board_id/lists/:list_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `board_id` | integer | yes | The ID of a board. | | `list_id` | integer | yes | The ID of a board’s list. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/boards/1/lists/1" --- # Group SSH certificates API | GitLab Docs * * * Group SSH certificates API ========================== * Tier: Premium, Ultimate * Offering: GitLab.com History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/421915) in GitLab 16.4 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `ssh_certificates_rest_endpoints`. Disabled by default. * [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/424501) in GitLab 16.9. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/424501) in GitLab 17.7. Feature flag `ssh_certificates_rest_endpoints` removed. Use this API to manage [SSH certificates for groups](https://docs.gitlab.com/user/group/ssh_certificates/) . Only top-level groups can store SSH certificates. Prerequisites: * You must be an Owner for a top-level group. List all group SSH certificates ------------------------------- Lists all SSH certificates for a specified group. GET /groups/:id/ssh_certificates Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of the group. | By default, `GET` requests return 20 results at a time because the API results are paginated. Read more on [pagination](https://docs.gitlab.com/api/rest/#pagination) . Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://primary.example.com/api/v4/groups/90/ssh_certificates" Example response: [\ {\ "id": 12345,\ "title": "SSH Title 1",\ "key": "ssh-rsa AAAAB3NzaC1ea2dAAAADAQABAAAAgQDGbLkF44ScxRQi2FfA7VsHgGqptguSbmW26jkJhEiRZpGS4/+UzaaSqc8Psw2OhSsKc5QwfrB/ANpO4LhOjDzhf2FuD8ACkv3R7XtaJ+rN6PlyzoBfLAiSyzxhEoMFDBprTgaiZKgg2yQ9dRH55w3f6XMZ4hnaUae53nQgfQLxFw== example@gitlab.com",\ "created_at": "2023-09-08T12:39:00.172Z"\ },\ {\ "id":12346,\ "title":"SSH Title 2",\ "key": "ssh-rsa AAAAB3NzaC1ac2EAAAADAQABAAAAgQDTl/hHfu1F/KlR+QfgM2wUmyxcN5YeiaWluEGIrfXUeJuI+bK6xjpE3+2afHDYtE9VQkeL32KRjefX2d72Jeoa68ewt87Vn8CcGkUTOTpHNzeL8pHMKFs3m7ArSBxNg5vTdgAsq5dbDGNtat7b2WCHTNvtWoON1Jetne30uW2EwQ== example@gitlab.com",\ "created_at": "2023-09-08T12:39:00.244Z"\ }\ ] Add a group SSH certificate --------------------------- Adds a group SSH certificate for a specified group. POST /groups/:id/ssh_certificates Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of the group. | | `key` | string | Yes | The public key of the SSH certificate. | | `title` | string | Yes | The title of the SSH certificate. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/ssh_certificates?title=newtitle&key=ssh-rsa+REDACTED+example%40gitlab.com" Example response: { "id": 54321, "title": "newtitle", "key": "ssh-rsa ssh-rsa AAAAB3NzaC1ea2dAAAADAQABAAAAgQDGbLkF44ScxRQi2FfA7VsHgGqptguSbmW26jkJhEiRZpGS4/+UzaaSqc8Psw2OhSsKc5QwfrB/ANpO4LhOjDzhf2FuD8ACkv3R7XtaJ+rN6PlyzoBfLAiSyzxhEoMFDBprTgaiZKgg2yQ9dRH55w3f6XMZ4hnaUae53nQgfQLxFw== example@gitlab.com", "created_at": "2023-09-08T12:39:00.172Z" } Delete a group SSH certificate ------------------------------ Deletes a specified group SSH certificate. DELETE /groups/:id/ssh_certificate/:id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of the group | | `id` | integer | Yes | The ID of the SSH certificate | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/ssh_certificates/12345" --- # Group push rules API | GitLab Docs * * * Group push rules API ==================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [group push rules](https://docs.gitlab.com/user/project/repository/push_rules/#group-push-rules) for newly created projects in a group. Prerequisites: * You must have the Owner role for the group or be an administrator for the instance. Retrieve the push rules of a group ---------------------------------- Retrieves the push rules of a specified group. GET /groups/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID of the group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author_email_regex` | string | Allow only commit author emails that match this regular expression. | | `branch_name_regex` | string | Allow only branch names that match this regular expression. | | `commit_committer_check` | boolean | If `true`, allows commits from users only if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | If `true`, allows commits from users only if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | Reject commit messages matching this regular expression. | | `commit_message_regex` | string | Allow only commit messages that match this regular expression. | | `created_at` | string | Date and time when the push rule was created. | | `deny_delete_tag` | boolean | If `true`, denies deleting a tag. | | `file_name_regex` | string | Reject filenames matching this regular expression. | | `id` | integer | The ID of the push rule. | | `max_file_size` | integer | Maximum file size (MB) allowed. | | `member_check` | boolean | If `true`, allows only GitLab users to author commits. | | `prevent_secrets` | boolean | If `true`, rejects files that are likely to contain secrets. | | `reject_non_dco_commits` | boolean | If `true`, rejects a commit when it’s not DCO certified. | | `reject_unsigned_commits` | boolean | If `true`, rejects a commit when it’s not signed. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/2/push_rule" Example response when push rules are configured with all settings disabled: { "id": 1, "created_at": "2020-08-17T19:09:19.580Z", "commit_message_regex": "[a-zA-Z]", "commit_message_negative_regex": "[x+]", "branch_name_regex": "[a-z]", "author_email_regex": "^[A-Za-z0-9.]+@gitlab.com$", "file_name_regex": "(exe)$", "deny_delete_tag": false, "member_check": false, "prevent_secrets": false, "max_file_size": 0, "commit_committer_check": null, "commit_committer_name_check": false, "reject_unsigned_commits": null, "reject_non_dco_commits": null } If push rules were never configured for the group, returns [`404 Not Found`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) : { "message": "404 Not Found" } This differs from the [project push rules API](https://docs.gitlab.com/api/project_push_rules/#retrieve-the-push-rules-of-a-project) , which returns HTTP `200 OK` with the literal string `"null"` when no push rules are configured. When disabled, some boolean attributes return `null` instead of `false`. For example: * `commit_committer_check` * `reject_unsigned_commits` * `reject_non_dco_commits` Add push rules to a group ------------------------- Adds push rules to the specified group. Use only if you haven’t defined any push rules so far. POST /groups/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `author_email_regex` | string | No | Allow only commit author emails that match the regular expression provided in this attribute, for example, `@my-company.com$`. | | `branch_name_regex` | string | No | Allow only branch names that match the regular expression provided in this attribute, for example, `(feature\|hotfix)\/.*`. | | `commit_committer_check` | boolean | No | If `true`, allows commits from users only if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | No | If `true`, allows commits from users only if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | No | Reject commit messages matching the regular expression provided in this attribute, for example, `ssh\:\/\/`. | | `commit_message_regex` | string | No | If `true`, allows only commit messages that match the regular expression provided in this attribute, for example, `Fixed \d+\..*`. | | `deny_delete_tag` | boolean | No | Deny deleting a tag. | | `file_name_regex` | string | No | Reject filenames matching the regular expression provided in this attribute, for example, `(jar\|exe)$`. | | `max_file_size` | integer | No | Maximum file size (MB) allowed. | | `member_check` | boolean | No | If `true`, allows only GitLab users to author commits. | | `prevent_secrets` | boolean | No | If `true`, rejects files that are likely to [contain secrets](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/checks/files_denylist.yml)
. | | `reject_non_dco_commits` | boolean | No | If `true`, rejects a commit when it’s not DCO certified. | | `reject_unsigned_commits` | boolean | No | If `true`, rejects a commit when it’s not signed. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author_email_regex` | string | Allow only commit author emails that match this regular expression. | | `branch_name_regex` | string | Allow only branch names that match this regular expression. | | `commit_committer_check` | boolean | If `true`, allows commits from users only if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | If `true`, allows commits from users only if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | Reject commit messages matching this regular expression. | | `commit_message_regex` | string | If `true`, allows only commit messages that match this regular expression. | | `created_at` | string | Date and time when the push rule was created. | | `deny_delete_tag` | boolean | If `true`, denies deleting a tag. | | `file_name_regex` | string | Reject filenames matching this regular expression. | | `id` | integer | The ID of the push rule. | | `max_file_size` | integer | Maximum file size (MB) allowed. | | `member_check` | boolean | If `true`, allows only GitLab users to author commits. | | `prevent_secrets` | boolean | If `true`, rejects files that are likely to contain secrets. | | `reject_non_dco_commits` | boolean | If `true`, rejects a commit when it’s not DCO certified. | | `reject_unsigned_commits` | boolean | If `true`, rejects a commit when it’s not signed. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/19/push_rule?prevent_secrets=true" Example response: { "id": 1, "created_at": "2020-08-31T15:53:00.073Z", "commit_committer_check": false, "commit_committer_name_check": false, "reject_unsigned_commits": false, "reject_non_dco_commits": false, "commit_message_regex": "[a-zA-Z]", "commit_message_negative_regex": "[x+]", "branch_name_regex": null, "deny_delete_tag": false, "member_check": false, "prevent_secrets": true, "author_email_regex": "^[A-Za-z0-9.]+@gitlab.com$", "file_name_regex": null, "max_file_size": 100 } Update push rules of a group ---------------------------- Updates the push rules for the specified group. PUT /groups/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `author_email_regex` | string | No | Allow only commit author emails that match the regular expression provided in this attribute, for example, `@my-company.com$`. | | `branch_name_regex` | string | No | Allow only branch names that match the regular expression provided in this attribute, for example, `(feature\|hotfix)\/.*`. | | `commit_committer_check` | boolean | No | If `true`, allows commits from users only if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | No | If `true`, allows commits from users only if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | No | Reject commit messages matching the regular expression provided in this attribute, for example, `ssh\:\/\/`. | | `commit_message_regex` | string | No | If `true`, allows only commit messages that match the regular expression provided in this attribute, for example, `Fixed \d+\..*`. | | `deny_delete_tag` | boolean | No | If `true`, denies deleting a tag. | | `file_name_regex` | string | No | Reject filenames matching the regular expression provided in this attribute, for example, `(jar\|exe)$`. | | `max_file_size` | integer | No | Maximum file size (MB) allowed. | | `member_check` | boolean | No | If `true`, allows only GitLab users to author commits. | | `prevent_secrets` | boolean | No | If `true`, rejects files that are likely to [contain secrets](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/checks/files_denylist.yml)
. | | `reject_non_dco_commits` | boolean | No | If `true`, rejects a commit when it’s not DCO certified. | | `reject_unsigned_commits` | boolean | No | If `true`, rejects a commit when it’s not signed. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author_email_regex` | string | Allow only commit author emails that match this regular expression. | | `branch_name_regex` | string | Allow only branch names that match this regular expression. | | `commit_committer_check` | boolean | If `true`, allows commits from users only if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | If `true`, allows commits from users only if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | Reject commit messages matching this regular expression. | | `commit_message_regex` | string | If `true`, allows only commit messages that match this regular expression. | | `created_at` | string | Date and time when the push rule was created. | | `deny_delete_tag` | boolean | If `true`, denies deleting a tag. | | `file_name_regex` | string | Reject filenames matching this regular expression. | | `id` | integer | The ID of the push rule. | | `max_file_size` | integer | Maximum file size (MB) allowed. | | `member_check` | boolean | If `true`, allows only GitLab users to author commits. | | `prevent_secrets` | boolean | If `true`, rejects files that are likely to contain secrets. | | `reject_non_dco_commits` | boolean | If `true`, rejects a commit when it’s not DCO certified. | | `reject_unsigned_commits` | boolean | If `true`, rejects a commit when it’s not signed. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/19/push_rule?member_check=true" Example response: { "id": 19, "created_at": "2020-08-31T15:53:00.073Z", "commit_committer_check": false, "commit_committer_name_check": false, "reject_unsigned_commits": false, "reject_non_dco_commits": false, "commit_message_regex": "[a-zA-Z]", "commit_message_negative_regex": "[x+]", "branch_name_regex": null, "deny_delete_tag": false, "member_check": true, "prevent_secrets": false, "author_email_regex": "^[A-Za-z0-9.]+@staging.gitlab.com$", "file_name_regex": null, "max_file_size": 100 } Delete the push rules of a group -------------------------------- Deletes all the push rules of a specified group. DELETE /groups/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) with no response body. Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/19/push_rule" --- # Heartbleed OpenSSL vulnerability | GitLab Docs * * * Heartbleed OpenSSL vulnerability ================================ Description ----------- Check for Heartbleed OpenSSL vulnerability. Remediation ----------- The Heartbleed vulnerability is a serious bug in the popular OpenSSL cryptographic library. OpenSSL is used to encrypt and decrypt communications and secure the Internet traffic. This vulnerability allows the attacker to steal protected information, which should not be accessible under other circumstance such as secret keys that are used to encrypt sensitive information. Anyone on with access to the target API can use the Heartbleed vulnerability to read the memory from protected systems taking advantage of vulnerable versions of OpenSSL library. Links ----- * [OWASP](https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components/) * [CWE](https://cwe.mitre.org/data/definitions/119.html) --- # Group release API | GitLab Docs * * * Group release API ================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/351703) in GitLab 14.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `group_releases_finder_inoperator`. Disabled by default. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/355463) in GitLab 15.0. Feature flag `group_releases_finder_inoperator` removed. Use this API to interact with [projects releases](https://docs.gitlab.com/user/project/releases/) in groups. To interact with project releases directly, see the [project release API](https://docs.gitlab.com/api/releases/) . List all releases in a group ---------------------------- Lists all releases for projects in a specified group. GET /groups/:id/releases GET /groups/:id/releases?simple=true Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `sort` | string | no | The direction of the order. Possible values: `desc` or `asc`. | | `simple` | boolean | no | If `true`, only returns limited fields for each release. | curl --header "PRIVATE-TOKEN: " --url "https://gitlab.example.com/api/v4/groups/5/releases" Example response: [\ {\ "name": "standard release",\ "tag_name": "releasetag",\ "description": "",\ "created_at": "2022-01-10T15:23:15.529Z",\ "released_at": "2022-01-10T15:23:15.529Z",\ "author": {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",\ "web_url": "https://gitlab.com/root"\ },\ "commit": {\ "id": "e8cbb845ae5a53a2fef2938cf63cf82efc10d993",\ "short_id": "e8cbb845",\ "created_at": "2022-01-10T15:20:29.000+00:00",\ "parent_ids": [],\ "title": "Update test",\ "message": "Update test",\ "author_name": "Administrator",\ "author_email": "admin@example.com",\ "authored_date": "2022-01-10T15:20:29.000+00:00",\ "committer_name": "Administrator",\ "committer_email": "admin@example.com",\ "committed_date": "2022-01-10T15:20:29.000+00:00",\ "trailers": {},\ "web_url": "https://gitlab.com/groups/gitlab-org/-/commit/e8cbb845ae5a53a2fef2938cf63cf82efc10d993"\ },\ "upcoming_release": false,\ "commit_path": "/testgroup/test/-/commit/e8cbb845ae5a53a2fef2938cf63cf82efc10d993",\ "tag_path": "/testgroup/test/-/tags/testtag"\ }\ ] --- # Group security settings API | GitLab Docs * * * Group security settings API =========================== * Tier: Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/502827) in GitLab 17.7. Every API call to group security settings must be [authenticated](https://docs.gitlab.com/api/rest/authentication/) . If a user isn’t a member of a private group, requests to the private group return a `404 Not Found` status code. Update group security settings ------------------------------ Updates group security settings for a specified group. Prerequisites: * You must have the Security Manager, Maintainer or Owner role for the group. PUT /groups/:id/security_settings | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a group. | | `secret_push_protection_enabled` | boolean | Yes | Enables secret push protection for projects in the group. | | `projects_to_exclude` | array of integers | No | IDs of projects to exclude from secret push protection. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/7/security_settings?secret_push_protection_enabled=true&projects_to_exclude[]=1&projects_to_exclude[]=2" Example response: { "secret_push_protection_enabled": true, "errors": [] } --- # Insecure HTTP methods | GitLab Docs * * * Insecure HTTP methods ===================== Description ----------- Checks to see if HTTP methods like OPTIONS and TRACE are enabled on any target endpoints. Remediation ----------- The resource tested supports the OPTIONS HTTP method. Usually, this is considered a security misconfiguration as it leaks supported HTTP methods leading to information gathering about a specific server or resource. However, there is a sub-set of the API community looking to use OPTIONS as a method to self discover resource operations. If this is the intended use for enabling OPTIONS, then this issue can be considered a false positive. The resource tested supports the TRACE HTTP method. In combination with other cross-domain vulnerabilities in web browsers, sensitive information can be leaked from headers. It’s recommended the TRACE method be disabled in your server/framework. Links ----- * [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration/) * [CWE](https://cwe.mitre.org/data/definitions/200.html) --- # Helm API | GitLab Docs * * * Helm API ======== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with [Helm package clients](https://docs.gitlab.com/user/packages/helm_repository/) . This API is used by the Helm-related package clients such as [Helm](https://helm.sh/) and [`helm-push`](https://github.com/chartmuseum/helm-push/#readme) , and is generally not meant for manual consumption. These endpoints do not adhere to the standard API authentication methods. See the [Helm registry documentation](https://docs.gitlab.com/user/packages/helm_repository/) for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future. Download a chart index ---------------------- To ensure consistent chart download URLs, the `contextPath` field in `index.yaml` responses always uses the numeric project ID, whether you access the API with the project ID or the full project path. Downloads a specified chart index for a project. GET projects/:id/packages/helm/:channel/index.yaml | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `channel` | string | yes | Helm repository channel. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/index.yaml" Write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/index.yaml" \ --remote-name Download a chart ---------------- Downloads a specified chart for a project. GET projects/:id/packages/helm/:channel/charts/:file_name.tgz | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `channel` | string | yes | Helm repository channel. | | `file_name` | string | yes | Chart filename. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/helm/stable/charts/mychart.tgz" \ --remote-name Upload a chart -------------- Uploads a specified chart for a project. POST projects/:id/packages/helm/api/:channel/charts | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `channel` | string | yes | Helm repository channel. | | `chart` | file | yes | Chart (as `multipart/form-data`). | curl --request POST \ --form 'chart=@mychart.tgz' \ --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/helm/api/stable/charts" --- # Group relations export API | GitLab Docs * * * Group relations export API ========================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated This API is used by the destination instance during [group migration by direct transfer](https://docs.gitlab.com/user/group/import/) to migrate a group structure. You don’t usually need to use this API yourself. In this context, a ​ is an exportable item such as an epic. When exported, the relation includes any items related to the relation such as a label. If you want to use this API, your GitLab instance must meet certain [prerequisites](https://docs.gitlab.com/user/group/import/direct_transfer_migrations/#prerequisites) . This API can’t be used with the [group import and export API](https://docs.gitlab.com/api/group_import_export/) , which is for file-based migration. Schedule a new export for a group --------------------------------- Schedules a relations export for a specified group. POST /groups/:id/export_relations | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | Integer or string | Yes | ID of the group. | | `batched` | Boolean | No | Whether to export in batches. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/export_relations" { "message": "202 Accepted" } Retrieve the status of an export -------------------------------- Retrieve the status of a relations export. GET /groups/:id/export_relations/status | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | Integer or string | Yes | ID of the group. | | `relation` | String | No | Name of the project top-level relation to view. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/export_relations/status" The status can be one of the following: * `0`: `started` * `1`: `finished` * `-1`: `failed` [\ {\ "relation": "badges",\ "status": 1,\ "error": null,\ "updated_at": "2021-05-04T11:25:20.423Z",\ "batched": true,\ "batches_count": 1,\ "batches": [\ {\ "status": 1,\ "batch_number": 1,\ "objects_count": 1,\ "error": null,\ "updated_at": "2021-05-04T11:25:20.423Z"\ }\ ]\ },\ {\ "relation": "boards",\ "status": 1,\ "error": null,\ "updated_at": "2021-05-04T11:25:20.085Z",\ "batched": false,\ "batches_count": 0\ }\ ] Download an export ------------------ Download the finished relations export. GET /groups/:id/export_relations/download | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | Integer or string | Yes | ID of the group. | | `relation` | String | Yes | Name of the group top-level relation to download. | | `batched` | Boolean | No | Whether the export is batched. | | `batch_number` | Integer | No | Number of export batch to download. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --remote-header-name \ --remote-name "https://gitlab.example.com/api/v4/groups/1/export_relations/download?relation=labels" ls labels.ndjson.gz labels.ndjson.gz Related topics -------------- * [Project relations export API](https://docs.gitlab.com/api/project_relations_export/) --- # Group-level protected branches API | GitLab Docs * * * Group-level protected branches API ================================== * Tier: Premium, Ultimate * Offering: GitLab Self-Managed History * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/500250) in GitLab 17.6. Feature flag `group_protected_branches` removed. Use this API to manage [protected branch settings](https://docs.gitlab.com/user/project/repository/branches/protected/#in-a-group) . Use this API to manage [protected branch settings](https://docs.gitlab.com/user/project/repository/branches/protected/#in-a-group) that are inherited by all projects in a group. Group protected branches only support [valid access levels](https://docs.gitlab.com/api/group_protected_branches/#valid-access-levels) . Individual users and groups cannot be specified. Protected branch settings for groups are restricted to top-level groups only. Valid access levels ------------------- The access levels are defined in the `ProtectedRefAccess.allowed_access_levels` method. These levels are recognized: 0 => No access 30 => Developer access 40 => Maintainer access 60 => Admin access List protected branches ----------------------- Gets a list of protected branches from a group. If a wildcard is set, it is returned instead of the exact name of the branches that match that wildcard. GET /groups/:id/protected_branches | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `search` | string | no | Name or part of the name of protected branches to be searched for. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_branches" Example response: [\ {\ "id": 1,\ "name": "main",\ "push_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ],\ "merge_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ],\ "allow_force_push":false,\ "code_owner_approval_required": false\ },\ {\ "id": 1,\ "name": "release/*",\ "push_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ],\ "merge_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ],\ "allow_force_push":false,\ "code_owner_approval_required": false\ },\ ...\ ] Get a single protected branch or wildcard protected branch ---------------------------------------------------------- Gets a single protected branch or wildcard protected branch. GET /groups/:id/protected_branches/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `name` | string | yes | The name of the branch or wildcard. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_branches/main" Example response: { "id": 1, "name": "main", "push_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "merge_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } Protect repository branches --------------------------- Protects a single repository branch using a wildcard protected branch. POST /groups/:id/protected_branches curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_branches?name=*-stable&push_access_level=30&merge_access_level=30&unprotect_access_level=40" | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `name` | string | yes | The name of the branch or wildcard. | | `allow_force_push` | boolean | no | Allow all users with push access to force push. Default: `false`. | | `allowed_to_merge` | array | no | Array of access levels allowed to merge, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. | | `allowed_to_push` | array | no | Array of access levels allowed to push, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. | | `allowed_to_unprotect` | array | no | Array of access levels allowed to unprotect, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. | | `code_owner_approval_required` | boolean | no | Prevent pushes to this branch if it matches an item in the [`CODEOWNERS` file](https://docs.gitlab.com/user/project/codeowners/)
. Default: `false`. | | `merge_access_level` | integer | no | Access levels allowed to merge. Defaults: `40`, Maintainer role. | | `push_access_level` | integer | no | Access levels allowed to push. Defaults: `40`, Maintainer role. | | `unprotect_access_level` | integer | no | Access levels allowed to unprotect. Defaults: `40`, Maintainer role. | Example response: { "id": 1, "name": "*-stable", "push_access_levels": [\ {\ "id": 1,\ "access_level": 30,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Developers + Maintainers"\ }\ ], "merge_access_levels": [\ {\ "id": 1,\ "access_level": 30,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Developers + Maintainers"\ }\ ], "unprotect_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } ### Example with access levels Use access levels to configure group protected branches: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "name": "main", "allowed_to_push": [{"access_level": 30}], "allowed_to_merge": [{\ "access_level": 30\ },{\ "access_level": 40\ }\ ]}' --url "https://gitlab.example.com/api/v4/groups/5/protected_branches" Example response: { "id": 5, "name": "main", "push_access_levels": [\ {\ "id": 1,\ "access_level": 30,\ "access_level_description": "Developers + Maintainers",\ "user_id": null,\ "group_id": null\ }\ ], "merge_access_levels": [\ {\ "id": 1,\ "access_level": 30,\ "access_level_description": "Developers + Maintainers",\ "user_id": null,\ "group_id": null\ },\ {\ "id": 2,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ], "unprotect_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } Unprotect repository branches ----------------------------- Unprotects the given protected branch or wildcard protected branch. DELETE /groups/:id/protected_branches/:name curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_branches/*-stable" | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `name` | string | yes | The name of the branch. | Example response: { "name": "main", "push_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ] } Update a protected branch ------------------------- Updates a protected branch. PATCH /groups/:id/protected_branches/:name curl --request PATCH \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_branches/feature-branch?allow_force_push=true&code_owner_approval_required=true" | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `name` | string | yes | The name of the branch. | | `allow_force_push` | boolean | no | When enabled, members who can push to this branch can also force push. | | `allowed_to_push` | array | no | Array of push access levels, with each described by a hash. | | `allowed_to_merge` | array | no | Array of merge access levels, with each described by a hash. | | `allowed_to_unprotect` | array | no | Array of unprotect access levels, with each described by a hash. | | `code_owner_approval_required` | boolean | no | Prevent pushes to this branch if it matches an item in the [`CODEOWNERS` file](https://docs.gitlab.com/user/project/codeowners/)
. Default: `false`. | Elements in the `allowed_to_push`, `allowed_to_merge` and `allowed_to_unprotect` arrays should take the form `{access_level: integer}`. Each access level must be a valid value from the [valid access levels](https://docs.gitlab.com/api/group_protected_branches/#valid-access-levels) . * To update access levels, you must also pass the `id` of the `access_level` in the respective hash. * To delete access levels, you must pass `_destroy` set to `true`. See the following examples. ### Example: create a `push_access_level` record curl --header 'Content-Type: application/json' --request PATCH \ --data '{"allowed_to_push": [{access_level: 40}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_branches/main" Example response: { "name": "main", "push_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ] } ### Example: update a `push_access_level` record curl --header 'Content-Type: application/json' --request PATCH \ --data '{"allowed_to_push": [{"id": 12, "access_level": 0}]' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_branches/main" Example response: { "name": "main", "push_access_levels": [\ {\ "id": 12,\ "access_level": 0,\ "access_level_description": "No One",\ "user_id": null,\ "group_id": null\ }\ ] } ### Example: delete a `push_access_level` record curl --header 'Content-Type: application/json' --request PATCH \ --data '{"allowed_to_push": [{"id": 12, "_destroy": true}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_branches/main" Example response: { "name": "main", "push_access_levels": [] } --- # Group-level Variables API | GitLab Docs * * * Group-level Variables API ========================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * Introduced [`filter`](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9. Use this API to interact with [CI/CD variables](https://docs.gitlab.com/ci/variables/#for-a-group) for a group. Prerequisites: * You must have the Owner role for the group. List all group variables ------------------------ Lists all variables for a specified group. Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. GET /groups/:id/variables | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID of a group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables" [\ {\ "key": "TEST_VARIABLE_1",\ "variable_type": "env_var",\ "value": "TEST_1",\ "protected": false,\ "masked": false,\ "hidden": false,\ "raw": false,\ "environment_scope": "*",\ "description": null\ },\ {\ "key": "TEST_VARIABLE_2",\ "variable_type": "env_var",\ "value": "TEST_2",\ "protected": false,\ "masked": false,\ "hidden": false,\ "raw": false,\ "environment_scope": "*",\ "description": null\ }\ ] Retrieve details of a group variable ------------------------------------ History * The `filter` parameter was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9. Retrieves details of a specified group variable. If there are multiple variables with the same key, use `filter` to select the correct `environment_scope`. GET /groups/:id/variables/:key | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID of a group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | string | Yes | Key of a variable. | | `filter` | hash | No | Filters results when multiple variables share the same key. Possible values: `[environment_scope]`. Premium and Ultimate only. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables/TEST_VARIABLE_1" { "key": "TEST_VARIABLE_1", "variable_type": "env_var", "value": "TEST_1", "protected": false, "masked": false, "hidden": false, "raw": false, "environment_scope": "*", "description": null } Example request with `filter`: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables/SCOPED_VARIABLE_1" \ --form "filter[environment_scope]=production" Create a group variable ----------------------- History * `masked_and_hidden` and `hidden` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29674) in GitLab 17.4. Creates a group variable. POST /groups/:id/variables | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID of a group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | string | Yes | The `key` of a variable. Maximum 255 characters. Only `A-Z`, `a-z`, `0-9`, and `_` are allowed. | | `value` | string | Yes | The `value` of a variable. | | `description` | string | No | The `description` of the variable. Maximum 255 characters. Default: `null`. | | `environment_scope` | string | No | The [environment scope](https://docs.gitlab.com/ci/environments/#limit-the-environment-scope-of-a-cicd-variable)
of a variable. Premium and Ultimate only. | | `masked` | boolean | No | Whether the variable is masked. | | `masked_and_hidden` | boolean | No | Whether the variable is masked and hidden. Default: `false` | | `protected` | boolean | No | Whether the variable is protected. | | `raw` | boolean | No | Whether the variable is treated as a raw string. Default: `true`. When `false`, variables in the value are [expanded](https://docs.gitlab.com/ci/variables/#allow-cicd-variable-expansion)
. | | `variable_type` | string | No | The type of a variable. Available types are: `env_var` (default) and `file`. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables" \ --form "key=NEW_VARIABLE" \ --form "value=new value" { "key": "NEW_VARIABLE", "value": "new value", "variable_type": "env_var", "protected": false, "masked": false, "hidden": false, "raw": false, "environment_scope": "*", "description": null } Update a group variable ----------------------- History * The `filter` parameter was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9. Updates the specified group variable. If there are multiple variables with the same key, use `filter` to select the correct `environment_scope`. When filtering for an `environment_scope` that does not exist, the endpoint falls back to updating a variable with the same name but different environment scope. Verify the existence of a scope for a given variable using the [retrieve details of a group variable](https://docs.gitlab.com/api/group_level_variables/#retrieve-details-of-a-group-variable) endpoint. PUT /groups/:id/variables/:key | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID of a group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | string | Yes | Key of a variable. | | `value` | string | Yes | Value of a variable. | | `description` | string | No | Description of the variable. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/409641)
in GitLab 16.2. Default: `null`. | | `environment_scope` | string | No | [Environment scope](https://docs.gitlab.com/ci/environments/#limit-the-environment-scope-of-a-cicd-variable)
of a variable. Premium and Ultimate only. | | `filter` | hash | No | Filters results when multiple variables share the same key. Possible values: `[environment_scope]`. Premium and Ultimate only. | | `masked` | boolean | No | If `true`, indicates the variable is masked. | | `protected` | boolean | No | If `true`, indicates the variable is protected. | | `raw` | boolean | No | If `true`, indicates the variable is treated as a raw string. When `false`, the variable value is [expanded](https://docs.gitlab.com/ci/variables/#allow-cicd-variable-expansion)
. Default: `true`. | | `variable_type` | string | No | Type of a variable. Available types are: `env_var` (default) and `file`. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables/NEW_VARIABLE" \ --form "value=updated value" { "key": "NEW_VARIABLE", "value": "updated value", "variable_type": "env_var", "protected": true, "masked": true, "hidden": false, "raw": true, "environment_scope": "*", "description": null } Example request with `filter`: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables/SCOPED_VARIABLE_1" \ --form "value=updated value" \ --form "environment_scope=production" \ --form "filter[environment_scope]=production" Delete a group variable ----------------------- History * The `filter` parameter was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9. Deletes the specified group variable. If there are multiple variables with the same key, use `filter` to select the correct `environment_scope`. DELETE /groups/:id/variables/:key | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID of a group or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | string | Yes | Key of a variable. | | `filter` | hash | No | Filters results when multiple variables share the same key. Possible values: `[environment_scope]`. Premium and Ultimate only. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables/VARIABLE_1" Example request with `filter`: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/variables/SCOPED_VARIABLE_1" \ --form "filter[environment_scope]=production" --- # Group wikis API | GitLab Docs * * * Group wikis API =============== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [group wikis](https://docs.gitlab.com/user/project/wiki/group/) . An API for [project wikis](https://docs.gitlab.com/api/wikis/) is also available. Comments on a wiki page are called `notes`. To interact with them, use the [notes API](https://docs.gitlab.com/api/notes/#group-wikis) . List wiki pages --------------- Lists all wiki pages for a specified group. GET /groups/:id/wikis | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `with_content` | boolean | No | Include pages’ content. | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/wikis?with_content=1" Example response: [\ {\ "content" : "Here is an instruction how to deploy this project.",\ "format" : "markdown",\ "slug" : "deploy",\ "title" : "deploy",\ "encoding": "UTF-8"\ },\ {\ "content" : "Our development process is described here.",\ "format" : "markdown",\ "slug" : "development",\ "title" : "development",\ "encoding": "UTF-8"\ },{\ "content" : "* [Deploy](deploy)\n* [Development](development)",\ "format" : "markdown",\ "slug" : "home",\ "title" : "home",\ "encoding": "UTF-8"\ }\ ] Retrieve a wiki page -------------------- Retrieves a wiki page for a specified group. GET /groups/:id/wikis/:slug | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `slug` | string | Yes | URL-encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name`. | | `render_html` | boolean | No | Return the rendered HTML of the wiki page. | | `version` | string | No | Wiki page version SHA. | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/wikis/home" Example response: { "content" : "home page", "format" : "markdown", "slug" : "home", "title" : "home", "encoding": "UTF-8" } Create a wiki page ------------------ Creates a wiki page for a specific project with the given title, slug, and content. POST /projects/:id/wikis | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `content` | string | Yes | The content of the wiki page. | | `title` | string | Yes | The title of the wiki page. | | `format` | string | No | The format of the wiki page. Available formats are: `markdown` (default), `rdoc`, `asciidoc`, and `org`. | curl --request POST \ --data "format=rdoc&title=Hello&content=Hello world" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/wikis" Example response: { "content" : "Hello world", "format" : "markdown", "slug" : "Hello", "title" : "Hello", "encoding": "UTF-8" } Update a wiki page ------------------ Updates a wiki page. At least one parameter is required to update the wiki page. PUT /groups/:id/wikis/:slug | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `content` | string | Yes, if `title` is not provided | The content of the wiki page. | | `title` | string | Yes, if `content` is not provided | The title of the wiki page. | | `format` | string | No | The format of the wiki page. Available formats are `markdown` (default), `rdoc`, `asciidoc`, and `org`. | | `slug` | string | Yes | URL encoded slug (a unique string) of the wiki page. For example: `dir%2Fpage_name`. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/wikis/foo" \ --data "format=rdoc" \ --data "title=Docs" \ --data "content=documentation" Example response: { "content" : "documentation", "format" : "markdown", "slug" : "Docs", "title" : "Docs", "encoding": "UTF-8" } Delete a wiki page ------------------ Deletes a wiki page from a specific project with a specified slug. DELETE /groups/:id/wikis/:slug | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `slug` | string | Yes | URL-encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name`. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/wikis/foo" If successful, a `204 No Content` HTTP response with an empty body is expected. Upload an attachment to the wiki repository ------------------------------------------- Uploads a file to the attachment folder inside the wiki’s repository for a specific project. The attachment folder is the `uploads` folder. POST /groups/:id/wikis/attachments | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `file` | string | Yes | The attachment to be uploaded. | | `branch` | string | No | The name of the branch. Defaults to the wiki repository default branch. | To upload a file from your file system, use the `--form` argument. This causes cURL to post data using the header `Content-Type: multipart/form-data`. The `file=` parameter must point to a file on your file system and be preceded by `@`. For example: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/wikis/attachments" \ --form "file=@dk.png" Example response: { "file_name" : "dk.png", "file_path" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png", "branch" : "main", "link" : { "url" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png", "markdown" : "![dk](uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png)" } } --- # Group-level protected environments API | GitLab Docs * * * Group-level protected environments API ====================================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215888) in GitLab 14.0. [Deployed behind the `group_level_protected_environments` flag](https://docs.gitlab.com/administration/feature_flags/) , disabled by default. * [Feature flag `group_level_protected_environments`](https://gitlab.com/gitlab-org/gitlab/-/issues/331085) removed in GitLab 14.3. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/331085) in GitLab 14.3. Use this API to interact with [group-level protected environments](https://docs.gitlab.com/ci/environments/protected_environments/#group-level-protected-environments) . For protected environments, see [protected environments API](https://docs.gitlab.com/api/protected_environments/) Valid access levels ------------------- The access levels are defined in the `ProtectedEnvironments::DeployAccessLevel::ALLOWED_ACCESS_LEVELS` method. Currently, these levels are recognized: 30 => Developer access 40 => Maintainer access 60 => Admin access List all group-level protected environments ------------------------------------------- Lists all protected environments for a specified group. GET /groups/:id/protected_environments | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group maintained by the authenticated user. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_environments/" Example response: [\ {\ "name":"production",\ "deploy_access_levels":[\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ],\ "required_approval_count": 0\ }\ ] Retrieve a single protected environment --------------------------------------- Retrieves a specified protected environment from a group. GET /groups/:id/protected_environments/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group maintained by the authenticated user. | | `name` | string | yes | The [deployment tier](https://docs.gitlab.com/ci/environments/#deployment-tier-of-environments)
of the protected environment. Possible values: `production`, `staging`, `testing`, `development`, or `other`. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_environments/production" Example response: { "name":"production", "deploy_access_levels":[\ {\ "id": 12,\ "access_level":40,\ "access_level_description":"Maintainers",\ "user_id":null,\ "group_id":null\ }\ ], "required_approval_count": 0 } Protect a single environment ---------------------------- Protects a single environment. POST /groups/:id/protected_environments | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group maintained by the authenticated user. | | `name` | string | yes | The [deployment tier](https://docs.gitlab.com/ci/environments/#deployment-tier-of-environments)
of the protected environment. Possible values: `production`, `staging`, `testing`, `development`, or `other`. | | `deploy_access_levels` | array | yes | Array of access levels allowed to deploy, with each described by a hash. Possible values: `user_id`, `group_id` or `access_level`. They take the form of `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}`. | | `approval_rules` | array | no | Array of access levels allowed to approve, with each described by a hash. Possible values: `user_id`, `group_id` or `access_level`. They take the form of `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}`. You can also specify the number of required approvals from the specified entity with `required_approvals` field. See [Multiple approval rules](https://docs.gitlab.com/ci/environments/deployment_approvals/#add-multiple-approval-rules)
for more information. | The assignable `user_id` are the users who belong to the given group with the Maintainer role (or above). The assignable `group_id` are the subgroups under the given group. curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_environments" \ --data '{"name": "production", "deploy_access_levels": [{"group_id": 9899826}]}' Example response: { "name":"production", "deploy_access_levels":[\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "protected-access-group",\ "user_id": null,\ "group_id": 9899826\ }\ ], "required_approval_count": 0 } An example with multiple approval rules: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/128/protected_environments" \ --data '{ "name": "production", "deploy_access_levels": [{"group_id": 138}], "approval_rules": [\ {"group_id": 134},\ {"group_id": 135, "required_approvals": 2}\ ] }' In this configuration, the operator group `"group_id": 138` can execute the deployment job to `production` only after the QA group `"group_id": 134` and security group `"group_id": 135` have approved the deployment. Update a protected environment ------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/351854) in GitLab 15.4. Updates a single environment. PUT /groups/:id/protected_environments/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group maintained by the authenticated user. | | `name` | string | yes | The [deployment tier](https://docs.gitlab.com/ci/environments/#deployment-tier-of-environments)
of the protected environment. Possible values: `production`, `staging`, `testing`, `development`, or `other`. | | `deploy_access_levels` | array | no | Array of access levels allowed to deploy, with each described by a hash. Possible values: `user_id`, `group_id` or `access_level`. They take the form of `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}`. | | `required_approval_count` | integer | no | The number of approvals required to deploy to this environment. | | `approval_rules` | array | no | Array of access levels allowed to approve, with each described by a hash. Possible values: `user_id`, `group_id`, or `access_level`. They take the form of `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. You can also specify the number of required approvals from the specified entity with `required_approvals` field. See [Multiple approval rules](https://docs.gitlab.com/ci/environments/deployment_approvals/#add-multiple-approval-rules)
for more information. | To update: * **`user_id`**: Ensure the updated user belongs to the given group with the Maintainer role (or above). You must also pass the `id` of either a `deploy_access_level` or `approval_rule` in the respective hash. * **`group_id`**: Ensure the updated group is a subgroup of the group this protected environment belongs to. You must also pass the `id` of either a `deploy_access_level` or `approval_rule` in the respective hash. To delete: * You must pass `_destroy` set to `true`. See the following examples. ### Example: Create a `deploy_access_level` record curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_environments/production" \ --data '{"deploy_access_levels": [{"group_id": 9899829, "access_level": 40}]}' Example response: { "name": "production", "deploy_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "protected-access-group",\ "user_id": null,\ "group_id": 9899829,\ "group_inheritance_type": 1\ }\ ], "required_approval_count": 0 } ### Example: Update a `deploy_access_level` record curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_environments/production" \ --data '{"deploy_access_levels": [{"id": 12, "group_id": 22034120}]}' { "name": "production", "deploy_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "protected-access-group",\ "user_id": null,\ "group_id": 22034120,\ "group_inheritance_type": 0\ }\ ], "required_approval_count": 2 } ### Example: Delete a `deploy_access_level` record curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_environments/production" \ --data '{"deploy_access_levels": [{"id": 12, "_destroy": true}]}' Example response: { "name": "production", "deploy_access_levels": [], "required_approval_count": 0 } ### Example: Create an `approval_rule` record curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_environments/production" \ --data '{"approval_rules": [{"group_id": 134, "required_approvals": 1}]}' Example response: { "name": "production", "approval_rules": [\ {\ "id": 38,\ "user_id": null,\ "group_id": 134,\ "access_level": null,\ "access_level_description": "qa-group",\ "required_approvals": 1,\ "group_inheritance_type": 0\ }\ ] } ### Example: Update an `approval_rule` record curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_environments/production" \ --data '{"approval_rules": [{"id": 38, "group_id": 135, "required_approvals": 2}]}' { "name": "production", "approval_rules": [\ {\ "id": 38,\ "user_id": null,\ "group_id": 135,\ "access_level": null,\ "access_level_description": "security-group",\ "required_approvals": 2,\ "group_inheritance_type": 0\ }\ ] } ### Example: Delete an `approval_rule` record curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/groups/22034114/protected_environments/production" \ --data '{"approval_rules": [{"id": 38, "_destroy": true}]}' Example response: { "name": "production", "approval_rules": [] } Unprotect a single environment ------------------------------ Unprotects the given protected environment. DELETE /groups/:id/protected_environments/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group maintained by the authenticated user. | | `name` | string | yes | The [deployment tier](https://docs.gitlab.com/ci/environments/#deployment-tier-of-environments)
of the protected environment. Possible values: `production`, `staging`, `testing`, `development`, or `other`. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/protected_environments/staging" The response should return a 200 code. --- # JSON injection | GitLab Docs * * * JSON injection ============== Description ----------- Check for JSON serialization/injection vulnerabilities. Remediation ----------- JSON injection is an attack technique used to manipulate or compromise the logic of a JSON application or service. The injection of unintended JSON content and/or structures into an JSON message can alter the intend logic of the application. Further, JSON injection can cause the insertion of malicious content into the resulting message/document. Links ----- * [OWASP](https://owasp.org/Top10/A03_2021-Injection/) * [CWE](https://cwe.mitre.org/data/definitions/929.html) --- # JSON hijacking | GitLab Docs * * * JSON hijacking ============== Description ----------- Checks for JSON data potentially vulnerable to hijacking. This check looks for a GET request that returns a JSON array, which could potentially be hijacked and read by a malicious website. Remediation ----------- JSON hijacking allows an attacker to send a GET request via a malicious web site or similar attack vector and utilize a user’s stored credentials to retrieve sensitive or protected data to which that user has access. A JSON array on its own is valid JavaScript, so a malicious GET request to a resource that returns only a JavaScript array can allow the attacker to use a malicious script to read the data in the array from the request. GET requests should never return a JSON array, even if the resource requires authentication to access. Consider using POST instead of a GET for this request or wrapping the array in a JSON object. Links ----- * [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control/) * [CWE](https://cwe.mitre.org/data/definitions/352.html) --- # Interactive API documentation | GitLab Docs * * * Interactive API documentation ============================= The [OpenAPI specification](https://swagger.io/specification/) (formerly called Swagger) defines a standard, language-agnostic interface to RESTful APIs. OpenAPI definition files are written in the YAML format, which is automatically rendered by the GitLab browser into a more human-readable interface. For general information about the GitLab APIs, see [Extend with GitLab](https://docs.gitlab.com/api/) . The [interactive API documentation tool](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/api/openapi/openapi_v2.yaml) allows API testing directly on the GitLab.com website. Only a few of the available endpoints are documented with the OpenAPI spec, but the current list demonstrates the functionality of the tool. [![A list of some available GitLab API endpoints.](https://docs.gitlab.com/api/openapi/img/apiviewer01-fs8_v13_9.png)](https://docs.gitlab.com/api/openapi/img/apiviewer01-fs8_v13_9.png) Endpoint parameters ------------------- When you expand an endpoint listing, you see a description, input parameters (if required), and example server responses. Some parameters include a default or a list of allowed values. [![An expanded view that displays the endpoint information and the try it out option.](https://docs.gitlab.com/api/openapi/img/apiviewer04-fs8_v13_9.png)](https://docs.gitlab.com/api/openapi/img/apiviewer04-fs8_v13_9.png) Starting an interactive session ------------------------------- A [personal access token](https://docs.gitlab.com/user/profile/personal_access_tokens/) (PAT) is one way to start an interactive session. To do this, select **Authorize** from the main page, and a dialog prompts you to enter your PAT, which is valid for the current web session. To test the endpoint, first select **Try it out** on the endpoint definition page. Input the parameters as required, then select **Execute**. The following example executes a request for the `version` endpoint (no parameters required). The tool shows the `curl` command and URL of the request, followed by the server responses that are returned. You can create new responses by editing the relevant parameters and then select **Execute** once again. [![The endpoint test view that includes the request and response.](https://docs.gitlab.com/api/openapi/img/apiviewer03-fs8_v13_9.png)](https://docs.gitlab.com/api/openapi/img/apiviewer03-fs8_v13_9.png) Vision ------ The API code is the single source of truth, and the API documentation should be tightly coupled to its implementation. The OpenAPI specification provides a standardized and comprehensive way to document APIs. It should be the go-to format for documenting the GitLab REST API. This will result in more accurate, reliable, and user-friendly documentation that enhances the overall experience of using the GitLab REST API. To achieve this it should be a requirement to update the OpenAPI specification with every API code change. Doing so ensures that the documentation is always up-to-date and accurate, reducing the risk of confusion as well as errors for users. The OpenAPI documentation should be autogenerated from the API code, so that it is easy to keep it up to date and accurate. This will save time and effort for our documentation team. You can follow the current progress of this vision in the [Document the REST API in OpenAPI V2 epic](https://gitlab.com/groups/gitlab-org/-/epics/8926) . --- # Instance clusters API (certificate-based) (deprecated) | GitLab Docs * * * Instance clusters API (certificate-based) (deprecated) ====================================================== * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. With [instance-level Kubernetes clusters](https://docs.gitlab.com/user/instance/clusters/) , you can connect a Kubernetes cluster to the GitLab instance and use the same cluster across all of the projects within your instance. Users need administrator access to use these endpoints. List instance clusters ---------------------- Lists all instance clusters. GET /admin/clusters Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/admin/clusters" Example response: [\ {\ "id": 9,\ "name": "cluster-1",\ "created_at": "2020-07-14T18:36:10.440Z",\ "managed": true,\ "enabled": true,\ "domain": null,\ "provider_type": "user",\ "platform_type": "kubernetes",\ "environment_scope": "*",\ "cluster_type": "instance_type",\ "user": {\ "id": 1,\ "name": "Administrator",\ "username": "root",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/root"\ },\ "platform_kubernetes": {\ "api_url": "https://example.com",\ "namespace": null,\ "authorization_type": "rbac",\ "ca_cert":"-----BEGIN CERTIFICATE-----IxMDM1MV0ZDJkZjM...-----END CERTIFICATE-----"\ },\ "provider_gcp": null,\ "management_project": null\ },\ {\ "id": 10,\ "name": "cluster-2",\ "created_at": "2020-07-14T18:39:05.383Z",\ "domain": null,\ "provider_type": "user",\ "platform_type": "kubernetes",\ "environment_scope": "staging",\ "cluster_type": "instance_type",\ "user": {\ "id": 1,\ "name": "Administrator",\ "username": "root",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/root"\ },\ "platform_kubernetes": {\ "api_url": "https://example.com",\ "namespace": null,\ "authorization_type": "rbac",\ "ca_cert":"-----BEGIN CERTIFICATE-----LzEtMCadtaLGxcsGAZjM...-----END CERTIFICATE-----"\ },\ "provider_gcp": null,\ "management_project": null\ },\ {\ "id": 11,\ "name": "cluster-3",\ ...\ }\ ] Retrieve a single instance cluster ---------------------------------- Retrieves a single instance cluster. Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `cluster_id` | integer | yes | The ID of the cluster | GET /admin/clusters/:cluster_id Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/admin/clusters/9" Example response: { "id": 9, "name": "cluster-1", "created_at": "2020-07-14T18:36:10.440Z", "managed": true, "enabled": true, "domain": null, "provider_type": "user", "platform_type": "kubernetes", "environment_scope": "*", "cluster_type": "instance_type", "user": { "id": 1, "name": "Administrator", "username": "root", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url": "https://example.com", "namespace": null, "authorization_type": "rbac", "ca_cert":"-----BEGIN CERTIFICATE-----IxMDM1MV0ZDJkZjM...-----END CERTIFICATE-----" }, "provider_gcp": null, "management_project": null } Create an instance cluster -------------------------- Creates an instance cluster by adding an existing Kubernetes cluster. POST /admin/clusters/add Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | The name of the cluster | | `domain` | string | no | The [base domain](https://docs.gitlab.com/user/project/clusters/gitlab_managed_clusters/#base-domain)
of the cluster | | `environment_scope` | string | no | The associated environment to the cluster. Defaults to `*` | | `management_project_id` | integer | no | The ID of the [management project](https://docs.gitlab.com/user/clusters/management_project/)
for the cluster | | `enabled` | boolean | no | Determines if cluster is active or not, defaults to `true` | | `managed` | boolean | no | Determines if GitLab manages namespaces and service accounts for this cluster. Defaults to `true` | | `platform_kubernetes_attributes[api_url]` | string | yes | The URL to access the Kubernetes API | | `platform_kubernetes_attributes[token]` | string | yes | The token to authenticate against Kubernetes | | `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. | | `platform_kubernetes_attributes[namespace]` | string | no | The unique namespace related to the project | | `platform_kubernetes_attributes[authorization_type]` | string | no | The cluster authorization type: `rbac`, `abac` or `unknown_authorization`. Defaults to `rbac`. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Accept: application/json" \ --header "Content-Type: application/json" \ --data '{"name":"cluster-3", "environment_scope":"production", "platform_kubernetes_attributes":{"api_url":"https://example.com", "token":"12345", "ca_cert":"-----BEGIN CERTIFICATE-----qpoeiXXZafCM0ZDJkZjM...-----END CERTIFICATE-----"}}' \ --url "http://gitlab.example.com/api/v4/admin/clusters/add" Example response: { "id": 11, "name": "cluster-3", "created_at": "2020-07-14T18:42:50.805Z", "managed": true, "enabled": true, "domain": null, "provider_type": "user", "platform_type": "kubernetes", "environment_scope": "production", "cluster_type": "instance_type", "user": { "id": 1, "name": "Administrator", "username": "root", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://gitlab.example.com:3000/root" }, "platform_kubernetes": { "api_url": "https://example.com", "namespace": null, "authorization_type": "rbac", "ca_cert":"-----BEGIN CERTIFICATE-----qpoeiXXZafCM0ZDJkZjM...-----END CERTIFICATE-----" }, "provider_gcp": null, "management_project": null } Update an instance cluster -------------------------- Updates an existing instance cluster. PUT /admin/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `cluster_id` | integer | yes | The ID of the cluster | | `name` | string | no | The name of the cluster | | `domain` | string | no | The [base domain](https://docs.gitlab.com/user/project/clusters/gitlab_managed_clusters/#base-domain)
of the cluster | | `environment_scope` | string | no | The associated environment to the cluster | | `management_project_id` | integer | no | The ID of the [management project](https://docs.gitlab.com/user/clusters/management_project/)
for the cluster | | `enabled` | boolean | no | Determines if cluster is active or not | | `managed` | boolean | no | Determines if GitLab manages namespaces and service accounts for this cluster | | `platform_kubernetes_attributes[api_url]` | string | no | The URL to access the Kubernetes API | | `platform_kubernetes_attributes[token]` | string | no | The token to authenticate against Kubernetes | | `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. | | `platform_kubernetes_attributes[namespace]` | string | no | The unique namespace related to the project | `name`, `api_url`, `ca_cert` and `token` can only be updated if the cluster was added through the [Add existing Kubernetes cluster](https://docs.gitlab.com/user/project/clusters/add_existing_cluster/) option or through the [Create an instance cluster](https://docs.gitlab.com/api/instance_clusters/#create-an-instance-cluster) endpoint. Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"name":"update-cluster-name", "platform_kubernetes_attributes":{"api_url":"https://new-example.com","token":"new-token"}}' \ --url "http://gitlab.example.com/api/v4/admin/clusters/9" Example response: { "id": 9, "name": "update-cluster-name", "created_at": "2020-07-14T18:36:10.440Z", "managed": true, "enabled": true, "domain": null, "provider_type": "user", "platform_type": "kubernetes", "environment_scope": "*", "cluster_type": "instance_type", "user": { "id": 1, "name": "Administrator", "username": "root", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url": "https://new-example.com", "namespace": null, "authorization_type": "rbac", "ca_cert":"-----BEGIN CERTIFICATE-----IxMDM1MV0ZDJkZjM...-----END CERTIFICATE-----" }, "provider_gcp": null, "management_project": null, "project": null } Delete instance cluster ----------------------- Deletes an existing instance cluster. Does not remove existing resources within the connected Kubernetes cluster. DELETE /admin/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `cluster_id` | integer | yes | The ID of the cluster | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/admin/clusters/11" --- # Identify issue boards by using GraphQL | GitLab Docs * * * Identify issue boards by using GraphQL ====================================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated You can identify [issue boards](https://docs.gitlab.com/user/project/issue_board/) for a project by using: * GraphiQL. * [`cURL`](https://docs.gitlab.com/api/graphql/getting_started/#command-line) . Use GraphiQL ------------ You can use GraphiQL to list the issue boards for a project. 1. Open GraphiQL: * For GitLab.com, use: `https://gitlab.com/-/graphql-explorer` * For GitLab Self-Managed, use: `https://gitlab.example.com/-/graphql-explorer` 2. Copy the following text and paste it in the left window. This query gets issue boards for the `docs-gitlab-com` repository. query { project(fullPath: "gitlab-org/technical-writing/docs-gitlab-com") { name forksCount statistics { wikiSize } issuesEnabled boards { nodes { id name } } } } 3. Select **Play**. To view one of these issue boards, copy a numeric identifier from the output. For example, if the identifier is `7174622`, use this URL to go to the issue board: https:/gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/boards/7174622 Related topics -------------- * [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) --- # HTML injection | GitLab Docs * * * HTML injection ============== Description ----------- Check for XSS via HTML injection into all fields that support strings. This includes portions of the HTTP request such as path, query, headers and also body parameters such as XML fields, JSON fields, etc. Detection is performed by monitoring responses for the injected value in to known HTML enabled fields. Remediation ----------- Cross-site scripting (XSS) is an attack technique that involves echoing attacker-supplied code into a user’s browser instance. A browser instance can be a standard web browser client, or a browser object embedded in a software product such as the browser within WinAmp, an RSS reader, or an email client. The code itself is usually written in HTML/JavaScript, but may also extend to VBScript, ActiveX, Java, Flash, or any other browser-supported technology. When an attacker gets a user’s browser to execute his/her code, the code will run within the security context (or zone) of the hosting web site. With this level of privilege, the code has the ability to read, modify and transmit any sensitive data accessible by the browser. A Cross-site Scripted user could have his/her account hijacked (cookie theft), their browser redirected to another location, or possibly shown fraudulent content delivered by the web site they are visiting. Cross-site Scripting attacks essentially compromise the trust relationship between a user and the web site. Applications utilizing browser object instances which load content from the file system may execute code under the local machine zone allowing for system compromise. There are three types of Cross-site Scripting attacks: non-persistent, persistent and DOM-based. Non-persistent attacks and DOM-based attacks require a user to either visit a specially crafted link laced with malicious code, or visit a malicious web page containing a web form, which when posted to the vulnerable site, will mount the attack. Using a malicious form will oftentimes take place when the vulnerable resource only accepts HTTP POST requests. In such a case, the form can be submitted automatically, without the victim’s knowledge (for example, by using JavaScript). Upon clicking on the malicious link or submitting the malicious form, the XSS payload will get echoed back and will get interpreted by the user’s browser and execute. Another technique to send almost arbitrary requests (GET and POST) is by using an embedded client, such as Adobe Flash. Persistent attacks occur when the malicious code is submitted to a web site where it’s stored for a period of time. Examples of an attacker’s favorite targets often include message board posts, web mail messages, and web chat software. The unsuspecting user is not required to interact with any additional site/link (for example, an attacker site or a malicious link sent via email), just simply view the web page containing the code. Links ----- * [OWASP](https://owasp.org/Top10/A03_2021-Injection/) * [CWE](https://cwe.mitre.org/data/definitions/79.html) --- # Issue links API | GitLab Docs * * * Issue links API =============== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * The simple “relates to” relationship [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212329) to GitLab Free in 13.4. Use this API to manage [issue links](https://docs.gitlab.com/user/project/issues/related_issues/) . List all issue links -------------------- Lists all [linked issues](https://docs.gitlab.com/user/project/issues/related_issues/) for a specified issue, sorted by the relationship creation datetime (ascending). Issues are filtered according to the user authorizations. GET /projects/:id/issues/:issue_iid/links Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `issue_iid` | integer | yes | The internal ID of a project’s issue | [\ {\ "id" : 84,\ "iid" : 14,\ "issue_link_id": 1,\ "project_id" : 4,\ "created_at" : "2016-01-07T12:44:33.959Z",\ "title" : "Issues with auth",\ "state" : "opened",\ "assignees" : [],\ "assignee" : null,\ "labels" : [\ "bug"\ ],\ "author" : {\ "name" : "Alexandra Bashirian",\ "avatar_url" : null,\ "state" : "active",\ "web_url" : "https://gitlab.example.com/eileen.lowe",\ "id" : 18,\ "username" : "eileen.lowe"\ },\ "description" : null,\ "updated_at" : "2016-01-07T12:44:33.959Z",\ "milestone" : null,\ "user_notes_count": 0,\ "due_date": null,\ "web_url": "http://example.com/example/example/issues/14",\ "confidential": false,\ "weight": null,\ "link_type": "relates_to",\ "link_created_at": "2016-01-07T12:44:33.959Z",\ "link_updated_at": "2016-01-07T12:44:33.959Z"\ }\ ] Retrieve an issue link ---------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88228) in GitLab 15.1. * `id` response attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/work_items/585093) in GitLab 18.9. Retrieves details about a specified issue link. GET /projects/:id/issues/:issue_iid/links/:issue_link_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `issue_iid` | integer | Yes | Internal ID of a project’s issue. | | `issue_link_id` | integer or string | Yes | ID of an issue relationship. | Response body attributes: | Attribute | Type | Description | | --- | --- | --- | | `id` | integer | ID of the issue link. | | `source_issue` | object | Details of the source issue of the relationship. | | `target_issue` | object | Details of the target issue of the relationship. | | `link_type` | string | Type of the relationship. Possible values are `relates_to`, `blocks` and `is_blocked_by`. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/84/issues/14/links/1" Example response: { "id": 1, "source_issue" : { "id" : 83, "iid" : 11, "project_id" : 4, "created_at" : "2016-01-07T12:44:33.959Z", "title" : "Issues with auth", "state" : "opened", "assignees" : [], "assignee" : null, "labels" : [\ "bug"\ ], "author" : { "name" : "Alexandra Bashirian", "avatar_url" : null, "state" : "active", "web_url" : "https://gitlab.example.com/eileen.lowe", "id" : 18, "username" : "eileen.lowe" }, "description" : null, "updated_at" : "2016-01-07T12:44:33.959Z", "milestone" : null, "subscribed" : true, "user_notes_count": 0, "due_date": null, "web_url": "http://example.com/example/example/issues/11", "confidential": false, "weight": null }, "target_issue" : { "id" : 84, "iid" : 14, "project_id" : 4, "created_at" : "2016-01-07T12:44:33.959Z", "title" : "Issues with auth", "state" : "opened", "assignees" : [], "assignee" : null, "labels" : [\ "bug"\ ], "author" : { "name" : "Alexandra Bashirian", "avatar_url" : null, "state" : "active", "web_url" : "https://gitlab.example.com/eileen.lowe", "id" : 18, "username" : "eileen.lowe" }, "description" : null, "updated_at" : "2016-01-07T12:44:33.959Z", "milestone" : null, "subscribed" : true, "user_notes_count": 0, "due_date": null, "web_url": "http://example.com/example/example/issues/14", "confidential": false, "weight": null }, "link_type": "relates_to" } Create an issue link -------------------- History * `id` response attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/work_items/585093) in GitLab 18.9. Creates a two-way relationship between two issues. The user must be allowed to update both issues to succeed. POST /projects/:id/issues/:issue_iid/links | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `issue_iid` | integer | yes | The internal ID of a project’s issue | | `target_project_id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a target project | | `target_issue_iid` | integer or string | yes | The internal ID of a target project’s issue | | `link_type` | string | no | The type of the relation (`relates_to`, `blocks`, `is_blocked_by`), defaults to `relates_to`). | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/4/issues/1/links?target_project_id=5&target_issue_iid=1" Example response: { "id": 1, "source_issue" : { "id" : 83, "iid" : 11, "project_id" : 4, "created_at" : "2016-01-07T12:44:33.959Z", "title" : "Issues with auth", "state" : "opened", "assignees" : [], "assignee" : null, "labels" : [\ "bug"\ ], "author" : { "name" : "Alexandra Bashirian", "avatar_url" : null, "state" : "active", "web_url" : "https://gitlab.example.com/eileen.lowe", "id" : 18, "username" : "eileen.lowe" }, "description" : null, "updated_at" : "2016-01-07T12:44:33.959Z", "milestone" : null, "subscribed" : true, "user_notes_count": 0, "due_date": null, "web_url": "http://example.com/example/example/issues/11", "confidential": false, "weight": null }, "target_issue" : { "id" : 84, "iid" : 14, "project_id" : 4, "created_at" : "2016-01-07T12:44:33.959Z", "title" : "Issues with auth", "state" : "opened", "assignees" : [], "assignee" : null, "labels" : [\ "bug"\ ], "author" : { "name" : "Alexandra Bashirian", "avatar_url" : null, "state" : "active", "web_url" : "https://gitlab.example.com/eileen.lowe", "id" : 18, "username" : "eileen.lowe" }, "description" : null, "updated_at" : "2016-01-07T12:44:33.959Z", "milestone" : null, "subscribed" : true, "user_notes_count": 0, "due_date": null, "web_url": "http://example.com/example/example/issues/14", "confidential": false, "weight": null }, "link_type": "relates_to" } Delete an issue link -------------------- History * `id` response attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/work_items/585093) in GitLab 18.9. Deletes a specified issue link, removing the two-way relationship. DELETE /projects/:id/issues/:issue_iid/links/:issue_link_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `issue_iid` | integer | yes | The internal ID of a project’s issue | | `issue_link_id` | integer or string | yes | The ID of an issue relationship | | `link_type` | string | no | The type of the relation (`relates_to`, `blocks`, `is_blocked_by`), defaults to `relates_to` | { "id": 1, "source_issue" : { "id" : 83, "iid" : 11, "project_id" : 4, "created_at" : "2016-01-07T12:44:33.959Z", "title" : "Issues with auth", "state" : "opened", "assignees" : [], "assignee" : null, "labels" : [\ "bug"\ ], "author" : { "name" : "Alexandra Bashirian", "avatar_url" : null, "state" : "active", "web_url" : "https://gitlab.example.com/eileen.lowe", "id" : 18, "username" : "eileen.lowe" }, "description" : null, "updated_at" : "2016-01-07T12:44:33.959Z", "milestone" : null, "subscribed" : true, "user_notes_count": 0, "due_date": null, "web_url": "http://example.com/example/example/issues/11", "confidential": false, "weight": null }, "target_issue" : { "id" : 84, "iid" : 14, "project_id" : 4, "created_at" : "2016-01-07T12:44:33.959Z", "title" : "Issues with auth", "state" : "opened", "assignees" : [], "assignee" : null, "labels" : [\ "bug"\ ], "author" : { "name" : "Alexandra Bashirian", "avatar_url" : null, "state" : "active", "web_url" : "https://gitlab.example.com/eileen.lowe", "id" : 18, "username" : "eileen.lowe" }, "description" : null, "updated_at" : "2016-01-07T12:44:33.959Z", "milestone" : null, "subscribed" : true, "user_notes_count": 0, "due_date": null, "web_url": "http://example.com/example/example/issues/14", "confidential": false, "weight": null }, "link_type": "relates_to" } --- # LDAP group links | GitLab Docs * * * LDAP group links ================ * Tier: Premium, Ultimate * Offering: GitLab Self-Managed Use this API to manage LDAP group links. For more information, see [manage group memberships with LDAP](https://docs.gitlab.com/user/group/access_and_permissions/#manage-group-memberships-with-ldap) . List all LDAP group links ------------------------- Lists all LDAP group links. GET /groups/:id/ldap_group_links Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/4/ldap_group_links" Example response: [\ {\ "cn": "group1",\ "group_access": 40,\ "provider": "ldapmain",\ "filter": null,\ "member_role_id": null\ },\ {\ "cn": "group2",\ "group_access": 10,\ "provider": "ldapmain",\ "filter": null,\ "member_role_id": null\ }\ ] Add an LDAP group link with CN or filter ---------------------------------------- Adds an LDAP group link using a CN or filter. POST /groups/:id/ldap_group_links Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `group_access` | integer | yes | The default access level for members of the LDAP group. Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), `50` (Owner). | | `provider` | string | yes | LDAP provider ID for the LDAP group link. | | `cn` | string | yes/no | The CN of an LDAP group. Provide either a `cn` or a `filter`, but not both. | | `filter` | string | yes/no | The LDAP filter for the group. Provide either a `cn` or a `filter`, but not both. | | `member_role_id` | integer | no | The ID of the [member role](https://docs.gitlab.com/api/member_roles/)
. Ultimate only. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"group_access": 40, "provider": "ldapmain", "cn": "group2"}' \ --url "https://gitlab.example.com/api/v4/groups/4/ldap_group_links" Example response: { "cn": "group2", "group_access": 40, "provider": "main", "filter": null, "member_role_id": null } Delete an LDAP group link with CN or filter ------------------------------------------- Deletes an LDAP group link using a CN or filter. DELETE /groups/:id/ldap_group_links Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `provider` | string | yes | LDAP provider ID for the LDAP group link. | | `cn` | string | yes/no | The CN of an LDAP group. Provide either a `cn` or a `filter`, but not both. | | `filter` | string | yes/no | The LDAP filter for the group. Provide either a `cn` or a `filter`, but not both. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"provider": "ldapmain", "cn": "group2"}' \ --url "https://gitlab.example.com/api/v4/groups/4/ldap_group_links" If successful, no response is returned. Delete an LDAP group link (deprecated) -------------------------------------- Deletes an LDAP group link. Deprecated. Scheduled for removal in a future release. Use [Delete an LDAP group link with CN or filter](https://docs.gitlab.com/api/group_ldap_links/#delete-an-ldap-group-link-with-cn-or-filter) instead. Delete an LDAP group link with a CN: DELETE /groups/:id/ldap_group_links/:cn | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `cn` | string | yes | The CN of an LDAP group | Delete an LDAP group link for a specific LDAP provider: DELETE /groups/:id/ldap_group_links/:provider/:cn | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `cn` | string | yes | The CN of an LDAP group | | `provider` | string | yes | LDAP provider for the LDAP group link | --- # Merge request context commits API | GitLab Docs * * * Merge request context commits API ================================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated If your merge request builds upon a previous merge request, you might need to [include previously-merged commits for context](https://docs.gitlab.com/user/project/merge_requests/commits/#show-commits-from-previous-merge-requests) in your merge request. Use this API to add commits to a merge request for more context. List context commits for a merge request ---------------------------------------- Lists context commits for a single merge request. GET /projects/:id/merge_requests/:merge_request_iid/context_commits Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | [\ {\ "id": "4a24d82dbca5c11c61556f3b35ca472b7463187e",\ "short_id": "4a24d82d",\ "created_at": "2017-04-11T10:08:59.000Z",\ "parent_ids": null,\ "title": "Update README.md to include `Usage in testing and development`",\ "message": "Update README.md to include `Usage in testing and development`",\ "author_name": "Example \"Sample\" User",\ "author_email": "user@example.com",\ "authored_date": "2017-04-11T10:08:59.000Z",\ "committer_name": "Example \"Sample\" User",\ "committer_email": "user@example.com",\ "committed_date": "2017-04-11T10:08:59.000Z"\ }\ ] Create context commits for a merge request ------------------------------------------ Creates context commits for a single merge request. POST /projects/:id/merge_requests/:merge_request_iid/context_commits Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `commits` | string array | Yes | The context commits’ SHAs. | Example request: curl --request POST --header "PRIVATE-TOKEN: " \ --header 'Content-Type: application/json' \ --data '{"commits": ["51856a574ac3302a95f82483d6c7396b1e0783cb"]}' \ --url "https://gitlab.example.com/api/v4/projects/15/merge_requests/12/context_commits" Example response: [\ {\ "id": "51856a574ac3302a95f82483d6c7396b1e0783cb",\ "short_id": "51856a57",\ "created_at": "2014-02-27T10:05:10.000+02:00",\ "parent_ids": [\ "57a82e2180507c9e12880c0747f0ea65ad489515"\ ],\ "title": "Commit title",\ "message": "Commit message",\ "author_name": "Example User",\ "author_email": "user@example.com",\ "authored_date": "2014-02-27T10:05:10.000+02:00",\ "committer_name": "Example User",\ "committer_email": "user@example.com",\ "committed_date": "2014-02-27T10:05:10.000+02:00",\ "trailers": {},\ "web_url": "https://gitlab.example.com/project/path/-/commit/b782f6c553653ab4e16469ff34bf3a81638ac304"\ }\ ] Delete context commits from a merge request ------------------------------------------- Deletes context commits from a single merge request. DELETE /projects/:id/merge_requests/:merge_request_iid/context_commits Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `commits` | string array | Yes | The context commits’ SHA. | | `id` | integer | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | --- # Maven API | GitLab Docs * * * Maven API ========= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with the [Maven package manager client](https://docs.gitlab.com/user/packages/maven_repository/) . This API is used by the [Maven package manager client](https://maven.apache.org/) and is generally not meant for manual consumption. These endpoints do not adhere to the standard API authentication methods. See [Maven package registry documentation](https://docs.gitlab.com/user/packages/maven_repository/) for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future. Download a package file for an instance --------------------------------------- Downloads a specified Maven package file for the instance. GET packages/maven/*path/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `path` | string | yes | The Maven package path, in the format `//`. Replace any `.` in the `groupId` with `/`. | | `file_name` | string | yes | The name of the Maven package file. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/packages/maven/foo/bar/mypkg/1.0-SNAPSHOT/mypkg-1.0-SNAPSHOT.jar" To write the output to file: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/packages/maven/foo/bar/mypkg/1.0-SNAPSHOT/mypkg-1.0-SNAPSHOT.jar" >> mypkg-1.0-SNAPSHOT.jar This writes the downloaded file to `mypkg-1.0-SNAPSHOT.jar` in the current directory. Download a package file for a group-level ----------------------------------------- Downloads a specified Maven package file for a group. GET groups/:id/-/packages/maven/*path/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `path` | string | yes | The Maven package path, in the format `//`. Replace any `.` in the `groupId` with `/`. | | `file_name` | string | yes | The name of the Maven package file. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/maven/foo/bar/mypkg/1.0-SNAPSHOT/mypkg-1.0-SNAPSHOT.jar" To write the output to file: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/maven/foo/bar/mypkg/1.0-SNAPSHOT/mypkg-1.0-SNAPSHOT.jar" >> mypkg-1.0-SNAPSHOT.jar This writes the downloaded file to `mypkg-1.0-SNAPSHOT.jar` in the current directory. Download a package file for a project ------------------------------------- Downloads a specified Maven package file for a project. GET projects/:id/packages/maven/*path/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `path` | string | yes | The Maven package path, in the format `//`. Replace any `.` in the `groupId` with `/`. | | `file_name` | string | yes | The name of the Maven package file. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/maven/foo/bar/mypkg/1.0-SNAPSHOT/mypkg-1.0-SNAPSHOT.jar" To write the output to file: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/maven/foo/bar/mypkg/1.0-SNAPSHOT/mypkg-1.0-SNAPSHOT.jar" >> mypkg-1.0-SNAPSHOT.jar This writes the downloaded file to `mypkg-1.0-SNAPSHOT.jar` in the current directory. Upload a package file --------------------- Uploads a specified Maven package file for a project. PUT projects/:id/packages/maven/*path/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `path` | string | yes | The Maven package path, in the format `//`. Replace any `.` in the `groupId` with `/`. | | `file_name` | string | yes | The name of the Maven package file. | curl --request PUT \ --upload-file path/to/mypkg-1.0-SNAPSHOT.pom \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/maven/foo/bar/mypkg/1.0-SNAPSHOT/mypkg-1.0-SNAPSHOT.pom" --- # Merge request approval settings API | GitLab Docs * * * Merge request approval settings API =================================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage group and project [merge request approval settings](https://docs.gitlab.com/user/project/merge_requests/approvals/settings/) . All endpoints require authentication. Group MR approval settings -------------------------- Prerequisites: * You must have the Owner role in the group. ### Retrieve MR approval settings for a group Retrieves the merge request approval settings for a specified group. GET /groups/:id/merge_request_approval_setting Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/merge_request_approval_setting" Example response: { "allow_author_approval": { "value": true, "locked": false, "inherited_from": null }, "allow_committer_approval": { "value": true, "locked": false, "inherited_from": null }, "allow_overrides_to_approver_list_per_merge_request": { "value": true, "locked": false, "inherited_from": null }, "retain_approvals_on_push": { "value": false, "locked": false, "inherited_from": null }, "selective_code_owner_removals": { "value": false, "locked": false, "inherited_from": null }, "require_password_to_approve": { "value": false, "locked": false, "inherited_from": null }, "require_reauthentication_to_approve": { "value": false, "locked": false, "inherited_from": null } } ### Update group MR approval settings Update the merge request approval settings of a group. PUT /groups/:id/merge_request_approval_setting Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `allow_author_approval` | boolean | No | Allow or prevent authors from self approving merge requests; `true` means authors can self approve. | | `allow_committer_approval` | boolean | No | Allow or prevent committers from self approving merge requests. | | `allow_overrides_to_approver_list_per_merge_request` | boolean | No | Allow or prevent overriding approvers per merge request. | | `retain_approvals_on_push` | boolean | No | Retain approval count on a new push. | | `require_reauthentication_to_approve` | boolean | No | Require approver to authenticate before adding the approval. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/431346)
in GitLab 17.1. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/merge_request_approval_setting?allow_author_approval=false" Example response: { "allow_author_approval": { "value": false, "locked": false, "inherited_from": null }, "allow_committer_approval": { "value": true, "locked": false, "inherited_from": null }, "allow_overrides_to_approver_list_per_merge_request": { "value": true, "locked": false, "inherited_from": null }, "retain_approvals_on_push": { "value": false, "locked": false, "inherited_from": null }, "selective_code_owner_removals": { "value": false, "locked": false, "inherited_from": null }, "require_password_to_approve": { "value": false, "locked": false, "inherited_from": null }, "require_reauthentication_to_approve": { "value": false, "locked": false, "inherited_from": null } } Project MR approval settings ---------------------------- Prerequisites: * You must have the Maintainer role in the project. ### Retrieve MR approval settings for a project Retrieves the merge request approval settings for a specified project. GET /projects/:id/merge_request_approval_setting Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/merge_request_approval_setting" Example response: { "allow_author_approval": { "value": true, "locked": false, "inherited_from": null }, "allow_committer_approval": { "value": true, "locked": false, "inherited_from": null }, "allow_overrides_to_approver_list_per_merge_request": { "value": true, "locked": false, "inherited_from": null }, "retain_approvals_on_push": { "value": false, "locked": true, "inherited_from": "group" }, "selective_code_owner_removals": { "value": false, "locked": false, "inherited_from": null }, "require_password_to_approve": { "value": false, "locked": false, "inherited_from": null }, "require_reauthentication_to_approve": { "value": false, "locked": false, "inherited_from": null } } ### Update project MR approval settings Update the merge request approval settings of a project. PUT /projects/:id/merge_request_approval_setting Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `allow_author_approval` | boolean | No | Allow or prevent authors from self approving merge requests; `true` means authors can self approve. | | `allow_committer_approval` | boolean | No | Allow or prevent committers from self approving merge requests. | | `allow_overrides_to_approver_list_per_merge_request` | boolean | No | Allow or prevent overriding approvers per merge request. | | `retain_approvals_on_push` | boolean | No | Retain approval count on a new push. | | `selective_code_owner_removals` | boolean | No | Reset approvals from Code Owners if their files changed. You must disable the `retain_approvals_on_push` field to use this field. | | `require_reauthentication_to_approve` | boolean | No | Require approver to authenticate before adding the approval. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/431346)
in GitLab 17.1. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/merge_request_approval_setting?allow_author_approval=false" Example response: { "allow_author_approval": { "value": false, "locked": false, "inherited_from": null }, "allow_committer_approval": { "value": true, "locked": false, "inherited_from": null }, "allow_overrides_to_approver_list_per_merge_request": { "value": true, "locked": false, "inherited_from": null }, "retain_approvals_on_push": { "value": false, "locked": false, "inherited_from": null }, "selective_code_owner_removals": { "value": false, "locked": false, "inherited_from": null }, "require_password_to_approve": { "value": false, "locked": false, "inherited_from": null }, "require_reauthentication_to_approve": { "value": false, "locked": false, "inherited_from": null } } --- # List branch rules for a project by using GraphQL | GitLab Docs * * * List branch rules for a project by using GraphQL ================================================ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated You can query for branch rules in a given project by using: * GraphiQL. * [`cURL`](https://docs.gitlab.com/api/graphql/getting_started/#command-line) . * [The GitLab Development Kit (GDK)](https://docs.gitlab.com/api/graphql/branch_rules/#use-the-gdk) . Use GraphiQL ------------ You can use GraphiQL to list the branch rules for a project. 1. Open GraphiQL: * For GitLab.com, use: `https://gitlab.com/-/graphql-explorer` * For GitLab Self-Managed, use: `https://gitlab.example.com/-/graphql-explorer` 2. Copy the following text and paste it in the left window. This query searches for a project by its full path, for example `gitlab-org/gitlab-docs`. It requests all configured branch rules for the project. query { project(fullPath: "gitlab-org/gitlab-docs") { branchRules { nodes { name isDefault isProtected matchingBranchesCount createdAt updatedAt branchProtection { allowForcePush codeOwnerApprovalRequired mergeAccessLevels { nodes { accessLevel accessLevelDescription user { name } group { name } } } pushAccessLevels { nodes { accessLevel accessLevelDescription user { name } group { name } } } unprotectAccessLevels { nodes { accessLevel accessLevelDescription user { name } group { name } } } } externalStatusChecks { nodes { id name externalUrl } } approvalRules { nodes { id name type approvalsRequired eligibleApprovers { nodes { name } } } } } } } } 3. Select **Play**. If no branch rules are displayed, it might be because: * No branch rules are configured. * Your role doesn’t have permission to view branch rules. Administrators have access to all resources. Use the GDK ----------- Instead of requesting access, it may be easier for you to run the query in the [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit) . 1. Sign in as the default admin, `root`, with the credentials from [the GDK documentation](https://gitlab-org.gitlab.io/gitlab-development-kit/gdk_commands/#get-the-login-credentials) . 2. Ensure you have some branch rules configured for the `flightjs/Flight` project. 3. In your GDK instance, open GraphiQL: `http://gdk.test:3000/-/graphql-explorer`. 4. Copy the query and paste it in the left window. 5. Replace the full path with the following path: query { project(fullPath: "flightjs/Flight") { 6. Select **Play**. Related topics -------------- * [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) --- # Open redirect | GitLab Docs * * * Open redirect ============= Description ----------- Identify open redirects and determine if they can be abused by attackers. Remediation ----------- Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. By modifying untrusted URL input to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts may have a more trustworthy appearance. Unvalidated redirect and forward attacks can also be used to maliciously craft a URL that would pass the application’s access control check and then forward the attacker to privileged functions that they would usually not be able to access. Links ----- * [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control/) * [CWE](https://cwe.mitre.org/data/definitions/601.html) --- # Metadata API | GitLab Docs * * * Metadata API ============ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/357032) in GitLab 15.2. * `enterprise` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/103969) in GitLab 15.6. * `kas.externalK8sProxyUrl` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/172373) in GitLab 17.6. Retrieves metadata information for a specified GitLab instance. GET /metadata GET /version Response body attributes: | Attribute | Type | Description | | --- | --- | --- | | `version` | string | Version of the GitLab instance. | | `revision` | string | Revision of the GitLab instance. | | `kas` | object | Metadata about the GitLab agent server for Kubernetes (KAS). | | `kas.enabled` | boolean | Indicates whether KAS is enabled. | | `kas.externalUrl` | string or null | URL used by the agents to communicate with KAS. It’s `null` if `kas.enabled` is `false`. | | `kas.externalK8sProxyUrl` | string or null | URL used by the Kubernetes tooling to communicate with the KAS Kubernetes API proxy. It’s `null` if `kas.enabled` is `false`. | | `kas.version` | string or null | Version of KAS. It’s `null` if `kas.enabled` is `false` or when GitLab instance failed to fetch server info from KAS. | | `enterprise` | boolean | Indicates whether GitLab instance is Enterprise Edition. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/metadata" curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/version" Example response: { "version": "18.1.1-ee", "revision": "ceb07b24cb0", "kas": { "enabled": true, "externalUrl": "grpc://gitlab.example.com:8150", "externalK8sProxyUrl": "https://gitlab.example.com:8150/k8s-proxy", "version": "18.1.1" }, "enterprise": true } --- # Markdown uploads API | GitLab Docs * * * Markdown uploads API ==================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [Markdown uploads](https://docs.gitlab.com/security/user_file_uploads/) that can be referenced in Markdown text in issues, merge requests, snippets, or wiki pages. Create an upload ---------------- History * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112450) in GitLab 15.10. Feature flag `enforce_max_attachment_size_upload_api` removed. * `full_path` response attribute pattern [changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150939) in GitLab 17.1. * `id` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/161160) in GitLab 17.3. Uploads a file to the specified project to be used in an issue or merge request description, or a comment. POST /projects/:id/uploads Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `file` | string | Yes | File to be uploaded. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | To upload a file from your file system, use the `--form` argument. This causes cURL to post data using the `Content-Type: multipart/form-data` header. The `file=` parameter must point to a file on your file system and be preceded by `@`. Example request: curl --request POST --header "PRIVATE-TOKEN: " \ --form "file=@dk.png" "https://gitlab.example.com/api/v4/projects/5/uploads" Example response: { "id": 5, "alt": "dk", "url": "/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png", "full_path": "/-/project/1234/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png", "markdown": "![dk](/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png)" } In the response, the: * `full_path` is the absolute path to the file. * `url` can be used in Markdown contexts. The link is expanded when the format in `markdown` is used. List uploads ------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2. Lists all uploads of a project sorted by `created_at` in descending order. Prerequisites: * the Maintainer or Owner role. GET /projects/:id/uploads Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/uploads" Example response: [\ {\ "id": 1,\ "size": 1024,\ "filename": "image.png",\ "created_at":"2024-06-20T15:53:03.067Z",\ "uploaded_by": {\ "id": 18,\ "name" : "Alexandra Bashirian",\ "username" : "eileen.lowe"\ }\ },\ {\ "id": 2,\ "size": 512,\ "filename": "other-image.png",\ "created_at":"2024-06-19T15:53:03.067Z",\ "uploaded_by": null\ }\ ] Download an uploaded file by ID ------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2. Downloads an uploaded file by ID. Prerequisites: * the Maintainer or Owner role. GET /projects/:id/uploads/:upload_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `upload_id` | integer | Yes | ID of the upload. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the uploaded file in the response body. Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/uploads/1" Download an uploaded file by secret and filename ------------------------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4. Download an uploaded file by secret and filename. Prerequisites: * the Guest, Planner, Reporter, Developer, Maintainer, or Owner role. GET /projects/:id/uploads/:secret/:filename Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `secret` | string | Yes | 32-character secret of the upload. | | `filename` | string | Yes | Filename of the upload. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the uploaded file in the response body. Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg" Delete an uploaded file by ID ----------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157066) in GitLab 17.2. Deletes an uploaded file by ID. Prerequisites: * the Maintainer or Owner role. DELETE /projects/:id/uploads/:upload_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `upload_id` | integer | Yes | ID of the upload. | If successful, returns [`204`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) status code without any response body. Example request: curl --request DELETE --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/uploads/1" Delete an uploaded file by secret and filename ---------------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164441) in GitLab 17.4. Deletes an uploaded file by secret and filename. Prerequisites: * the Maintainer or Owner role. DELETE /projects/:id/uploads/:secret/:filename Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `secret` | string | Yes | 32-character secret of the upload. | | `filename` | string | Yes | Filename of the upload. | If successful, returns [`204`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) status code without any response body. Example request: curl --request DELETE --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/uploads/648d97c6eef5fc5df8d1004565b3ee5a/sample.jpg" --- # Offline configuration | GitLab Docs * * * Offline configuration ===================== * Tier: Ultimate * Offering: GitLab Self-Managed For instances in an environment with limited, restricted, or intermittent access to external resources through the internet, some adjustments are required for the API security testing job to successfully run. Steps: 1. Host the Docker image in a local container registry. 2. Set the `SECURE_ANALYZERS_PREFIX` to the local container registry. The Docker image for API security testing must be pulled (downloaded) from the public registry and then pushed (imported) into a local registry. The GitLab container registry can be used to locally host the Docker image. This process can be performed using a special template. See [loading Docker images onto your offline host](https://docs.gitlab.com/user/application_security/offline_deployments/#loading-docker-images-onto-your-offline-host) for instructions. Once the Docker image is hosted locally, the `SECURE_ANALYZERS_PREFIX` variable is set with the location of the local registry. The variable must be set such that concatenating `/api-security:2` results in a valid image location. API security testing and API fuzzing both use the same underlying Docker image `api-security:2`. For example, the below line sets a registry for the image `registry.gitlab.com/security-products/api-security:2`: `SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"` Setting `SECURE_ANALYZERS_PREFIX` changes the Docker image registry location for all GitLab Secure templates. For more information, see [Offline environments](https://docs.gitlab.com/user/application_security/offline_deployments/) . --- # OS command injection | GitLab Docs * * * OS command injection ==================== Description ----------- Check for OS command injection vulnerabilities. An OS command injection attack consists of insertion or “injection” of an OS command via the input data from the client to the application. A successful OS command injection exploit can run arbitrary commands. This allows an attacker the ability to read, write, and delete data. Depending on the user the commands run as, this can also include administrative functions. This check modifies parameters in the request (path, query string, headers, JSON, XML, etc.) to try and execute an OS command. Both standard injections and blind injections are performed. Blind injections cause delays in response when successful. Remediation ----------- It is possible to execute arbitrary OS commands on the target application server. OS Command Injection is a critical vulnerability that can lead to a full system compromise. User input should never be used in constructing commands or command arguments to functions which execute OS commands. This includes filenames supplied by user uploads or downloads. Ensure your application does not: * Use user supplied information in the process name to execute. * Use user supplied information in an OS command execution function which does not escape shell meta-characters. * Use user supplied information in arguments to OS commands. The application should have a hardcoded set of arguments that are to be passed to OS commands. If filenames are being passed to these functions, it is recommended that a hash of the filename be used instead, or some other unique identifier. It is strongly recommended that a native library that implements the same functionality be used instead of using OS system commands due to the risk of unknown attacks against third party commands. Links ----- * [OWASP](https://owasp.org/Top10/A03_2021-Injection/) * [CWE](https://cwe.mitre.org/data/definitions/78.html) --- # Overriding API fuzzing jobs | GitLab Docs * * * Overriding API fuzzing jobs =========================== To override a job definition, (for example, change properties like `variables`, `dependencies`, or [`rules`](https://docs.gitlab.com/ci/yaml/#rules) ), declare a job with the same name as the DAST job to override. Place this new job after the template inclusion and specify any additional keys under it. For example, this sets the target APIs base URL: include: - template: Security/API-Fuzzing.gitlab-ci.yml apifuzzing_fuzz: variables: FUZZAPI_TARGET_URL: https://target/api --- # Offline configuration | GitLab Docs * * * Offline configuration ===================== * Tier: Ultimate * Offering: GitLab Self-Managed For instances in an environment with limited, restricted, or intermittent access to external resources through the internet, some adjustments are required for the web API fuzz testing job to successfully run. Steps: 1. Host the Docker image in a local container registry. 2. Set the `SECURE_ANALYZERS_PREFIX` to the local container registry. The Docker image for API fuzzing must be pulled (downloaded) from the public registry and then pushed (imported) into a local registry. The GitLab container registry can be used to locally host the Docker image. This process can be performed using a special template. See [loading Docker images onto your offline host](https://docs.gitlab.com/user/application_security/offline_deployments/#loading-docker-images-onto-your-offline-host) for instructions. Once the Docker image is hosted locally, the `SECURE_ANALYZERS_PREFIX` variable is set with the location of the local registry. The variable must be set such that concatenating `/api-security:2` results in a valid image location. For example, the below line sets a registry for the image `registry.gitlab.com/security-products/api-security:2`: `SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"` Setting `SECURE_ANALYZERS_PREFIX` changes the Docker image registry location for all GitLab secure templates. For more information, see [Offline environments](https://docs.gitlab.com/user/application_security/offline_deployments/) . --- # Overriding API security testing jobs | GitLab Docs * * * Overriding API security testing jobs ==================================== To override a job definition, (for example, change properties like `variables`, `dependencies`, or [`rules`](https://docs.gitlab.com/ci/yaml/#rules) ), declare a job with the same name as the DAST job to override. Place this new job after the template inclusion and specify any additional keys under it. For example, this sets the target APIs base URL: include: - template: Security/API-Security.gitlab-ci.yml api_security: variables: APISEC_TARGET_URL: https://target/api --- # Model registry API | GitLab Docs * * * Model registry API ================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with the machine learning [model registry](https://docs.gitlab.com/user/project/ml/model_registry/) . The `:model_version_id` attribute in each endpoint accepts either a model version ID or a candidate run ID. For more information, see [Model version and candidate IDs](https://docs.gitlab.com/api/model_registry/#model-version-and-candidate-ids) . Download a machine learning model package file ---------------------------------------------- Downloads a specified file from a machine learning model package. GET /api/v4/projects/:id/packages/ml_models/:model_version_id/files/(*path/):file_name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `model_version_id` | integer or string | Yes | The model version ID or candidate run ID. See [Model version and candidate IDs](https://docs.gitlab.com/api/model_registry/#model-version-and-candidate-ids)
. | | `file_name` | string | Yes | The filename. | | `path` | string | No | The directory path for the file. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the file contents. Example request: curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/ml_models/2/files/foo.txt" Example request with a directory path: curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/ml_models/2/files/my_dir/foo.txt" Upload a model package file --------------------------- Uploads a file to a machine learning model package. ### Authorize the upload Authorizes a file upload to a machine learning model package. PUT /api/v4/projects/:id/packages/ml_models/:model_version_id/files/(*path/):file_name/authorize Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `model_version_id` | integer or string | Yes | The model version ID or candidate run ID. See [Model version and candidate IDs](https://docs.gitlab.com/api/model_registry/#model-version-and-candidate-ids)
. | | `file_name` | string | Yes | The filename. | | `path` | string | No | The directory path for the file. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request PUT \ --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/ml_models/2/files/model.pkl/authorize" ### Send the file Uploads the file to a machine learning model package. PUT /api/v4/projects/:id/packages/ml_models/:model_version_id/files/(*path/):file_name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `model_version_id` | integer or string | Yes | The model version ID or candidate run ID. See [Model version and candidate IDs](https://docs.gitlab.com/api/model_registry/#model-version-and-candidate-ids)
. | | `file_name` | string | Yes | The filename. | | `path` | string | No | The directory path for the file. | | `file` | file | Yes | The file to upload. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request PUT \ --header "Authorization: Bearer " \ --form "file=@model.pkl" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/ml_models/2/files/model.pkl" Example request with a directory path: curl --request PUT \ --header "Authorization: Bearer " \ --form "file=@model.pkl" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/ml_models/2/files/my_dir/model.pkl" Model version and candidate IDs ------------------------------- The `:model_version_id` attribute accepts either a model version ID or a candidate run ID. To find the model version ID, check the URL of the model version page. For example, in `https://gitlab.example.com/my-namespace/my-project/-/ml/models/1/versions/5`, the model version ID is `5`. curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/ml_models/5/files/model.pkl" To use a candidate run ID, prepend the internal ID of the candidate with `candidate:`. For example, in `https://gitlab.example.com/my-namespace/my-project/-/ml/candidates/5`, the value for `:model_version_id` is `candidate:5`. curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/ml_models/candidate:5/files/model.pkl" --- # Path traversal | GitLab Docs * * * Path traversal ============== Description ----------- Many file operations are intended to take place within a restricted directory. By using special elements such as `..` and `/` separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the `../` sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute path-names such as `/usr/local/bin`, which may also be useful in accessing unexpected files. This is referred to as absolute path traversal. In many programming languages, the injection of a null byte (the `0` or `NULL` ) may allow an attacker to truncate a generated filename to widen the scope of attack. For example, the software may add `.txt` to any pathname, thus limiting the attacker to text files, but a null injection may effectively remove this restriction. This check modifies parameters in the request (path, query string, headers, JSON, XML, etc.) to try and access restricted files and files outside of the web-root. Logs and responses are then analyzed to try and detect if the file was successfully accessed. Remediation ----------- The Path traversal attack technique allows an attacker access to files, directories, and commands that potentially reside outside the web document root directory. An attacker may manipulate a URL in such a way that the web site will execute or reveal the contents of arbitrary files anywhere on the web server. Any device that exposes an HTTP-based interface is potentially vulnerable to Path traversal. Most web sites restrict user access to a specific portion of the file-system, typically called the “web document root” or “CGI root” directory. These directories contain the files intended for user access and the executable necessary to drive web application functionality. To access files or execute commands anywhere on the file-system, Path traversal attacks will utilize the ability of special-characters sequences. The most basic Path traversal attack uses the `../` special-character sequence to alter the resource location requested in the URL. Although most popular web servers will prevent this technique from escaping the web document root, alternate encodings of the `../` sequence may help bypass the security filters. These method variations include valid and invalid Unicode-encoding (`..%u2216` or `..%c0%af`) of the forward slash character, backslash characters (`..`) on Windows-based servers, URL encoded characters (`%2e%2e%2f`), and double URL encoding (`..%255c`) of the backslash character. Even if the web server properly restricts Path traversal attempts in the URL path, a web application itself may still be vulnerable due to improper handling of user-supplied input. This is a common problem of web applications that use template mechanisms or load static text from files. In variations of the attack, the original URL parameter value is substituted with the file name of one of the web application’s dynamic scripts. Consequently, the results can reveal source code because the file is interpreted as text instead of an executable script. These techniques often employ additional special characters such as the dot (`.`) to reveal the listing of the current working directory, or `%00` NULL characters in order to bypass rudimentary file extension checks. Links ----- * [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control/) * [CWE](https://cwe.mitre.org/data/definitions/22.html) --- # Plan limits API | GitLab Docs * * * Plan limits API =============== * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Use this API to interact with the application limits for your existing subscription plan. The existing plans depend on the GitLab edition. In the Community Edition, only the plan `default` is available. In the Enterprise Edition, additional plans are available as well. Prerequisites: * You must have administrator access to the instance. Retrieve current plan limits ---------------------------- Retrieves the current limits of a plan on the GitLab instance. GET /application/plan_limits | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `plan_name` | string | no | Name of the plan to get the limits from. Default: `default`. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/application/plan_limits" Example response: { "ci_instance_level_variables": 25, "ci_pipeline_size": 0, "ci_active_jobs": 0, "ci_project_subscriptions": 2, "ci_pipeline_schedules": 10, "ci_needs_size_limit": 50, "ci_registered_group_runners": 1000, "ci_registered_project_runners": 1000, "dotenv_size": 5120, "dotenv_variables": 20, "conan_max_file_size": 3221225472, "enforcement_limit": 10000, "generic_packages_max_file_size": 5368709120, "helm_max_file_size": 5242880, "notification_limit": 10000, "maven_max_file_size": 3221225472, "npm_max_file_size": 524288000, "nuget_max_file_size": 524288000, "pipeline_hierarchy_size": 1000, "pypi_max_file_size": 3221225472, "terraform_module_max_file_size": 1073741824, "storage_size_limit": 15000 } Update plan limits ------------------ Updates the limits of a plan on the GitLab instance. PUT /application/plan_limits | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `plan_name` | string | yes | Name of the plan to update. | | `ci_instance_level_variables` | integer | no | Maximum number of Instance-level CI/CD variables that can be defined. | | `ci_pipeline_size` | integer | no | Maximum number of jobs in a single pipeline. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895)
in GitLab 15.0. | | `ci_active_jobs` | integer | no | Total number of jobs in currently active pipelines. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895)
in GitLab 15.0. | | `ci_project_subscriptions` | integer | no | Maximum number of pipeline subscriptions to and from a project. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895)
in GitLab 15.0. | | `ci_pipeline_schedules` | integer | no | Maximum number of pipeline schedules. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895)
in GitLab 15.0. | | `ci_needs_size_limit` | integer | no | Maximum number of [`needs`](https://docs.gitlab.com/ci/yaml/needs/)
dependencies that a job can have. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895)
in GitLab 15.0. | | `ci_registered_group_runners` | integer | no | Maximum number of runners created or active in a group during the past seven days. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895)
in GitLab 15.0. | | `ci_registered_project_runners` | integer | no | Maximum number of runners created or active in a project during the past seven days. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895)
in GitLab 15.0. | | `dotenv_size` | integer | no | Maximum size of a dotenv artifact in bytes. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/432529)
in GitLab 17.1. | | `dotenv_variables` | integer | no | Maximum number of variables in a dotenv artifact. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/432529)
in GitLab 17.1. | | `conan_max_file_size` | integer | no | Maximum Conan package file size in bytes. | | `enforcement_limit` | integer | no | Maximum storage size for root namespace limit enforcement in MiB. | | `generic_packages_max_file_size` | integer | no | Maximum generic package file size in bytes. | | `helm_max_file_size` | integer | no | Maximum Helm chart file size in bytes. | | `maven_max_file_size` | integer | no | Maximum Maven package file size in bytes. | | `notification_limit` | integer | no | Maximum storage size for root namespace limit notifications in MiB. | | `npm_max_file_size` | integer | no | Maximum NPM package file size in bytes. | | `nuget_max_file_size` | integer | no | Maximum NuGet package file size in bytes. | | `pipeline_hierarchy_size` | integer | no | Maximum number of downstream pipelines in a pipeline’s hierarchy tree. Default value: `1000`. Values greater than 1000 are [not recommended](https://docs.gitlab.com/administration/instance_limits/#limit-pipeline-hierarchy-size)
. | | `pypi_max_file_size` | integer | no | Maximum PyPI package file size in bytes. | | `terraform_module_max_file_size` | integer | no | Maximum Terraform Module package file size in bytes. | | `storage_size_limit` | integer | no | Maximum storage size for the root namespace in MiB. | | `web_hook_calls` | integer | no | Maximum number of times a webhook can be called per minute per top-level namespace. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/571738)
in GitLab 18.5. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/application/plan_limits?plan_name=default&conan_max_file_size=3221225472" Example response: { "ci_instance_level_variables": 25, "ci_pipeline_size": 0, "ci_active_jobs": 0, "ci_project_subscriptions": 2, "ci_pipeline_schedules": 10, "ci_needs_size_limit": 50, "ci_registered_group_runners": 1000, "ci_registered_project_runners": 1000, "conan_max_file_size": 3221225472, "dotenv_variables": 20, "dotenv_size": 5120, "generic_packages_max_file_size": 5368709120, "helm_max_file_size": 5242880, "maven_max_file_size": 3221225472, "npm_max_file_size": 524288000, "nuget_max_file_size": 524288000, "pipeline_hierarchy_size": 1000, "pypi_max_file_size": 3221225472, "terraform_module_max_file_size": 1073741824 } --- # npm API | GitLab Docs * * * npm API ======= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with the [npm package manager client](https://docs.gitlab.com/user/packages/npm_registry/) . This API is used by the [npm package manager client](https://docs.npmjs.com/) and is not meant for manual consumption. These endpoints do not adhere to the standard API authentication methods. See the [npm package registry documentation](https://docs.gitlab.com/user/packages/npm_registry/) for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future. Download a package ------------------ Downloads a specified npm package for a project. This URL is provided by the [metadata endpoint](https://docs.gitlab.com/api/packages/npm/#retrieve-package-metadata) . GET projects/:id/packages/npm/:package_name/-/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | | `file_name` | string | yes | The name of the package file. | curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/npm/@myscope/my-pkg/-/@my-scope/my-pkg-0.0.1.tgz" Write the output to a file: curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/npm/@myscope/my-pkg/-/@my-scope/my-pkg-0.0.1.tgz" >> @myscope/my-pkg-0.0.1.tgz This writes the downloaded file to `@myscope/my-pkg-0.0.1.tgz` in the current directory. Upload a package file --------------------- Uploads a package for a specified project. PUT projects/:id/packages/npm/:package_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | | `versions` | string | yes | Package version information. | curl --request PUT --header "Content-Type: application/json" --data @./path/to/metadata/file.json --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/npm/@myscope%2fmy-pkg" The metadata file content is generated by npm, but looks something like this: { "_attachments": { "@myscope/my-pkg-1.3.7.tgz": { "content_type": "application/octet-stream", "data": "H4sIAAAAAAAAE+1TQUvDMBjdeb/iI4edZEldV2dPwhARPIjiyXlI26zN1iYhSeeK7L+bNJtednMg4l4OKe+9PF7DF0XzNS0ZVmEfr4wUgxODEJLEMRzjPRJyCYPJNCFRlCTE+dzH1PvJqYscQ2ss1a7KT3PCv8DX/kfwMQRAgjYMpYBuIoIzKtwy6MILG6YNl8Jr0XgyvgpswUyuubJ75TGMDuSaUcsKyDooa1C6De6G8t7GRcG2br4CGxKME3wDR1hmrLexvJKwQLdaS52CkOAFMIrlfMlZsUAwGgHbcgsRcid3fdqade9SFz7u9a1naGsrqX3gHbcPNINDyydWcmN1By+W19x2oU7NcyZMfwn3z/PAqTaruanmUix5+V3UXVKq9yEoRZW1yqQYl9zWNBvnssFUcbyJsdJyxXJrcHQdz8gsTg6PzGChGty3H+6Gvz0BZ5xxxn/FJ1EDRNIACAAA", "length": 354 } }, "_id": "@myscope/my-pkg", "description": "Package created by me", "dist-tags": { "latest": "1.3.7" }, "name": "@myscope/my-pkg", "readme": "ERROR: No README data found!", "versions": { "1.3.7": { "_id": "@myscope/my-pkg@1.3.7", "_nodeVersion": "12.18.4", "_npmVersion": "6.14.6", "author": { "name": "GitLab package registry Utility" }, "description": "Package created by me", "dist": { "integrity": "sha512-loy16p+Dtw2S43lBmD3Nye+t+Vwv7Tbhv143UN2mwcjaHJyBfGZdNCTXnma3gJCUSE/AR4FPGWEyCOOTJ+ev9g==", "shasum": "4a9dbd94ca6093feda03d909f3d7e6bd89d9d4bf", "tarball": "https://gitlab.example.com/api/v4/projects/1/packages/npm/@myscope/my-pkg/-/@myscope/my-pkg-1.3.7.tgz" }, "keywords": [], "license": "ISC", "main": "index.js", "name": "@myscope/my-pkg", "publishConfig": { "@myscope:registry": "https://gitlab.example.com/api/v4/projects/1/packages/npm" }, "readme": "ERROR: No README data found!", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "version": "1.3.7" } } } Route prefix ------------ For the remaining routes, there are two sets of identical routes that each make requests in different scopes: * Use the instance-level prefix to make requests in the scope of the entire instance. * Use the project-level prefix to make requests in a single project’s scope. * Use the group-level prefix to make requests in a group’s scope. The examples in this document all use the project-level prefix. ### Instance-level /packages/npm ### Project-level /projects/:id/packages/npm | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The project ID or full project path. | ### Group-level History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299834) in GitLab 16.0 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `npm_group_level_endpoints`. Disabled by default. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121837) in GitLab 16.1. Feature flag `npm_group_level_endpoints` removed. /groups/:id/-/packages/npm | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The group ID or full group path. | Retrieve package metadata ------------------------- Retrieves the metadata for a specified package. GET /:package_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `package_name` | string | yes | The name of the package. | curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/npm/@myscope/my-pkg" Example response: { "name": "@myscope/my-pkg", "versions": { "0.0.2": { "name": "@myscope/my-pkg", "version": "0.0.1", "dist": { "shasum": "93abb605b1110c0e3cca0a5b805e5cb01ac4ca9b", "tarball": "https://gitlab.example.com/api/v4/projects/1/packages/npm/@myscope/my-pkg/-/@myscope/my-pkg-0.0.1.tgz" } } }, "dist-tags": { "latest": "0.0.1" } } The URLs in the response have the same route prefix used to request them. If you request them with the instance-level route, the returned URLs contain `/api/v4/packages/npm`. Dist-Tags --------- ### List all dist-tags Lists all dist-tags for a specified package. GET /-/package/:package_name/dist-tags | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `package_name` | string | yes | The name of the package. | curl --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/npm/-/package/@myscope/my-pkg/dist-tags" Example response: { "latest": "2.1.1", "stable": "1.0.0" } The URLs in the response have the same route prefix used to request them. If you request them with the instance-level route, the returned URLs contain `/api/v4/packages/npm`. ### Create or update a dist-tag Creates or updates a specified dist-tag for a package. PUT /-/package/:package_name/dist-tags/:tag | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `package_name` | string | yes | The name of the package. | | `tag` | string | yes | The tag to be created or updated. | | `version` | string | yes | The version to be tagged. | curl --request PUT --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/npm/-/package/@myscope/my-pkg/dist-tags/stable" This endpoint responds successfully with `204 No Content`. ### Delete a dist-tag Deletes a specified dist-tag for a package. DELETE /-/package/:package_name/dist-tags/:tag | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `package_name` | string | yes | The name of the package. | | `tag` | string | yes | The tag to be created or updated. | curl --request DELETE --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects/1/packages/npm/-/package/@myscope/my-pkg/dist-tags/stable" This endpoint responds successfully with `204 No Content`. --- # Namespaces API | GitLab Docs * * * Namespaces API ============== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * Visibility of billing-related fields changed in GitLab 18.3 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `restrict_namespace_api_billing_fields`. Disabled by default. * Visibility of billing-related fields [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/565598) in GitLab 18.9. Feature flag `restrict_namespace_api_billing_fields` removed. Use this API to interact with namespaces, a special resource category used to organize users and groups. For more information, see [namespaces](https://docs.gitlab.com/user/namespace/) . This API uses [Pagination](https://docs.gitlab.com/api/rest/#pagination) to filter results. List all namespaces ------------------- History * `top_level_only` [introduced](https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/7600) in GitLab 16.8. Lists all namespaces available to the current user. If the user is an administrator, this endpoint returns all namespaces in the instance. GET /namespaces | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `search` | string | no | Returns only namespaces that contain the specified value in their name or path. | | `owned_only` | boolean | no | If `true`, only returns namespaces by the current user. | | `top_level_only` | boolean | no | In GitLab 16.8 and later, if `true`, only returns top-level namespaces. | | `full_path_search` | boolean | no | If `true`, the `search` parameter is matched against the full path of the namespaces. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/namespaces" Example response: [\ {\ "id": 1,\ "name": "user1",\ "path": "user1",\ "kind": "user",\ "full_path": "user1",\ "parent_id": null,\ "avatar_url": "https://secure.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",\ "web_url": "https://gitlab.example.com/user1",\ "billable_members_count": 1,\ "plan": "ultimate",\ "end_date": null,\ "trial_ends_on": null,\ "trial": false,\ "root_repository_size": 100,\ "projects_count": 3\ },\ {\ "id": 2,\ "name": "group1",\ "path": "group1",\ "kind": "group",\ "full_path": "group1",\ "parent_id": null,\ "avatar_url": null,\ "web_url": "https://gitlab.example.com/groups/group1",\ "members_count_with_descendants": 2,\ "billable_members_count": 2,\ "plan": "ultimate",\ "end_date": null,\ "trial_ends_on": null,\ "trial": false,\ "root_repository_size": 100,\ "projects_count": 3\ },\ {\ "id": 3,\ "name": "bar",\ "path": "bar",\ "kind": "group",\ "full_path": "foo/bar",\ "parent_id": 9,\ "avatar_url": null,\ "web_url": "https://gitlab.example.com/groups/foo/bar",\ "members_count_with_descendants": 5,\ "billable_members_count": 5,\ "end_date": null,\ "trial_ends_on": null,\ "trial": false,\ "root_repository_size": 100,\ "projects_count": 3\ }\ ] Additional attributes might be returned for Group owners or on GitLab.com: [\ {\ ...\ "max_seats_used": 3,\ "max_seats_used_changed_at":"2025-05-15T12:00:02.000Z",\ "seats_in_use": 2,\ "projects_count": 1,\ "root_repository_size":0,\ "members_count_with_descendants":26,\ "plan": "free",\ ...\ }\ ] Retrieve namespace details -------------------------- Retrieves details for a specified namespace. GET /namespaces/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the namespace. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/namespaces/2" Example response: { "id": 2, "name": "group1", "path": "group1", "kind": "group", "full_path": "group1", "parent_id": null, "avatar_url": null, "web_url": "https://gitlab.example.com/groups/group1", "members_count_with_descendants": 2, "billable_members_count": 2, "max_seats_used": 0, "seats_in_use": 0, "plan": "default", "end_date": null, "trial_ends_on": null, "trial": false, "root_repository_size": 100, "projects_count": 3 } Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/namespaces/group1" Example response: { "id": 2, "name": "group1", "path": "group1", "kind": "group", "full_path": "group1", "parent_id": null, "avatar_url": null, "web_url": "https://gitlab.example.com/groups/group1", "members_count_with_descendants": 2, "billable_members_count": 2, "max_seats_used": 0, "seats_in_use": 0, "plan": "default", "end_date": null, "trial_ends_on": null, "trial": false, "root_repository_size": 100 } Verify namespace availability ----------------------------- Verifies if a specified namespace exists. If the namespace exists, the endpoint suggests an alternate name. GET /namespaces/:namespace/exists | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `namespace` | string | yes | Path of the namespace. | | `parent_id` | integer | no | ID of the parent namespace. If unspecified, only returns top-level namespaces. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/namespaces/my-group/exists?parent_id=1" Example response: { "exists": true, "suggests": [\ "my-group1"\ ] } --- # Project Aliases API | GitLab Docs * * * Project Aliases API =================== * Tier: Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Use this API to manage [project aliases](https://docs.gitlab.com/user/project/working_with_projects/#project-aliases) . After you create an alias for a project, users can clone the repository with the alias, which can be helpful when migrating repositories. All methods require administrator authorization. List all project aliases ------------------------ Get a list of all project aliases: GET /project_aliases If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `id` | integer | ID of the project alias. | | `name` | string | Name of the alias. | | `project_id` | integer | ID of the associated project. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/project_aliases" Example response: [\ {\ "id": 1,\ "project_id": 1,\ "name": "gitlab-foss"\ },\ {\ "id": 2,\ "project_id": 2,\ "name": "gitlab"\ }\ ] Retrieve a project alias ------------------------ Retrieves details of a project alias: GET /project_aliases/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | Yes | The name of the alias. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `id` | integer | ID of the project alias. | | `name` | string | Name of the alias. | | `project_id` | integer | ID of the associated project. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/project_aliases/gitlab" Example response: { "id": 1, "project_id": 1, "name": "gitlab" } Create a project alias ---------------------- Add a new alias for a project: POST /project_aliases Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | Yes | Name of the alias. Must be unique. | | `project_id` | integer or string | Yes | ID or path of the project. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `id` | integer | ID of the project alias. | | `name` | string | Name of the alias. | | `project_id` | integer | ID of the associated project. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/project_aliases" \ --form "project_id=1" \ --form "name=gitlab" You can also use the project path: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/project_aliases" \ --form "project_id=gitlab-org/gitlab" \ --form "name=gitlab" Example response: { "id": 1, "project_id": 1, "name": "gitlab" } Delete a project alias ---------------------- Remove a project alias: DELETE /project_aliases/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | Yes | Name of the alias. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/project_aliases/gitlab" --- # Pages domains API | GitLab Docs * * * Pages domains API ================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed Use this API to manage [GitLab Pages domains](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/) . The GitLab Pages feature must be enabled to use these endpoints. Find out more about [administering](https://docs.gitlab.com/administration/pages/) and [using](https://docs.gitlab.com/user/project/pages/) the feature. List all Pages domains ---------------------- Lists all Pages domains on the instance. Prerequisites: * You must have administrator access to the instance. GET /pages/domains Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `domain` | string | no | The domain of the GitLab Pages site to filter on. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `domain` | string | The custom domain name for the GitLab Pages site. | | `url` | string | The full URL of the Pages site, including the protocol. | | `project_id` | integer | The ID of the GitLab project associated with this Pages domain. | | `verified` | boolean | Indicates whether the domain has been verified. | | `verification_code` | string | A unique record used to verify domain ownership. | | `enabled_until` | date | The date until which the domain is enabled. This updates periodically as the domain is reverified. | | `auto_ssl_enabled` | boolean | Indicates if [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates using Let’s Encrypt is enabled for this domain. | | `certificate_expiration` | object | Information about the SSL certificate expiration. | | `certificate_expiration.expired` | boolean | Indicates whether the SSL certificate has expired. | | `certificate_expiration.expiration` | date | The expiration date and time of the SSL certificate. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/pages/domains" Example response: [\ {\ "domain": "ssl.domain.example",\ "url": "https://ssl.domain.example",\ "project_id": 1337,\ "verified": true,\ "verification_code": "1234567890abcdef",\ "enabled_until": "2020-04-12T14:32:00.000Z",\ "auto_ssl_enabled": false,\ "certificate": {\ "expired": false,\ "expiration": "2020-04-12T14:32:00.000Z"\ }\ }\ ] List all Pages domains in a project ----------------------------------- Lists all Pages domains in the specified project. The user must have permissions to view Pages domains. GET /projects/:id/pages/domains Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `domain` | string | The custom domain name for the GitLab Pages site. | | `url` | string | The full URL of the Pages site, including the protocol. | | `verified` | boolean | Indicates whether the domain has been verified. | | `verification_code` | string | A unique record used to verify domain ownership. | | `enabled_until` | date | The date until which the domain is enabled. This updates periodically as the domain is reverified. | | `auto_ssl_enabled` | boolean | Indicates if [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates using Let’s Encrypt is enabled for this domain. | | `certificate` | object | Information about the SSL certificate. | | `certificate.subject` | string | The subject of the SSL certificate, typically containing information about the domain. | | `certificate.expired` | date | Indicates whether the SSL certificate has expired (true) or is still valid (false). | | `certificate.certificate` | string | The full SSL certificate in PEM format. | | `certificate.certificate_text` | date | A human-readable text representation of the SSL certificate, including details such as issuer, validity period, subject, and other certificate information. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains" Example response: [\ {\ "domain": "www.domain.example",\ "url": "http://www.domain.example",\ "verified": true,\ "verification_code": "1234567890abcdef",\ "enabled_until": "2020-04-12T14:32:00.000Z",\ "auto_ssl_enabled": false,\ },\ {\ "domain": "ssl.domain.example",\ "url": "https://ssl.domain.example",\ "verified": true,\ "verification_code": "1234567890abcdef",\ "enabled_until": "2020-04-12T14:32:00.000Z",\ "auto_ssl_enabled": false,\ "certificate": {\ "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",\ "expired": false,\ "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",\ "certificate_text": "Certificate:\n … \n"\ }\ }\ ] Retrieve a Pages domain ----------------------- Retrieves a Pages domain from the specified project. The user must have permissions to view Pages domains. GET /projects/:id/pages/domains/:domain Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `domain` | string | yes | The custom domain indicated by the user | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `domain` | string | The custom domain name for the GitLab Pages site. | | `url` | string | The full URL of the Pages site, including the protocol. | | `verified` | boolean | Indicates whether the domain has been verified. | | `verification_code` | string | A unique record used to verify domain ownership. | | `enabled_until` | date | The date until which the domain is enabled. This updates periodically as the domain is reverified. | | `auto_ssl_enabled` | boolean | Indicates if [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates using Let’s Encrypt is enabled for this domain. | | `certificate` | object | Information about the SSL certificate. | | `certificate.subject` | string | The subject of the SSL certificate, typically containing information about the domain. | | `certificate.expired` | date | Indicates whether the SSL certificate has expired (true) or is still valid (false). | | `certificate.certificate` | string | The full SSL certificate in PEM format. | | `certificate.certificate_text` | date | A human-readable text representation of the SSL certificate, including details such as issuer, validity period, subject, and other certificate information. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example" Example response: { "domain": "ssl.domain.example", "url": "https://ssl.domain.example", "verified": true, "verification_code": "1234567890abcdef", "enabled_until": "2020-04-12T14:32:00.000Z", "auto_ssl_enabled": false, "certificate": { "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate", "expired": false, "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----", "certificate_text": "Certificate:\n … \n" } } Create new Pages domain ----------------------- Creates a Pages domain in the specified project. The user must have permissions to create new Pages domains. POST /projects/:id/pages/domains Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `domain` | string | yes | The custom domain indicated by the user | | `auto_ssl_enabled` | boolean | no | Enables [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates issued by Let’s Encrypt for custom domains. | | `certificate` | file/string | no | The certificate in PEM format with intermediates following in most specific to least specific order. | | `key` | file/string | no | The certificate key in PEM format. | If successful, returns [`201`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `domain` | string | The custom domain name for the GitLab Pages site. | | `url` | string | The full URL of the Pages site, including the protocol. | | `verified` | boolean | Indicates whether the domain has been verified. | | `verification_code` | string | A unique record used to verify domain ownership. | | `enabled_until` | date | The date until which the domain is enabled. This updates periodically as the domain is reverified. | | `auto_ssl_enabled` | boolean | Indicates if [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates using Let’s Encrypt is enabled for this domain. | | `certificate` | object | Information about the SSL certificate. | | `certificate.subject` | string | The subject of the SSL certificate, typically containing information about the domain. | | `certificate.expired` | date | Indicates whether the SSL certificate has expired (true) or is still valid (false). | | `certificate.certificate` | string | The full SSL certificate in PEM format. | | `certificate.certificate_text` | date | A human-readable text representation of the SSL certificate, including details such as issuer, validity period, subject, and other certificate information. | Example requests: Create a new Pages domain with a certificate from a `.pem` file: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains" \ --form "domain=ssl.domain.example" \ --form "certificate=@/path/to/cert.pem" \ --form "key=@/path/to/key.pem" Create a new Pages domain by using a variable containing the certificate: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains" \ --form "domain=ssl.domain.example" \ --form "certificate=$CERT_PEM" \ --form "key=$KEY_PEM" Create a new Pages domain with an [automatic certificate](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/#enabling-lets-encrypt-integration-for-your-custom-domain) : curl --request POST --header "PRIVATE-TOKEN: " --form "domain=ssl.domain.example" \ --form "auto_ssl_enabled=true" "https://gitlab.example.com/api/v4/projects/5/pages/domains" Example response: { "domain": "ssl.domain.example", "url": "https://ssl.domain.example", "auto_ssl_enabled": true, "certificate": { "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate", "expired": false, "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----", "certificate_text": "Certificate:\n … \n" } } Update Pages domain ------------------- Updates the specified Pages domain in a project. The user must have permissions to change an existing Pages domain. PUT /projects/:id/pages/domains/:domain Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `domain` | string | yes | The custom domain indicated by the user | | `auto_ssl_enabled` | boolean | no | Enables [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates issued by Let’s Encrypt for custom domains. | | `certificate` | file/string | no | The certificate in PEM format with intermediates following in most specific to least specific order. | | `key` | file/string | no | The certificate key in PEM format. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `domain` | string | The custom domain name for the GitLab Pages site. | | `url` | string | The full URL of the Pages site, including the protocol. | | `verified` | boolean | Indicates whether the domain has been verified. | | `verification_code` | string | A unique record used to verify domain ownership. | | `enabled_until` | date | The date until which the domain is enabled. This updates periodically as the domain is reverified. | | `auto_ssl_enabled` | boolean | Indicates if [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates using Let’s Encrypt is enabled for this domain. | | `certificate` | object | Information about the SSL certificate. | | `certificate.subject` | string | The subject of the SSL certificate, typically containing information about the domain. | | `certificate.expired` | date | Indicates whether the SSL certificate has expired (true) or is still valid (false). | | `certificate.certificate` | string | The full SSL certificate in PEM format. | | `certificate.certificate_text` | date | A human-readable text representation of the SSL certificate, including details such as issuer, validity period, subject, and other certificate information. | ### Adding certificate Add a certificate for a Pages domain from a `.pem` file: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example" \ --form "certificate=@/path/to/cert.pem" \ --form "key=@/path/to/key.pem" Add a certificate for a Pages domain by using a variable containing the certificate: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example" \ --form "certificate=$CERT_PEM" \ --form "key=$KEY_PEM" Example response: { "domain": "ssl.domain.example", "url": "https://ssl.domain.example", "auto_ssl_enabled": false, "certificate": { "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate", "expired": false, "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----", "certificate_text": "Certificate:\n … \n" } } ### Enabling Let’s Encrypt integration for Pages custom domains curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example" \ --form "auto_ssl_enabled=true" Example response: { "domain": "ssl.domain.example", "url": "https://ssl.domain.example", "auto_ssl_enabled": true } ### Removing certificate To remove the SSL certificate attached to the Pages domain, run: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example" \ --form "certificate=" \ --form "key=" Example response: { "domain": "ssl.domain.example", "url": "https://ssl.domain.example", "auto_ssl_enabled": false } Verify Pages domain ------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21261) in GitLab 17.7. Verifies the specified Pages domain in a project. The user must have permissions to update Pages domains. PUT /projects/:id/pages/domains/:domain/verify Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or URL-encoded path of the project | | `domain` | string | yes | The custom domain to verify | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `domain` | string | The custom domain name for the GitLab Pages site. | | `url` | string | The full URL of the Pages site, including the protocol. | | `verified` | boolean | Indicates whether the domain has been verified. | | `verification_code` | string | A unique record used to verify domain ownership. | | `enabled_until` | date | The date until which the domain is enabled. This updates periodically as the domain is reverified. | | `auto_ssl_enabled` | boolean | Indicates if [automatic generation](https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration/)
of SSL certificates using Let’s Encrypt is enabled for this domain. | | `certificate` | object | Information about the SSL certificate. | | `certificate.subject` | string | The subject of the SSL certificate, typically containing information about the domain. | | `certificate.expired` | date | Indicates whether the SSL certificate has expired (true) or is still valid (false). | | `certificate.certificate` | string | The full SSL certificate in PEM format. | | `certificate.certificate_text` | date | A human-readable text representation of the SSL certificate, including details such as issuer, validity period, subject, and other certificate information. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example/verify" Example response: { "domain": "ssl.domain.example", "url": "https://ssl.domain.example", "auto_ssl_enabled": false, "verified": true, "verification_code": "1234567890abcdef", "enabled_until": "2020-04-12T14:32:00.000Z" } Delete Pages domain ------------------- Deletes the specified Pages domain in a project. DELETE /projects/:id/pages/domains/:domain Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `domain` | string | yes | The custom domain indicated by the user | If successful, a `204 No Content` HTTP response with an empty body is expected. Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example" --- # Performance tuning and testing speed | GitLab Docs * * * Performance tuning and testing speed ==================================== Security tools that perform dynamic analysis testing, such as API security testing, perform testing by sending requests to an instance of your running application. The requests are engineered to test for specific vulnerabilities that might exist in your application. The speed of a dynamic analysis test depends on the following: * How many requests per second can be sent to your application by GitLab tooling * How fast your application responds to requests * How many requests must be sent to test the application * How many operations your API is comprised of * How many fields are in each operation (think JSON bodies, headers, query string, cookies, etc.) If the API security testing job still takes longer than expected reach after following the advice in this performance guide, reach out to support for further assistance. Diagnosing performance issues ----------------------------- The first step to resolving performance issues is to understand what is contributing to the slower-than-expected testing time. Some commonly reported issues are: * API security testing is running on a low-vCPU runner * The application deployed to a slow/single-CPU instance and is not able to keep up with the testing load * The application contains a slow operation that impacts the overall test speed (> 1/2 second) * The application contains an operation that returns a large amount of data (> 500K+) * The application contains a large number of operations (> 40) ### The application contains a slow operation that impacts the overall test speed (> 1/2 second) The API security testing job output contains helpful information about testing speed, operation response times, and summary information. The following sample output shows how you can use a summary output in tracking down performance issues: API SECURITY: Loaded 10 operations from: assets/har-large-response/large_responses.har API SECURITY: API SECURITY: Testing operation [1/10]: 'GET http://target:7777/api/large_response_json'. API SECURITY: - Parameters: (Headers: 4, Query: 0, Body: 0) API SECURITY: - Request body size: 0 Bytes (0 bytes) API SECURITY: API SECURITY: Finished testing operation 'GET http://target:7777/api/large_response_json'. API SECURITY: - Excluded Parameters: (Headers: 0, Query: 0, Body: 0) API SECURITY: - Performed 767 requests API SECURITY: - Average response body size: 130 MB API SECURITY: - Average call time: 2 seconds and 82.69 milliseconds (2.082693 seconds) API SECURITY: - Time to complete: 14 minutes, 8 seconds and 788.36 milliseconds (848.788358 seconds) The job console output snippet starts with how many operations were found (10). Next, it notifies that testing started on a specific operation and a summary of the operation has been completed. The summary shows that it took API security testing 767 requests to fully test this operation and its related fields. The summary also shows that the operation had an average response time of 2 seconds, and took 14 minutes to complete. An average response time of 2 seconds is a good initial indicator that this specific operation takes a long time to test. The summary also shows a large response body size, which causes the long response time. Most of the response time on each request is spent transferring the response body data. For this issue, the team might decide to: * Use a runner with more vCPUs, as this allows API security testing to parallelize the work being performed. This helps lower the test time, but getting the test down under 10 minutes might still be problematic without moving to a high CPU machine due to how long the operation takes to test. While larger runners are more costly, you also pay for less minutes if the job executions are quicker. * [Exclude this operation](https://docs.gitlab.com/user/application_security/api_security_testing/performance/#excluding-slow-operations) from API security testing. While this is the simplest, it has the downside of a gap in security test coverage. * [Exclude the operation from feature branch API security testing, but include it in the default branch test](https://docs.gitlab.com/user/application_security/api_security_testing/performance/#excluding-operations-in-feature-branches-but-not-default-branch) . * [Split up API security testing into multiple jobs](https://docs.gitlab.com/user/application_security/api_security_testing/performance/#splitting-a-test-into-multiple-jobs) . The likely solution is to use a combination of these solutions to reach an acceptable test time, assuming your team’s requirements are in the 5-7 minute range. Addressing performance issues ----------------------------- The following sections document various options for addressing performance issues for API security testing: * [Using a larger runner](https://docs.gitlab.com/user/application_security/api_security_testing/performance/#using-a-larger-runner) * [Excluding slow operations](https://docs.gitlab.com/user/application_security/api_security_testing/performance/#excluding-slow-operations) * [Splitting a test into multiple jobs](https://docs.gitlab.com/user/application_security/api_security_testing/performance/#splitting-a-test-into-multiple-jobs) * [Excluding operations in feature branches, but not default branch](https://docs.gitlab.com/user/application_security/api_security_testing/performance/#excluding-operations-in-feature-branches-but-not-default-branch) ### Using a larger runner One of the easiest performance boosts can be achieved using a [larger runner](https://docs.gitlab.com/ci/runners/hosted_runners/linux/#machine-types-available-for-linux---x86-64) with API security testing. This table shows statistics collected during benchmarking of a Java Spring Boot REST API. In this benchmark, the target and API security testing share a single runner instance. | Hosted runner on Linux tag | Requests per second | | --- | --- | | `saas-linux-small-amd64` (default) | 255 | | `saas-linux-medium-amd64` | 400 | This table shows how increasing the size of the runner and vCPU count can have a large impact on testing speed/performance. Here is an example job definition for API security testing that adds a `tags` section to use the medium GitLab-hosted runner on Linux. The job extends the job definition included through the API security testing template. api_security: tags: - saas-linux-medium-amd64 In the `gl-api-security-scanner.log` file you can search for the string `Starting work item processor` to inspect the reported max DOP (degree of parallelism). The max DOP should be greater than or equal to the number of vCPUs assigned to the runner. If unable to identify the problem, open a ticket with support to assist. Example log entry: `17:00:01.084 [INF] Starting work item processor with 4 max DOP` ### Excluding slow operations In the case of one or two slow operations, the team might decide to skip testing the operations. Excluding the operation is done using the `APISEC_EXCLUDE_PATHS` configuration [variable as explained in this section.](https://docs.gitlab.com/user/application_security/api_security_testing/configuration/customizing_analyzer_settings/#exclude-paths) This example shows an operation that returns a large amount of data. The operation is `GET http://target:7777/api/large_response_json`. To exclude it, provide the `APISEC_EXCLUDE_PATHS` configuration variable with the path portion of the operation URL `/api/large_response_json`. To verify the operation is excluded, run the API security testing job and review the job console output. It includes a list of included and excluded operations at the end of the test. api_security: variables: APISEC_EXCLUDE_PATHS: /api/large_response_json Excluding operations from testing could allow some vulnerabilities to go undetected. ### Splitting a test into multiple jobs Splitting a test into multiple jobs is supported by API security testing through the use of [`APISEC_EXCLUDE_PATHS`](https://docs.gitlab.com/user/application_security/api_security_testing/configuration/customizing_analyzer_settings/#exclude-paths) and [`APISEC_EXCLUDE_URLS`](https://docs.gitlab.com/user/application_security/api_security_testing/configuration/customizing_analyzer_settings/#exclude-urls) . When splitting a test up, a good pattern is to disable the `dast_api` job and replace it with two jobs with identifying names. This example shows two jobs. Each job tests a version of the API, as their names reflect. However, this technique can be applied to any situation, not just with versions of an API. The rules used in the `APISEC_v1` and `APISEC_v2` jobs are copied from the [API security testing template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/API-Security.gitlab-ci.yml) . # Disable the main dast_api job api_security: rules: - if: $CI_COMMIT_BRANCH when: never APISEC_v1: extends: dast_api variables: APISEC_EXCLUDE_PATHS: /api/v1/** rules: - if: $APISEC_DISABLED == 'true' || $APISEC_DISABLED == '1' when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == 'true' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == '1' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: APISEC_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH APISEC_v2: variables: APISEC_EXCLUDE_PATHS: /api/v2/** rules: - if: $APISEC_DISABLED == 'true' || $APISEC_DISABLED == '1' when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == 'true' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == '1' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: APISEC_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH ### Excluding operations in feature branches, but not default branch In the case of one or two slow operations, the team might decide to skip testing the operations, or exclude them from feature branch tests, but include them for default branch tests. Excluding the operation is done using the `APISEC_EXCLUDE_PATHS` configuration [variable as explained in this section.](https://docs.gitlab.com/user/application_security/api_security_testing/configuration/customizing_analyzer_settings/#exclude-paths) This example shows an operation that returns a large amount of data. The operation is `GET http://target:7777/api/large_response_json`. To exclude it, provide the `APISEC_EXCLUDE_PATHS` configuration variable with the path portion of the operation URL `/api/large_response_json`. The configuration disables the main `dast_api` job and creates two new jobs `APISEC_main` and `APISEC_branch`. The `APISEC_branch` is set up to exclude the long operation and only run on non-default branches (for example, feature branches). The `APISEC_main` branch is set up to only execute on the default branch (`main` in this example). The `APISEC_branch` jobs run faster, allowing for quick development cycles, while the `APISEC_main` job which only runs on default branch builds, takes longer to run. To verify the operation is excluded, run the API security testing job and review the job console output. It includes a list of included and excluded operations at the end of the test. # Disable the main job so you can create two jobs with # different names api_security: rules: - if: $CI_COMMIT_BRANCH when: never # API security testing for feature branch work, excludes /api/large_response_json APISEC_branch: extends: dast_api variables: APISEC_EXCLUDE_PATHS: /api/large_response_json rules: - if: $APISEC_DISABLED == 'true' || $APISEC_DISABLED == '1' when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == 'true' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == '1' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: APISEC_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: never - if: $CI_COMMIT_BRANCH # API security testing for default branch (main in this case) # Includes the long running operations APISEC_main: extends: dast_api rules: - if: $APISEC_DISABLED == 'true' || $APISEC_DISABLED == '1' when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == 'true' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $APISEC_DISABLED_FOR_DEFAULT_BRANCH == '1' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: APISEC_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH --- # Pipeline trigger tokens API | GitLab Docs * * * Pipeline trigger tokens API =========================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to [trigger pipelines](https://docs.gitlab.com/ci/triggers/) . List project trigger tokens --------------------------- Lists a project’s pipeline trigger tokens. GET /projects/:id/triggers | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/triggers" [\ {\ "id": 10,\ "description": "my trigger",\ "created_at": "2016-01-07T09:53:58.235Z",\ "last_used": null,\ "token": "6d056f63e50fe6f8c5f8f4aa10edb7",\ "updated_at": "2016-01-07T09:53:58.235Z",\ "owner": null\ }\ ] The trigger token is displayed in full if the trigger token was created by the authenticated user. Trigger tokens created by other users are shortened to four characters. Retrieve trigger token details ------------------------------ Retrieves details of a project’s pipeline trigger token. GET /projects/:id/triggers/:trigger_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `trigger_id` | integer | Yes | The trigger ID | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/triggers/5" { "id": 10, "description": "my trigger", "created_at": "2016-01-07T09:53:58.235Z", "last_used": null, "token": "6d056f63e50fe6f8c5f8f4aa10edb7", "updated_at": "2016-01-07T09:53:58.235Z", "owner": null } Create a trigger token ---------------------- Creates a pipeline trigger token for a project. POST /projects/:id/triggers | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `description` | string | Yes | The trigger name | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | curl --request POST \ --header "PRIVATE-TOKEN: " \ --form description="my description" \ --url "https://gitlab.example.com/api/v4/projects/1/triggers" { "id": 10, "description": "my trigger", "created_at": "2016-01-07T09:53:58.235Z", "last_used": null, "token": "6d056f63e50fe6f8c5f8f4aa10edb7", "updated_at": "2016-01-07T09:53:58.235Z", "owner": null } Update a pipeline trigger token ------------------------------- Updates a project’s pipeline trigger token. PUT /projects/:id/triggers/:trigger_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `trigger_id` | integer | Yes | The trigger ID | | `description` | string | No | The trigger name | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --form description="my description" \ --url "https://gitlab.example.com/api/v4/projects/1/triggers/10" { "id": 10, "description": "my trigger", "created_at": "2016-01-07T09:53:58.235Z", "last_used": null, "token": "6d056f63e50fe6f8c5f8f4aa10edb7", "updated_at": "2016-01-07T09:53:58.235Z", "owner": null } Delete a pipeline trigger token ------------------------------- Deletes a project’s pipeline trigger token. DELETE /projects/:id/triggers/:trigger_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `trigger_id` | integer | Yes | The trigger ID | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/triggers/5" Trigger a pipeline with a token ------------------------------- History * `inputs` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/519958) in GitLab 17.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `ci_inputs_for_pipelines`. Disabled by default. * `inputs` attribute [enabled on GitLab.com, GitLab Self-Managed, and GitLab Dedicated](https://gitlab.com/gitlab-org/gitlab/-/issues/525504) in GitLab 17.11. * `inputs` attribute [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/536548) in GitLab 18.1. Feature flag `ci_inputs_for_pipelines` removed. Triggers a pipeline by using a [pipeline trigger token](https://docs.gitlab.com/ci/triggers/#create-a-pipeline-trigger-token) or a [CI/CD job token](https://docs.gitlab.com/ci/jobs/ci_job_token/) for authentication. With a CI/CD job token, the [triggered pipeline is a multi-project pipeline](https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#trigger-a-multi-project-pipeline-by-using-the-api) . The job that authenticates the request becomes associated with the upstream pipeline, which is visible on the pipeline graph. If you use a trigger token in a job, the job is not associated with the upstream pipeline. POST /projects/:id/trigger/pipeline Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `ref` | string | Yes | The branch or tag to run the pipeline on. | | `token` | string | Yes | The trigger token or CI/CD job token. | | `variables` | hash | No | A map of key-valued strings containing the pipeline variables. For example: `{ VAR1: "value1", VAR2: "value2" }`. | | `inputs` | hash | No | A map of inputs, as key-value pairs, to use when creating the pipeline. | Example request with [variables](https://docs.gitlab.com/ci/variables/) : curl --request POST \ --form "variables[VAR1]=value1" \ --form "variables[VAR2]=value2" \ --url "https://gitlab.example.com/api/v4/projects/123/trigger/pipeline?token=2cb1840fb9dfc9fb0b7b1609cd29cb&ref=main" Example request with [inputs](https://docs.gitlab.com/ci/inputs/) : curl --request POST \ --header "Content-Type: application/json" \ --data '{"inputs": {"environment": "environment", "scan_security": false, "level": 3}}' \ --url "https://gitlab.example.com/api/v4/projects/123/trigger/pipeline?token=2cb1840fb9dfc9fb0b7b1609cd29cb&ref=main" Example response: { "id": 257, "iid": 118, "project_id": 123, "sha": "91e2711a93e5d9e8dddfeb6d003b636b25bf6fc9", "ref": "main", "status": "created", "source": "trigger", "created_at": "2022-03-31T01:12:49.068Z", "updated_at": "2022-03-31T01:12:49.068Z", "web_url": "http://127.0.0.1:3000/test-group/test-project/-/pipelines/257", "before_sha": "0000000000000000000000000000000000000000", "tag": false, "yaml_errors": null, "user": { "id": 1, "username": "root", "name": "Administrator", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://127.0.0.1:3000/root" }, "started_at": null, "finished_at": null, "committed_at": null, "duration": null, "queued_duration": null, "coverage": null, "detailed_status": { "icon": "status_created", "text": "created", "label": "created", "group": "created", "tooltip": "created", "has_details": true, "details_path": "/test-group/test-project/-/pipelines/257", "illustration": null, "favicon": "/assets/ci_favicons/favicon_status_created-4b975aa976d24e5a3ea7cd9a5713e6ce2cd9afd08b910415e96675de35f64955.png" }, "archived": false } --- # Performance tuning and testing speed | GitLab Docs * * * Performance tuning and testing speed ==================================== Security tools that perform API fuzz testing, such as API fuzzing, perform testing by sending requests to an instance of your running application. The requests are mutated by the fuzzing engine to trigger unexpected behavior that might exist in your application. The speed of an API fuzzing test depends on the following: * How many requests per second can be sent to your application by GitLab tooling * How fast your application responds to requests * How many requests must be sent to test the application * How many operations your API is comprised of * How many fields are in each operation (think JSON bodies, headers, query string, cookies, etc.) If API fuzzing testing job still takes longer than expected after following the advice in this performance guide, reach out to support for further assistance. Diagnosing performance issues ----------------------------- The first step to resolving performance issues is to understand what is contributing to the slower-than-expected testing time. Some commonly reported issues are: * API fuzzing is running on a low-vCPU runner * The application deployed to a slow/single-CPU instance and is not able to keep up with the testing load * The application contains a slow operation that impacts the overall test speed (> 1/2 second) * The application contains an operation that returns a large amount of data (> 500K+) * The application contains a large number of operations (> 40) ### The application contains a slow operation that impacts the overall test speed (> 1/2 second) The API fuzzing job output contains helpful information about testing speed, operation response times, and summary information. Use the following sample output to track down performance issues: API Fuzzing: Loaded 10 operations from: assets/har-large-response/large_responses.har API Fuzzing: API Fuzzing: Testing operation [1/10]: 'GET http://target:7777/api/large_response_json'. API Fuzzing: - Parameters: (Headers: 4, Query: 0, Body: 0) API Fuzzing: - Request body size: 0 Bytes (0 bytes) API Fuzzing: API Fuzzing: Finished testing operation 'GET http://target:7777/api/large_response_json'. API Fuzzing: - Excluded Parameters: (Headers: 0, Query: 0, Body: 0) API Fuzzing: - Performed 767 requests API Fuzzing: - Average response body size: 130 MB API Fuzzing: - Average call time: 2 seconds and 82.69 milliseconds (2.082693 seconds) API Fuzzing: - Time to complete: 14 minutes, 8 seconds and 788.36 milliseconds (848.788358 seconds) The job console output snippet starts with how many operations were found (10). Next are notifications that testing has started on a specific operation, and an operation summary has been completed. The summary shows that API fuzzing took 767 requests to fully test this operation and its related fields. The summary also shows that this operation took 14 minutes to complete, with an average response time of 2 seconds. An average response time of two seconds is an initial indicator that this specific operation takes a long time to test. You can also see that the response body size is large, which is the cause of the long response time. Most of the response time on each request is spent transferring the response body data. For this issue, the team might decide to: * Use a runner with more vCPUs, because this allows API fuzzing to parallelize the work being performed. This helps lower the test time, but getting the test down under 10 minutes might still be problematic without moving to a high CPU machine due to how long the operation takes to test. While larger runners are more costly, you also pay for less minutes if the job executions are quicker. * [Exclude this operation](https://docs.gitlab.com/user/application_security/api_fuzzing/performance/#excluding-slow-operations) from the API fuzzing test. While this is the simplest, it has the downside of a gap in security test coverage. * [Exclude the operation from feature branch API fuzzing tests, but include it in the default branch test](https://docs.gitlab.com/user/application_security/api_fuzzing/performance/#excluding-operations-in-feature-branches-but-not-default-branch) . * [Split up the API fuzzing testing into multiple jobs](https://docs.gitlab.com/user/application_security/api_fuzzing/performance/#splitting-a-test-into-multiple-jobs) . The likely solution is to use a combination of these solutions to reach an acceptable test time, assuming your team’s requirements are in the 5-7 minute range. Addressing performance issues ----------------------------- The following sections document various options for addressing performance issues for API fuzzing: * [Using a larger runner](https://docs.gitlab.com/user/application_security/api_fuzzing/performance/#using-a-larger-runner) * [Excluding slow operations](https://docs.gitlab.com/user/application_security/api_fuzzing/performance/#excluding-slow-operations) * [Splitting a test into multiple jobs](https://docs.gitlab.com/user/application_security/api_fuzzing/performance/#splitting-a-test-into-multiple-jobs) * [Excluding operations in feature branches, but not default branch](https://docs.gitlab.com/user/application_security/api_fuzzing/performance/#excluding-operations-in-feature-branches-but-not-default-branch) ### Using a larger runner One of the easiest performance boosts can be achieved using a [larger runner](https://docs.gitlab.com/ci/runners/hosted_runners/linux/#machine-types-available-for-linux---x86-64) with API fuzzing. This table shows statistics collected during benchmarking of a Java Spring Boot REST API. In this benchmark, the target and API fuzzing share a single runner instance. | Hosted runner on Linux tag | Requests per second | | --- | --- | | `saas-linux-small-amd64` (default) | 255 | | `saas-linux-medium-amd64` | 400 | This table shows how increasing the size of the runner and vCPU count can have a large impact on testing speed/performance. Here is an example job definition for API fuzzing that adds a `tags` section to use the medium GitLab-hosted runner on Linux. The job extends the job definition included through the API fuzzing template. apifuzzer_fuzz: tags: - saas-linux-medium-amd64 In the `gl-api-security-scanner.log` file you can search for the string `Starting work item processor` to inspect the reported max DOP (degree of parallelism). The max DOP should be greater than or equal to the number of vCPUs assigned to the runner. If unable to identify the problem, open a ticket with support to assist. Example log entry: `17:00:01.084 [INF] Starting work item processor with 4 max DOP` ### Excluding slow operations In the case of one or two slow operations, the team might decide to skip testing the operations. Excluding the operation is done using the `FUZZAPI_EXCLUDE_PATHS` configuration [variable as explained in this section.](https://docs.gitlab.com/user/application_security/api_fuzzing/configuration/customizing_analyzer_settings/#exclude-paths) This example shows an operation that returns a large amount of data. The operation is `GET http://target:7777/api/large_response_json`. To exclude it, provide the `FUZZAPI_EXCLUDE_PATHS` configuration variable with the path portion of the operation URL `/api/large_response_json`. To verify the operation is excluded, run the API fuzzing job and review the job console output. It includes a list of included and excluded operations at the end of the test. apifuzzer_fuzz: variables: FUZZAPI_EXCLUDE_PATHS: /api/large_response_json Excluding operations from testing could allow some vulnerabilities to go undetected. ### Splitting a test into multiple jobs Splitting a test into multiple jobs is supported by API fuzzing through the use of [`FUZZAPI_EXCLUDE_PATHS`](https://docs.gitlab.com/user/application_security/api_fuzzing/configuration/customizing_analyzer_settings/#exclude-paths) and [`FUZZAPI_EXCLUDE_URLS`](https://docs.gitlab.com/user/application_security/api_fuzzing/configuration/customizing_analyzer_settings/#exclude-urls) . When splitting a test up, a good pattern is to disable the `apifuzzer_fuzz` job and replace it with two jobs with identifying names. This example shows two jobs. Each job tests a version of the API, as their names reflect. However, this technique can be applied to any situation, not just with versions of an API. The rules used in the `apifuzzer_v1` and `apifuzzer_v2` jobs are copied from the [API fuzzing template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) . # Disable the main apifuzzer_fuzz job apifuzzer_fuzz: rules: - if: $CI_COMMIT_BRANCH when: never apifuzzer_v1: extends: apifuzzer_fuzz variables: FUZZAPI_EXCLUDE_PATHS: /api/v1/** rules: - if: $API_FUZZING_DISABLED == 'true' || $API_FUZZING_DISABLED == '1' when: never - if: $API_FUZZING_DISABLED_FOR_DEFAULT_BRANCH == 'true' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $API_FUZZING_DISABLED_FOR_DEFAULT_BRANCH == '1' && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: FUZZAPI_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH apifuzzer_v2: variables: FUZZAPI_EXCLUDE_PATHS: /api/v2/** rules: - if: $API_FUZZING_DISABLED == 'true' || $API_FUZZING_DISABLED == '1' when: never - if: $API_FUZZING_DISABLED_FOR_DEFAULT_BRANCH && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: FUZZAPI_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH ### Excluding operations in feature branches, but not default branch In the case of one or two slow operations, the team might decide to skip testing the operations, or exclude them from feature branch tests, but include them for default branch tests. Excluding the operation is done using the `FUZZAPI_EXCLUDE_PATHS` configuration [variable as explained in this section.](https://docs.gitlab.com/user/application_security/api_fuzzing/configuration/customizing_analyzer_settings/#exclude-paths) This example shows an operation that returns a large amount of data. The operation is `GET http://target:7777/api/large_response_json`. To exclude it, provide the `FUZZAPI_EXCLUDE_PATHS` configuration variable with the path portion of the operation URL `/api/large_response_json`. The configuration disables the main `apifuzzer_fuzz` job and creates two new jobs `apifuzzer_main` and `apifuzzer_branch`. The `apifuzzer_branch` is set up to exclude the long operation and only run on non-default branches (for example, feature branches). The `apifuzzer_main` branch is set up to only execute on the default branch (`main` in this example). The `apifuzzer_branch` jobs run faster, allowing for quick development cycles, while the `apifuzzer_main` job which only runs on default branch builds, takes longer to run. To verify the operation is excluded, run the API fuzzing job and review the job console output. It includes a list of included and excluded operations at the end of the test. # Disable the main job so you can create two jobs with # different names apifuzzer_fuzz: rules: - if: $CI_COMMIT_BRANCH when: never # API fuzzing for feature branch work, excludes /api/large_response_json apifuzzer_branch: extends: apifuzzer_fuzz variables: FUZZAPI_EXCLUDE_PATHS: /api/large_response_json rules: - if: $API_FUZZING_DISABLED == 'true' || $API_FUZZING_DISABLED == '1' when: never - if: $API_FUZZING_DISABLED_FOR_DEFAULT_BRANCH && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: FUZZAPI_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: never - if: $CI_COMMIT_BRANCH # API fuzzing for default branch (main in this case) # Includes the long running operations apifuzzer_main: extends: apifuzzer_fuzz rules: - if: $API_FUZZING_DISABLED == 'true' || $API_FUZZING_DISABLED == '1' when: never - if: $API_FUZZING_DISABLED_FOR_DEFAULT_BRANCH && $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME when: never - if: $CI_COMMIT_BRANCH && $CI_GITLAB_FIPS_MODE == "true" variables: FUZZAPI_IMAGE_SUFFIX: "-fips" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH --- # Project access tokens API | GitLab Docs * * * Project access tokens API ========================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with project access tokens. For more information, see [Project access tokens](https://docs.gitlab.com/user/project/settings/project_access_tokens/) . List all project access tokens ------------------------------ History * `state` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/462217) in GitLab 17.2. Lists all project access tokens for a specified project. GET projects/:id/access_tokens GET projects/:id/access_tokens?state=inactive | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `created_after` | datetime (ISO 8601) | No | If defined, returns tokens created after the specified time. | | `created_before` | datetime (ISO 8601) | No | If defined, returns tokens created before the specified time. | | `expires_after` | date (ISO 8601) | No | If defined, returns tokens that expire after the specified time. | | `expires_before` | date (ISO 8601) | No | If defined, returns tokens that expire before the specified time. | | `last_used_after` | datetime (ISO 8601) | No | If defined, returns tokens last used after the specified time. | | `last_used_before` | datetime (ISO 8601) | No | If defined, returns tokens last used before the specified time. | | `revoked` | boolean | No | If `true`, only returns revoked tokens. | | `search` | string | No | If defined, returns tokens that include the specified value in the name. | | `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `expires_asc`, `expires_desc`, `last_used_asc`, `last_used_desc`, `name_asc`, `name_desc`. | | `state` | string | No | If defined, returns tokens with the specified state. Possible values: `active` and `inactive`. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects//access_tokens" [\ {\ "user_id" : 141,\ "scopes" : [\ "api"\ ],\ "name" : "token",\ "expires_at" : "2021-01-31",\ "id" : 42,\ "active" : true,\ "created_at" : "2021-01-20T22:11:48.151Z",\ "description": "Test Token description",\ "last_used_at" : null,\ "revoked" : false,\ "access_level" : 40\ },\ {\ "user_id" : 141,\ "scopes" : [\ "read_api"\ ],\ "name" : "token-2",\ "expires_at" : "2021-01-31",\ "id" : 43,\ "active" : false,\ "created_at" : "2021-01-21T12:12:38.123Z",\ "description": "Test Token description",\ "revoked" : true,\ "last_used_at" : "2021-02-13T10:34:57.178Z",\ "access_level" : 40\ }\ ] Retrieve details on a project access token ------------------------------------------ Retrieves details on a project access token. GET projects/:id/access_tokens/:token_id | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `token_id` | integer or string | yes | ID | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects//access_tokens/" { "user_id" : 141, "scopes" : [\ "api"\ ], "name" : "token", "expires_at" : "2021-01-31", "id" : 42, "active" : true, "created_at" : "2021-01-20T22:11:48.151Z", "description": "Test Token description", "revoked" : false, "access_level": 40, "last_used_at": "2022-03-15T11:05:42.437Z" } Create a project access token ----------------------------- History * The `expires_at` attribute default was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120213) in GitLab 16.0. Creates a project access token for a specified project. You cannot create a token with an access level greater than your account. For example, a user with the Maintainer role cannot create a project access token with the Owner role. You must use a personal access token with this endpoint. You cannot authenticate with a project access token. There is an [open feature request](https://gitlab.com/gitlab-org/gitlab/-/issues/359953) to add this functionality. POST projects/:id/access_tokens | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `name` | string | yes | Name of the token. | | `description` | string | no | Description of the project access token. Maximum: 255 characters. | | `scopes` | `Array[String]` | yes | List of [scopes](https://docs.gitlab.com/user/project/settings/project_access_tokens/#project-access-token-scopes)
available to the token. | | `access_level` | integer | no | Role for the token. Possible values: `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), and `50` (Owner). Default value: `40`. | | `expires_at` | date | yes | Expiration date of the token in ISO format (`YYYY-MM-DD`). If undefined, the date is set to the [maximum allowable lifetime limit](https://docs.gitlab.com/user/profile/personal_access_tokens/#access-token-expiration)
. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type:application/json" \ --data '{ "name":"test_token", "scopes":["api", "read_repository"], "expires_at":"2021-01-31", "access_level":30 }' \ --url "https://gitlab.example.com/api/v4/projects//access_tokens" { "scopes" : [\ "api",\ "read_repository"\ ], "active" : true, "name" : "test", "revoked" : false, "created_at" : "2021-01-21T19:35:37.921Z", "description": "Test Token description", "user_id" : 166, "id" : 58, "expires_at" : "2021-01-31", "token" : "D4y...Wzr", "access_level": 30 } Rotate a project access token ----------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/403042) in GitLab 16.0 * `expires_at` attribute [added](https://gitlab.com/gitlab-org/gitlab/-/issues/416795) in GitLab 16.6. Rotates a project access token. This immediately revokes the previous token and creates a new token. Generally, this endpoint rotates a specific project access token by authenticating with a personal access token. You can also use a project access token to rotate itself. For more information, see [Self-rotate](https://docs.gitlab.com/api/project_access_tokens/#self-rotate) . If you attempt to use this endpoint to rotate a token that was previously revoked, any active tokens from the same token family are revoked. For more information, see [Automatic reuse detection](https://docs.gitlab.com/api/personal_access_tokens/#automatic-reuse-detection) . Prerequisites: * To rotate another project access token, you must have a personal access token with the [`api` scope](https://docs.gitlab.com/user/profile/personal_access_tokens/#personal-access-token-scopes) . * To [self-rotate](https://docs.gitlab.com/api/project_access_tokens/#self-rotate) a project access token, the token must have the [`api` or `self_rotate` scope](https://docs.gitlab.com/user/profile/personal_access_tokens/#personal-access-token-scopes) . POST /projects/:id/access_tokens/:token_id/rotate | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `token_id` | integer or string | yes | ID of a project access token or the keyword `self`. | | `expires_at` | date | no | Expiration date of the access token in ISO format (`YYYY-MM-DD`). If the token requires an expiration date, defaults to 1 week. If not required, defaults to the [maximum allowable lifetime limit](https://docs.gitlab.com/user/profile/personal_access_tokens/#access-token-expiration)
. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects//access_tokens//rotate" Example response: { "id": 42, "name": "Rotated Token", "revoked": false, "created_at": "2023-08-01T15:00:00.000Z", "description": "Test project access token", "scopes": ["api"], "user_id": 1337, "last_used_at": null, "active": true, "expires_at": "2023-08-15", "access_level": 30, "token": "s3cr3t" } If successful, returns `200: OK`. Other possible responses: * `400: Bad Request` if not rotated successfully. * `401: Unauthorized` if any of the following conditions are true: * The token does not exist. * The token has expired. * The token was revoked. * You do not have access to the specified token. * You’re using a project access token to rotate another project access token. See [Self-rotate](https://docs.gitlab.com/api/project_access_tokens/#self-rotate) instead. * `403: Forbidden` if the token is not allowed to rotate itself. * `404: Not Found` if the user is an administrator but the token does not exist. * `405: Method Not Allowed` if the token is not a project access token. ### Self-rotate Instead of rotating a specific project access token, you can rotate the same project access token you used to authenticate the request. To self-rotate a project access token, you must: * Rotate a project access token with the [`api` or `self_rotate` scope](https://docs.gitlab.com/user/profile/personal_access_tokens/#personal-access-token-scopes) . * Use the `self` keyword in the request URL. Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects//access_tokens/self/rotate" Revoke a project access token ----------------------------- Revokes a specified project access token. DELETE projects/:id/access_tokens/:token_id | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `token_id` | integer | yes | ID of a project access token. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects//access_tokens/" If successful, returns `204 No content`. Other possible responses: * `400: Bad Request` if not revoked successfully. * `404: Not Found` if the access token does not exist. --- # NuGet API | GitLab Docs * * * NuGet API ========= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with the [NuGet package manager client](https://docs.gitlab.com/user/packages/nuget_repository/) . This API is used by the [NuGet package manager client](https://www.nuget.org/) and is generally not meant for manual consumption. These endpoints do not adhere to the standard API authentication methods. See the [NuGet package registry documentation](https://docs.gitlab.com/user/packages/nuget_repository/) for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future. Retrieve a package index ------------------------ Retrieves the index for a specified package, which includes a list of available versions. GET projects/:id/packages/nuget/download/:package_name/index | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/index" Example response: { "versions": [\ "1.3.0.17"\ ] } Download a package file ----------------------- Downloads a specified NuGet package file for a project. The [metadata service](https://docs.gitlab.com/api/packages/nuget/#retrieve-package-metadata) provides this URL. GET projects/:id/packages/nuget/download/:package_name/:package_version/:package_filename | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | | `package_version` | string | yes | The version of the package. | | `package_filename` | string | yes | The name of the file. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/mynugetpkg.1.3.0.17.nupkg" Write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/mynugetpkg.1.3.0.17.nupkg" > MyNuGetPkg.1.3.0.17.nupkg This writes the downloaded file to `MyNuGetPkg.1.3.0.17.nupkg` in the current directory. This API returns a `404` status when you use [group endpoints](https://docs.gitlab.com/api/packages/nuget/#group-level) . Use the NuGet package manager CLI to [install packages](https://docs.gitlab.com/user/packages/nuget_repository/#install-a-package) with group endpoints to avoid this error. Upload a package file --------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416404) in GitLab 16.2 for NuGet v2 feed. Uploads a NuGet package file for a specified project. * For NuGet v3 feed: PUT projects/:id/packages/nuget * For NuGet V2 feed: PUT projects/:id/packages/nuget/v2 | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | | `package_version` | string | yes | The version of the package. | | `package_filename` | string | yes | The name of the file. | * For NuGet v3 feed: curl --request PUT \ --form 'package=@path/to/mynugetpkg.1.3.0.17.nupkg' \ --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/" * For NuGet v2 feed: curl --request PUT \ --form 'package=@path/to/mynugetpkg.1.3.0.17.nupkg' \ --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/v2" Upload a symbol package file ---------------------------- Uploads a specified NuGet symbol package file (`.snupkg`) for a project. PUT projects/:id/packages/nuget/symbolpackage | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | | `package_version` | string | yes | The version of the package. | | `package_filename` | string | yes | The name of the file. | curl --request PUT \ --form 'package=@path/to/mynugetpkg.1.3.0.17.snupkg' \ --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/symbolpackage" Route prefix ------------ For the remaining routes, there are two sets of identical routes that each make requests in different scopes: * Use the group-level prefix to make requests in a group’s scope. * Use the project-level prefix to make requests in a single project’s scope. The examples in this document all use the project-level prefix. ### Group-level /groups/:id/-/packages/nuget | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The group ID or full group path. | ### Project-level /projects/:id/packages/nuget | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The project ID or full project path. | Service Index ------------- ### V2 source feed/protocol Retrieves an XML document that represents the service index of the v2 NuGet source feed. Authentication is not required. GET /v2 Example Request: curl "https://gitlab.example.com/api/v4/projects/1/packages/nuget/v2" Example response: Default Packages ### V3 source feed/protocol History * [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/214674) to be public in GitLab 16.1. Retrieves a list of available API resources. Authentication is not required. GET /index Example Request: curl --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/index" Example response: { "version": "3.0.0", "resources": [\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/query",\ "@type": "SearchQueryService",\ "comment": "Filter and search for packages by keyword."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/query",\ "@type": "SearchQueryService/3.0.0-beta",\ "comment": "Filter and search for packages by keyword."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/query",\ "@type": "SearchQueryService/3.0.0-rc",\ "comment": "Filter and search for packages by keyword."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata",\ "@type": "RegistrationsBaseUrl",\ "comment": "Get package metadata."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata",\ "@type": "RegistrationsBaseUrl/3.0.0-beta",\ "comment": "Get package metadata."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata",\ "@type": "RegistrationsBaseUrl/3.0.0-rc",\ "comment": "Get package metadata."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download",\ "@type": "PackageBaseAddress/3.0.0",\ "comment": "Get package content (.nupkg)."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget",\ "@type": "PackagePublish/2.0.0",\ "comment": "Push and delete (or unlist) packages."\ },\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/symbolpackage",\ "@type": "SymbolPackagePublish/4.9.0",\ "comment": "Push symbol packages."\ }\ ] } The URLs in the response have the same route prefix used to request them. If you request them with the group-level route, the returned URLs contain `/groups/:id/-`. Retrieve package metadata ------------------------- Retrieves metadata for a specified package. GET /metadata/:package_name/index | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `package_name` | string | yes | The name of the package. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/index" Example response: { "count": 1, "items": [\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/1.3.0.17.json",\ "lower": "1.3.0.17",\ "upper": "1.3.0.17",\ "count": 1,\ "items": [\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/1.3.0.17.json",\ "packageContent": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/helloworld.1.3.0.17.nupkg",\ "catalogEntry": {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/1.3.0.17.json",\ "authors": "Author1, Author2",\ "dependencyGroups": [],\ "id": "MyNuGetPkg",\ "version": "1.3.0.17",\ "tags": "",\ "packageContent": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/helloworld.1.3.0.17.nupkg",\ "description": "Description of the package",\ "summary": "Description of the package",\ "published": "2023-05-08T17:23:25Z",\ }\ }\ ]\ }\ ] } Retrieve version metadata ------------------------- Retrieves metadata for a specified package version. GET /metadata/:package_name/:package_version | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `package_name` | string | yes | The name of the package. | | `package_version` | string | yes | The version of the package. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/1.3.0.17" Example response: { "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/1.3.0.17.json", "packageContent": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/helloworld.1.3.0.17.nupkg", "catalogEntry": { "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/1.3.0.17.json", "authors": "Author1, Author2", "dependencyGroups": [], "id": "MyNuGetPkg", "version": "1.3.0.17", "tags": "", "packageContent": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/download/MyNuGetPkg/1.3.0.17/helloworld.1.3.0.17.nupkg", "description": "Description of the package", "summary": "Description of the package", "published": "2023-05-08T17:23:25Z", } } Search for packages ------------------- Searches for NuGet packages in the repository based on a specified query. GET /query | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | yes | The search query. | | `skip` | integer | no | The number of results to skip. | | `take` | integer | no | The number of results to return. | | `prerelease` | boolean | no | Include prerelease versions. Defaults to `true` if no value is supplied. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/query?q=MyNuGet" Example response: { "totalHits": 1, "data": [\ {\ "@type": "Package",\ "authors": "Author1, Author2",\ "id": "MyNuGetPkg",\ "title": "MyNuGetPkg",\ "description": "Description of the package",\ "summary": "Description of the package",\ "totalDownloads": 0,\ "verified": true,\ "version": "1.3.0.17",\ "versions": [\ {\ "@id": "https://gitlab.example.com/api/v4/projects/1/packages/nuget/metadata/MyNuGetPkg/1.3.0.17.json",\ "version": "1.3.0.17",\ "downloads": 0\ }\ ],\ "tags": ""\ }\ ] } Delete a package ---------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/38275) in GitLab 16.5. Deletes a specified NuGet package. DELETE projects/:id/packages/nuget/:package_name/:package_version | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | | `package_version` | string | yes | The version of the package. | curl --request DELETE \ --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/MyNuGetPkg/1.3.0.17" Possible request responses: | Status | Description | | --- | --- | | `204` | Package deleted | | `401` | Unauthorized | | `403` | Forbidden | | `404` | Not found | Download a debugging symbol file `.pdb` --------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416178) in GitLab 16.7. Downloads a specified debugging symbol file (`.pdb`). GET /symbolfiles/:file_name/:signature/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `file_name` | string | yes | The name of the file. | | `signature` | string | yes | The signature of the file. | | `Symbolchecksum` | string | yes | Required header. The checksum of the file. | curl --header "Symbolchecksum: SHA256:" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/symbolfiles/:file_name/:signature/:file_name" Write the output to a file: curl --header "Symbolchecksum: SHA256:" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/symbolfiles/mynugetpkg.pdb/k813f89485474661234z7109cve5709eFFFFFFFF/mynugetpkg.pdb" > mynugetpkg.pdb Possible request responses: | Status | Description | | --- | --- | | `200` | File downloaded | | `400` | Bad request | | `403` | Forbidden | | `404` | Not found | V2 Feed Metadata Endpoints -------------------------- History * Introduced in GitLab 16.3. ### $metadata endpoint Authentication is not required. Returns metadata for a V2 feed available endpoints: GET /v2/$metadata curl --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/v2/$metadata" Example response: ### OData package entry endpoints History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127667) in GitLab 16.4. | Endpoint | Description | | --- | --- | | `GET projects/:id/packages/nuget/v2/Packages()?$filter=(tolower(Id) eq '')` | Returns an OData XML document containing information about the package with the given name. | | `GET projects/:id/packages/nuget/v2/FindPackagesById()?id=''` | Returns an OData XML document containing information about the package with the given name. | | `GET projects/:id/packages/nuget/v2/Packages(Id='',Version='')` | Returns an OData XML document containing information about the package with the given name and version. | curl --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/v2/Packages(Id='mynugetpkg',Version='1.0.0')" Example response: https://gitlab.example.com/api/v4/projects/1/packages/nuget/v2/Packages(Id='mynugetpkg',Version='1.0.0') mynugetpkg 1.0.0 GitLab doesn’t receive an authentication token for the `Packages()` and `FindPackagesByID()` endpoints, so the latest version of the package cannot be returned. You must provide the version when you install or upgrade a package with the NuGet v2 feed. curl --url "https://gitlab.example.com/api/v4/projects/1/packages/nuget/v2/Packages()?$filter=(tolower(Id) eq 'mynugetpkg')" Example response: https://gitlab.example.com/api/v4/projects/1/packages/nuget/v2/Packages(Id='mynugetpkg',Version='') mynugetpkg --- # Product analytics API | GitLab Docs * * * Product analytics API ===================== * Tier: Ultimate * Offering: GitLab.com, GitLab Self-Managed * Status: Beta History * Introduced in GitLab 15.4 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `cube_api_proxy`. Disabled by default. * `cube_api_proxy` removed and replaced with `product_analytics_internal_preview` in GitLab 15.10. * `product_analytics_internal_preview` replaced with `product_analytics_dashboards` in GitLab 15.11. * `product_analytics_dashboards` [enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/398653) by default in GitLab 16.11. * Feature flag `product_analytics_dashboards` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/454059) in GitLab 17.1. * [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/167296) to beta in GitLab 17.5 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `product_analytics_features`. The availability of this feature is controlled by a feature flag. For more information, see the history. This feature is not ready for production use. Use this API to track user behavior and application usage. Make sure to define the `cube_api_base_url` and `cube_api_key` application settings first using [the API](https://docs.gitlab.com/api/settings/) . Create a Cube query request --------------------------- Creates a query request to the Cube API and generates an access token. POST /projects/:id/product_analytics/request/load POST /projects/:id/product_analytics/request/dry-run | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID of a project that the current user has read access to. | | `include_token` | boolean | no | Whether to include the access token in the response. (Only required for funnel generation.) | ### Request body The body of the load request must be a valid Cube query. When measuring `TrackedEvents`, you must use `TrackedEvents.*` for `dimensions` and `timeDimensions`. The same rule applies when measuring `Sessions`. #### Tracked events example { "query": { "measures": [\ "TrackedEvents.count"\ ], "timeDimensions": [\ {\ "dimension": "TrackedEvents.utcTime",\ "dateRange": "This week"\ }\ ], "order": [\ [\ "TrackedEvents.count",\ "desc"\ ],\ [\ "TrackedEvents.docPath",\ "desc"\ ],\ [\ "TrackedEvents.utcTime",\ "asc"\ ]\ ], "dimensions": [\ "TrackedEvents.docPath"\ ], "limit": 23 }, "queryType": "multi" } #### Sessions example { "query": { "measures": [\ "Sessions.count"\ ], "timeDimensions": [\ {\ "dimension": "Sessions.startAt",\ "granularity": "day"\ }\ ], "order": { "Sessions.startAt": "asc" }, "limit": 100 }, "queryType": "multi" } Retrieve Cube metadata ---------------------- Retrieves Cube metadata for analytics data. GET /projects/:id/product_analytics/request/meta | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID of a project that the current user has read access to. | --- # Project push rules API | GitLab Docs * * * Project push rules API ====================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage project [push rules](https://docs.gitlab.com/user/project/repository/push_rules/) . GitLab uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for all regular expressions in push rules. Retrieve the push rules of a project ------------------------------------ Retrieves the push rules of a specified project. GET /projects/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author_email_regex` | string | All commit author emails must match this regular expression. | | `branch_name_regex` | string | All branch names must match this regular expression. | | `commit_committer_check` | boolean | If `true`, users can only push commits to this repository if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | If `true`, users can only push commits to this repository if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | No commit message is allowed to match this regular expression. | | `commit_message_regex` | string | All commit messages must match this regular expression. | | `created_at` | string | Date and time when the push rule was created. | | `deny_delete_tag` | boolean | If `true`, denies deleting a tag. | | `file_name_regex` | string | All committed filenames must not match this regular expression. | | `id` | integer | ID of the push rule. | | `max_file_size` | integer | Maximum file size (MB). | | `member_check` | boolean | If `true`, restricts commits by author (email) to existing GitLab users. | | `prevent_secrets` | boolean | If `true`, GitLab rejects any files that are likely to contain secrets. | | `project_id` | integer | ID of the project. | | `reject_non_dco_commits` | boolean | If `true`, rejects commits when not DCO certified. | | `reject_unsigned_commits` | boolean | If `true`, rejects commits when not signed. | If push rules were never configured for the project, returns HTTP `200 OK` with the literal string `"null"` as the response body. This differs from the [group push rules API](https://docs.gitlab.com/api/group_push_rules/#retrieve-the-push-rules-of-a-group) , which returns `404 Not Found` error. Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/3/push_rule" Example response when push rules are configured with all settings disabled: { "id": 1, "project_id": 3, "created_at": "2012-10-12T17:04:47Z", "commit_message_regex": "Fixes \\d+\\..*", "commit_message_negative_regex": "ssh\\:\\/\\/", "branch_name_regex": "", "deny_delete_tag": false, "member_check": false, "prevent_secrets": false, "author_email_regex": "", "file_name_regex": "", "max_file_size": 0, "commit_committer_check": null, "commit_committer_name_check": false, "reject_unsigned_commits": null, "reject_non_dco_commits": null } If the following attributes are disabled, they return `null` instead of `false`: * `commit_committer_check` * `reject_unsigned_commits` * `reject_non_dco_commits` Example response when push rules were never configured for the project: HTTP/1.1 200 OK Content-Type: application/json Content-Length: 4 null This returns the literal string `"null"` (4 characters), not a JSON `null` value. Add push rules to a project --------------------------- Adds push rules to the specified project. POST /projects/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `author_email_regex` | string | No | All commit author emails must match this regular expression. | | `branch_name_regex` | string | No | All branch names must match this regular expression. | | `commit_committer_check` | boolean | No | If `true`, users can only push commits to this repository if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | No | If `true`, users can only push commits to this repository if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | No | No commit message is allowed to match this regular expression. | | `commit_message_regex` | string | No | All commit messages must match this regular expression. | | `deny_delete_tag` | boolean | No | If `true`, denies deleting a tag. | | `file_name_regex` | string | No | All committed filenames must not match this regular expression. | | `max_file_size` | integer | No | Maximum file size (MB). | | `member_check` | boolean | No | If `true`, restricts commits by author (email) to existing GitLab users. | | `prevent_secrets` | boolean | No | If `true`, GitLab rejects any files that are likely to contain secrets. | | `reject_non_dco_commits` | boolean | No | If `true`, rejects commits when not DCO certified. | | `reject_unsigned_commits` | boolean | No | If `true`, rejects commits when not signed. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author_email_regex` | string | All commit author emails must match this regular expression. | | `branch_name_regex` | string | All branch names must match this regular expression. | | `commit_committer_check` | boolean | If `true`, users can only push commits to this repository if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | If `true`, users can only push commits to this repository if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | No commit message is allowed to match this regular expression. | | `commit_message_regex` | string | All commit messages must match this regular expression. | | `created_at` | string | Date and time when the push rule was created. | | `deny_delete_tag` | boolean | If `true`, denies deleting a tag. | | `file_name_regex` | string | All committed filenames must not match this regular expression. | | `id` | integer | ID of the push rule. | | `max_file_size` | integer | Maximum file size (MB). | | `member_check` | boolean | If `true`, restricts commits by author (email) to existing GitLab users. | | `prevent_secrets` | boolean | If `true`, GitLab rejects any files that are likely to contain secrets. | | `project_id` | integer | ID of the project. | | `reject_non_dco_commits` | boolean | If `true`, rejects commits when not DCO certified. | | `reject_unsigned_commits` | boolean | If `true`, rejects commits when not signed. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/3/push_rule" \ --data "commit_message_regex=Fixes \\d+\\..*" \ --data "deny_delete_tag=false" Example response: { "id": 1, "project_id": 3, "created_at": "2012-10-12T17:04:47Z", "commit_message_regex": "Fixes \\d+\\..*", "commit_message_negative_regex": "", "branch_name_regex": "", "deny_delete_tag": false, "member_check": false, "prevent_secrets": false, "author_email_regex": "", "file_name_regex": "", "max_file_size": 0, "commit_committer_check": false, "commit_committer_name_check": false, "reject_unsigned_commits": false, "reject_non_dco_commits": false } Update push rules of a project ------------------------------ Updates the push rules for the specified project. PUT /projects/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `author_email_regex` | string | No | All commit author emails must match this regular expression. | | `branch_name_regex` | string | No | All branch names must match this regular expression. | | `commit_committer_check` | boolean | No | If `true`, users can only push commits to this repository if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | No | If `true`, users can only push commits to this repository if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | No | No commit message is allowed to match this regular expression. | | `commit_message_regex` | string | No | All commit messages must match this regular expression. | | `deny_delete_tag` | boolean | No | If `true`, denies deleting a tag. | | `file_name_regex` | string | No | All committed filenames must not match this regular expression. | | `max_file_size` | integer | No | Maximum file size (MB). | | `member_check` | boolean | No | If `true`, restricts commits by author (email) to existing GitLab users. | | `prevent_secrets` | boolean | No | If `true`, GitLab rejects any files that are likely to contain secrets. | | `reject_non_dco_commits` | boolean | No | If `true`, rejects commits when not DCO certified. | | `reject_unsigned_commits` | boolean | No | If `true`, rejects commits when not signed. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author_email_regex` | string | All commit author emails must match this regular expression. | | `branch_name_regex` | string | All branch names must match this regular expression. | | `commit_committer_check` | boolean | If `true`, users can only push commits to this repository if the committer email is one of their own verified emails. | | `commit_committer_name_check` | boolean | If `true`, users can only push commits to this repository if the commit author name is consistent with their GitLab account name. | | `commit_message_negative_regex` | string | No commit message is allowed to match this regular expression. | | `commit_message_regex` | string | All commit messages must match this regular expression. | | `created_at` | string | Date and time when the push rule was created. | | `deny_delete_tag` | boolean | If `true`, denies deleting a tag. | | `file_name_regex` | string | All committed filenames must not match this regular expression. | | `id` | integer | ID of the push rule. | | `max_file_size` | integer | Maximum file size (MB). | | `member_check` | boolean | If `true`, restricts commits by author (email) to existing GitLab users. | | `prevent_secrets` | boolean | If `true`, GitLab rejects any files that are likely to contain secrets. | | `project_id` | integer | ID of the project. | | `reject_non_dco_commits` | boolean | If `true`, rejects commits when not DCO certified. | | `reject_unsigned_commits` | boolean | If `true`, rejects commits when not signed. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/3/push_rule" \ --data "commit_message_regex=Fixes \\d+\\..*" \ --data "deny_delete_tag=true" Example response: { "id": 1, "project_id": 3, "created_at": "2012-10-12T17:04:47Z", "commit_message_regex": "Fixes \\d+\\..*", "commit_message_negative_regex": "", "branch_name_regex": "", "deny_delete_tag": true, "member_check": false, "prevent_secrets": false, "author_email_regex": "", "file_name_regex": "", "max_file_size": 0, "commit_committer_check": false, "commit_committer_name_check": false, "reject_unsigned_commits": false, "reject_non_dco_commits": false } Delete the push rules of a project ---------------------------------- Deletes all the push rules of a specified project. DELETE /projects/:id/push_rule Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/3/push_rule" --- # Project iterations API | GitLab Docs * * * Project iterations API ====================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to access [project iterations](https://docs.gitlab.com/user/group/iterations/) . For group iterations, use the [group iterations API](https://docs.gitlab.com/api/group_iterations/) . We no longer have project-level iterations, but you can use this endpoint to fetch the iterations of the project’s ancestor groups. List all project iterations --------------------------- Lists all iterations for a specified project. Iterations created by **Enable automatic scheduling** in [Iteration cadences](https://docs.gitlab.com/user/group/iterations/#iteration-cadences) return `null` for the `title` and `description` fields. GET /projects/:id/iterations GET /projects/:id/iterations?state=opened GET /projects/:id/iterations?state=closed GET /projects/:id/iterations?search=version GET /projects/:id/iterations?include_ancestors=false GET /projects/:id/iterations?include_descendants=true GET /projects/:id/iterations?updated_before=2013-10-02T09%3A24%3A18Z GET /projects/:id/iterations?updated_after=2013-10-02T09%3A24%3A18Z | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `state` | string | no | ‘Return `opened`, `upcoming`, `current`, `closed`, or `all` iterations.’ | | `search` | string | no | Return only iterations with a title matching the provided string. | | `in` | array of strings | no | Fields in which fuzzy search should be performed with the query given in the argument `search`. The available options are `title` and `cadence_title`. Default is `[title]`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350991)
in GitLab 16.2. | | `include_ancestors` | boolean | no | Include iterations for parent group and its ancestors. Defaults to `true`. | | `include_descendants` | boolean | no | Include iterations for parent group and its descendants. Defaults to `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135764)
in GitLab 16.7. | | `updated_before` | datetime | no | Return only iterations updated before the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378662)
in GitLab 15.10. | | `updated_after` | datetime | no | Return only iterations updated after the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378662)
in GitLab 15.10. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/iterations" Example response: [\ {\ "id": 53,\ "iid": 13,\ "group_id": 5,\ "title": "Iteration II",\ "description": "Ipsum Lorem ipsum",\ "state": 2,\ "created_at": "2020-01-27T05:07:12.573Z",\ "updated_at": "2020-01-27T05:07:12.573Z",\ "due_date": "2020-02-01",\ "start_date": "2020-02-14",\ "web_url": "http://gitlab.example.com/groups/my-group/-/iterations/13"\ }\ ] --- # Groups members API | GitLab Docs * * * Groups members API ================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this endpoint to interact with group members. For information about project members, see the [Project members API](https://docs.gitlab.com/api/project_members/) . Known issues ------------ * The `group_saml_identity` and `group_scim_identity` attributes are only visible to group owners for [SSO-enabled groups](https://docs.gitlab.com/user/group/saml_sso/) . * The `email` attribute is only visible to group owners for [enterprise users](https://docs.gitlab.com/user/enterprise_user/) of the group when an API request is sent to the group itself, or that group’s subgroups or projects. List all group members ---------------------- Lists all direct members of a specified group. Returns only direct members and not inherited members through ancestor groups or members from an invited group. This function takes pagination parameters `page` and `per_page` to restrict the list of users. GET /groups/:id/members | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `query` | string | no | Filters results based on a given name, email, or username. Use partial values to widen the scope of the query. | | `user_ids` | array of integers | no | Filter the results on the given user IDs. | | `skip_users` | array of integers | no | Filter skipped users out of the results. | | `show_seat_info` | boolean | no | Show seat information for users. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members" Example response: [\ {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "group_saml_identity": null,\ "is_using_seat": true\ },\ {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "email": "john@example.com",\ "group_saml_identity": {\ "extern_uid":"ABC-1234567890",\ "provider": "group_saml",\ "saml_provider_id": 10\ }\ }\ ] List all group members, including inherited and invited members --------------------------------------------------------------- History * [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to return members of the invited private group if the current user is a member of the shared group or project in GitLab 16.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `webui_members_inherited_users`. Disabled by default. * Feature flag `webui_members_inherited_users` was [enabled on GitLab.com and GitLab Self-Managed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) in GitLab 17.0. * Feature flag `webui_members_inherited_users` [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163627) in GitLab 17.4. Members of invited groups displayed by default. Lists all members of a specified group, including inherited members, invited users, and permissions through ancestor groups. If a user is a member of this group and also of one or more ancestor groups, only its membership with the highest `access_level` is returned. This represents the effective permission of the user. Members from an invited group are returned if either: * The invited group is public. * The requester is also a member of the invited group. * The requester is a member of the shared group. The invited group members have shared membership in the shared group. This means that if the requester is a member of a shared group, but not a member of an invited private group, then using this endpoint the requester can get all the shared group members, including the invited private group members. This function takes pagination parameters `page` and `per_page` to restrict the list of users. GET /groups/:id/members/all | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `query` | string | no | Filters results based on a given name, email, or username. Use partial values to widen the scope of the query. | | `user_ids` | array of integers | no | Filter the results on the given user IDs. | | `show_seat_info` | boolean | no | Show seat information for users. | | `state` | string | no | Filter results by member state, one of `awaiting` or `active`. Premium and Ultimate only. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/all" Example response: [\ {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "group_saml_identity": null\ },\ {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "email": "john@example.com",\ "group_saml_identity": {\ "extern_uid":"ABC-1234567890",\ "provider": "group_saml",\ "saml_provider_id": 10\ }\ },\ {\ "id": 3,\ "username": "foo_bar",\ "name": "Foo bar",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-10-22T14:13:35Z",\ "created_by": {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-11-22",\ "access_level": 30,\ "group_saml_identity": null\ }\ ] Retrieve a group member ----------------------- Retrieves a specified member of a group. Returns only direct members and not inherited members through ancestor groups. GET /groups/:id/members/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/:user_id" To update or remove a custom role from a group member, pass an empty `member_role_id` value: # Updates a group membership curl --request PUT --header "Content-Type: application/json" \ --header "Authorization: Bearer " \ --data '{"member_role_id": null, "access_level": 10}' "https://gitlab.example.com/api/v4/groups//members/" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "access_level": 30, "email": "john@example.com", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": null, "group_saml_identity": null } Retrieve a group member, including inherited and invited members ---------------------------------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17744) in GitLab 12.4. * [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to return members of the invited private group if the current user is a member of the shared group or project in GitLab 16.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `webui_members_inherited_users`. Disabled by default. * [Enabled on GitLab.com and GitLab Self-Managed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) in GitLab 17.0. * Feature flag `webui_members_inherited_users` [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163627) in GitLab 17.4. Members of invited groups displayed by default. Retrieves a specified member of a group, including members inherited or invited through ancestor groups. For more information, see [List all inherited members](https://docs.gitlab.com/api/group_members/#list-all-group-members-including-inherited-and-invited-members) . The invited group members have shared membership in the shared group. This means that if the requester is a member of a shared group, but not a member of an invited private group, then using this endpoint the requester can get all the shared group members, including the invited private group members. GET /groups/:id/members/all/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/all/:user_id" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "access_level": 30, "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "email": "john@example.com", "expires_at": null, "group_saml_identity": null } List all billable group members ------------------------------- Lists all billable members of a specified group. The list includes members in subgroups and projects. Prerequisites: * You must have the Owner role to access the API endpoint for billing permissions, as shown in [billing permissions](https://docs.gitlab.com/user/free_user_limit/) . * This API endpoint works on top-level groups only. It does not work on subgroups. This function takes [pagination](https://docs.gitlab.com/api/rest/#pagination) parameters `page` and `per_page` to restrict the list of users. Use the `search` parameter to search for billable group members by name, and `sort` to sort the results. GET /groups/:id/billable_members | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `search` | string | no | A query string to search for group members by name, username, or public email. | | `sort` | string | no | A query string containing parameters that specify the sort attribute and order. See supported values below. | The supported values for the `sort` attribute are: | Value | Description | | --- | --- | | `access_level_asc` | Access level, ascending | | `access_level_desc` | Access level, descending | | `last_joined` | Last joined | | `name_asc` | Name, ascending | | `name_desc` | Name, descending | | `oldest_joined` | Oldest joined | | `oldest_sign_in` | Oldest sign in | | `recent_sign_in` | Recent sign in | | `last_activity_on_asc` | Last active date, ascending | | `last_activity_on_desc` | Last active date, descending | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/billable_members" Example response: [\ {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "last_activity_on": "2021-01-27",\ "membership_type": "group_member",\ "removable": true,\ "created_at": "2021-01-03T12:16:02.000Z",\ "last_login_at": "2022-10-09T01:33:06.000Z"\ },\ {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "email": "john@example.com",\ "last_activity_on": "2021-01-25",\ "membership_type": "group_member",\ "removable": true,\ "created_at": "2021-01-04T18:46:42.000Z",\ "last_login_at": "2022-09-29T22:18:46.000Z"\ },\ {\ "id": 3,\ "username": "foo_bar",\ "name": "Foo bar",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "last_activity_on": "2021-01-20",\ "membership_type": "group_invite",\ "removable": false,\ "created_at": "2021-01-09T07:12:31.000Z",\ "last_login_at": "2022-10-10T07:28:56.000Z"\ }\ ] List all memberships for a billable group member ------------------------------------------------ Lists all memberships for a specified billable member of a group. Prerequisites: * The response represents only direct memberships. Inherited memberships are not included. * This API endpoint works on top-level groups only. It does not work on subgroups. * This API endpoint requires permission to administer memberships for the group. Lists all projects and groups a user is a member of. Only projects and groups in the group hierarchy are included. For instance, if the requested group is `Top-Level Group`, and the requested user is a direct member of both `Top-Level Group / Subgroup One` and `Other Group / Subgroup Two`, then only `Top-Level Group / Subgroup One` is returned, because `Other Group / Subgroup Two` is not in the `Top-Level Group` hierarchy. This API endpoint takes [pagination](https://docs.gitlab.com/api/rest/#pagination) parameters `page` and `per_page` to restrict the list of memberships. GET /groups/:id/billable_members/:user_id/memberships | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `user_id` | integer | yes | The user ID of the billable member. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/billable_members/:user_id/memberships" Example response: [\ {\ "id": 168,\ "source_id": 131,\ "source_full_name": "Top-Level Group / Subgroup One",\ "source_members_url": "https://gitlab.example.com/groups/root-group/sub-group-one/-/group_members",\ "created_at": "2021-03-31T17:28:44.812Z",\ "expires_at": "2022-03-21",\ "access_level": {\ "string_value": "Developer",\ "integer_value": 30\ }\ },\ {\ "id": 169,\ "source_id": 63,\ "source_full_name": "Top-Level Group / Subgroup One / My Project",\ "source_members_url": "https://gitlab.example.com/root-group/sub-group-one/my-project/-/project_members",\ "created_at": "2021-03-31T17:29:14.934Z",\ "expires_at": null,\ "access_level": {\ "string_value": "Maintainer",\ "integer_value": 40\ }\ }\ ] List all indirect memberships for a billable group member --------------------------------------------------------- * Status: Experiment History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/386583) in GitLab 16.11. Gets a list of indirect memberships for a billable member of a group. Prerequisites: * This API endpoint works on top-level groups only. It does not work on subgroups. * This API endpoint requires permission to administer memberships for the group. Lists all projects and groups that a user is a member of, that have been invited to the requested top-level group. For instance, if the requested group is `Top-Level Group`, and the requested user is a direct member of `Other Group / Subgroup Two`, which was invited to `Top-Level Group`, then only `Other Group / Subgroup Two` is returned. The response lists only indirect memberships. Direct memberships are not included. This API endpoint takes [pagination](https://docs.gitlab.com/api/rest/#pagination) parameters `page` and `per_page` to restrict the list of memberships. GET /groups/:id/billable_members/:user_id/indirect | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `user_id` | integer | yes | The user ID of the billable member. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/billable_members/:user_id/indirect" Example response: [\ {\ "id": 168,\ "source_id": 132,\ "source_full_name": "Invited Group / Subgroup One",\ "source_members_url": "https://gitlab.example.com/groups/invited-group/sub-group-one/-/group_members",\ "created_at": "2021-03-31T17:28:44.812Z",\ "expires_at": "2022-03-21",\ "access_level": {\ "string_value": "Developer",\ "integer_value": 30\ }\ }\ ] Remove a billable group member ------------------------------ Removes a specified billable member from a group and its subgroups and projects. The user does not need to be a group member to qualify for removal. For example, if the user was added directly to a project in the group, you can still use this API endpoint to remove them. Member removal is handled asynchronously, so the changes complete in a few minutes. DELETE /groups/:id/billable_members/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `user_id` | integer | yes | The user ID of the member. | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/billable_members/:user_id" Change group membership state for a user ---------------------------------------- Changes the membership state for a specified user in a group. When a user is over [the free user limit](https://docs.gitlab.com/user/free_user_limit/) , changing their membership state for a group or project to `awaiting` or `active` can allow them to access that group or project. The change is applied to applied to all subgroups and projects. PUT /groups/:id/members/:user_id/state | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `user_id` | integer | yes | The user ID of the member. | | `state` | string | yes | The new state for the user. State is either `awaiting` or `active`. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/:user_id/state?state=active" Example response: { "success":true } Add a group member ------------------ Adds a member to a specified group. POST /groups/:id/members | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer or string | yes, if `username` is not provided | The user ID of the new member or multiple IDs separated by commas. | | `username` | string | yes, if `user_id` is not provided | The username of the new member or multiple usernames separated by commas. | | `access_level` | integer | yes | A valid [access level](https://docs.gitlab.com/user/permissions/#default-roles)
Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), `50` (Owner). Default: `30`. | | `expires_at` | string | no | A date string in the format `YEAR-MONTH-DAY`. | | `invite_source` | string | no | The source of the invitation that starts the member creation process. GitLab team members can view more information in this confidential issue: `https://gitlab.com/gitlab-org/gitlab/-/issues/327120>`. | | `member_role_id` | integer | no | Ultimate only. The ID of a custom member role. | curl --request POST --header "PRIVATE-TOKEN: " \ --data "user_id=1&access_level=30" "https://gitlab.example.com/api/v4/groups/:id/members" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": "2012-10-22", "access_level": 30, "email": "john@example.com", "group_saml_identity": null } If [administrator approval for role promotions](https://docs.gitlab.com/administration/settings/sign_up_restrictions/#turn-on-administrator-approval-for-role-promotions) is turned on, membership requests that promote existing users into a billable role require administrator approval. To enable **Manage Non-Billable Promotions**, you must first enable the `enable_member_promotion_management` application setting. Example of queueing a single user: curl --request POST --header "PRIVATE-TOKEN: " \ --data "user_id=1&access_level=30" "https://gitlab.example.com/api/v4/groups/:id/members" { "message":{ "username_1":"Request queued for administrator approval." } } Example of queueing multiple users: curl --request POST --header "PRIVATE-TOKEN: " \ --data "user_id=1,2&access_level=30" "https://gitlab.example.com/api/v4/groups/:id/members" curl --request POST --header "PRIVATE-TOKEN: " \ --data "user_id=1,2&access_level=30" "https://gitlab.example.com/api/v4/projects/:id/members" { "queued_users": { "username_1": "Request queued for administrator approval.", "username_2": "Request queued for administrator approval." }, "status": "success" } Update a group member --------------------- Updates a specified member of a group. PUT /groups/:id/members/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | | `access_level` | integer | yes | A valid [access level](https://docs.gitlab.com/user/permissions/#default-roles)
Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), `50` (Owner), `60` (Admin). Default: `30`. | | `expires_at` | string | no | A date string in the format `YEAR-MONTH-DAY`. | | `member_role_id` | integer | no | Ultimate only. The ID of a custom member role. If no value is specified, removes all roles. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/:user_id?access_level=40" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": "2012-10-22", "access_level": 40, "email": "john@example.com", "group_saml_identity": null } If [administrator approval for role promotions](https://docs.gitlab.com/administration/settings/sign_up_restrictions/#turn-on-administrator-approval-for-role-promotions) is turned on, membership requests that promote existing users into a billable role require administrator approval. To enable **Manage non-billable promotions**, you must first enable the `enable_member_promotion_management` application setting. Example response: { "message":{ "username_1":"Request queued for administrator approval." } } ### Set override flag for a member of a group By default, the access level of LDAP group members is set to the value specified by LDAP through Group Sync. You can allow access level overrides by calling this endpoint. POST /groups/:id/members/:user_id/override | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `user_id` | integer | yes | The user ID of the member. | curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/:user_id/override" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": "2012-10-22", "access_level": 40, "email": "john@example.com", "override": true } ### Remove override for a member of a group Sets the override flag to false and allows LDAP Group Sync to reset the access level to the LDAP-prescribed value. DELETE /groups/:id/members/:user_id/override | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `user_id` | integer | yes | The user ID of the member. | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/:user_id/override" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": "2012-10-22", "access_level": 40, "email": "john@example.com", "override": false } Remove a group member --------------------- Removes a specified user from a group where the user has been explicitly assigned a role. The user needs to be a group member to qualify for removal. For example, if the user was added directly to a project in the group but not this group explicitly, you cannot use this API endpoint to remove them. See [Remove a billable member from a group](https://docs.gitlab.com/api/group_members/#remove-a-billable-group-member) for an alternative approach. DELETE /groups/:id/members/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | | `skip_subresources` | boolean | false | Whether the deletion of direct memberships of the removed member in subgroups and projects should be skipped. Default is `false`. | | `unassign_issuables` | boolean | false | Whether the removed member should be unassigned from any issues or merge requests inside a given group or project. Default is `false`. | Example request: curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/:user_id" curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/members/:user_id" Approve a group member ---------------------- Approves a specified pending user for a group and its subgroups and projects. PUT /groups/:id/members/:member_id/approve | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the top-level group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `member_id` | integer | yes | The ID of the member. | Example request: curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/:member_id/approve" Approve all pending group members --------------------------------- Approves all pending users for a specified group and its subgroups and projects. POST /groups/:id/members/approve_all | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the top-level group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/members/approve_all" List all pending group members in a group and its subgroups and projects ------------------------------------------------------------------------ Lists all members in an `awaiting` state and those who are invited but do not have a GitLab account for a specified group and its subgroups and projects. Prerequisites: * This API endpoint works on top-level groups only. It does not work on subgroups. * This API endpoint requires permission to administer members for the group. This request returns all matching group and project members from all groups and projects in the top-level group’s hierarchy. When the member is an invited user that has not signed up for a GitLab account yet, the invited email address is returned. This API endpoint takes [pagination](https://docs.gitlab.com/api/rest/#pagination) parameters `page` and `per_page` to restrict the list of members. GET /groups/:id/pending_members | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/pending_members" Example response: [\ {\ "id": 168,\ "name": "Alex Garcia",\ "username": "alex_garcia",\ "email": "alex@example.com",\ "avatar_url": "http://example.com/uploads/user/avatar/1/cd8.jpeg",\ "web_url": "http://example.com/alex_garcia",\ "approved": false,\ "invited": false\ },\ {\ "id": 169,\ "email": "sidney@example.com",\ "avatar_url": "http://gravatar.com/../e346561cd8.jpeg",\ "approved": false,\ "invited": true\ },\ {\ "id": 170,\ "email": "zhang@example.com",\ "avatar_url": "http://gravatar.com/../e32131cd8.jpeg",\ "approved": true,\ "invited": true\ }\ ] --- # Project statistics API | GitLab Docs * * * Project statistics API ====================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to retrieve statistics about a [project](https://docs.gitlab.com/user/project/) . All endpoints require authentication. You must have read access to the repository. [Personal access tokens](https://docs.gitlab.com/user/profile/personal_access_tokens/) must have the `read_api` scope. [Group access tokens](https://docs.gitlab.com/user/group/settings/group_access_tokens/) can use the Reporter role and the `read_api` scope. This API retrieves the number of times the project is either cloned or pulled with the HTTP method. SSH fetches are not included. Retrieve the statistics of the last 30 days ------------------------------------------- Retrieves the clone and pull statistics for the last 30 days from a specified project. GET /projects/:id/statistics Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `fetches` | object | Fetch statistics for the project. | | `fetches.days` | array | Array of daily fetch statistics. | | `fetches.days[].count` | integer | Number of fetches for the specific date. | | `fetches.days[].date` | string | Date in ISO format (`YYYY-MM-DD`). | | `fetches.total` | integer | Total number of fetches for the last 30 days. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/statistics" Example response: { "fetches": { "total": 50, "days": [\ {\ "count": 10,\ "date": "2018-01-10"\ },\ {\ "count": 10,\ "date": "2018-01-09"\ },\ {\ "count": 10,\ "date": "2018-01-08"\ },\ {\ "count": 10,\ "date": "2018-01-07"\ },\ {\ "count": 10,\ "date": "2018-01-06"\ }\ ] } } --- # Project milestones API | GitLab Docs * * * Project milestones API ====================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [project milestones](https://docs.gitlab.com/user/project/milestones/) . For group milestones, use the [group milestones API](https://docs.gitlab.com/api/group_milestones/) . List all project milestones --------------------------- Lists all milestones for a project. GET /projects/:id/milestones GET /projects/:id/milestones?iids[]=42 GET /projects/:id/milestones?iids[]=42&iids[]=43 GET /projects/:id/milestones?state=active GET /projects/:id/milestones?state=closed GET /projects/:id/milestones?title=1.0 GET /projects/:id/milestones?search=version GET /projects/:id/milestones?updated_before=2013-10-02T09%3A24%3A18Z GET /projects/:id/milestones?updated_after=2013-10-02T09%3A24%3A18Z Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `iids[]` | integer array | no | Return only the milestones having the given `iid`. Ignored if `include_ancestors` is `true`. | | `state` | string | no | Return only `active` or `closed` milestones | | `title` | string | no | Return only the milestones having the given `title` | | `search` | string | no | Return only milestones with a title or description matching the provided string | | `include_parent_milestones` | boolean | no | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/433298)
in GitLab 16.7. Use `include_ancestors` instead. | | `include_ancestors` | boolean | no | Include milestones from all parent groups. | | `updated_before` | datetime | no | Return only milestones updated before the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10 | | `updated_after` | datetime | no | Return only milestones updated after the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10 | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/milestones" Example Response: [\ {\ "id": 12,\ "iid": 3,\ "project_id": 16,\ "title": "10.0",\ "description": "Version",\ "due_date": "2013-11-29",\ "start_date": "2013-11-10",\ "state": "active",\ "updated_at": "2013-10-02T09:24:18Z",\ "created_at": "2013-10-02T09:24:18Z",\ "expired": false\ }\ ] Retrieve a milestone -------------------- Retrieves a specified project milestone. GET /projects/:id/milestones/:milestone_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `milestone_id` | integer | yes | The ID of the project’s milestone | Create a milestone ------------------ Creates a project milestone. POST /projects/:id/milestones Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `title` | string | yes | The title of a milestone | | `description` | string | no | The description of the milestone | | `due_date` | string | no | The due date of the milestone (`YYYY-MM-DD`) | | `start_date` | string | no | The start date of the milestone (`YYYY-MM-DD`) | Update a milestone ------------------ Updates a specified project milestone. PUT /projects/:id/milestones/:milestone_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `milestone_id` | integer | yes | The ID of the project’s milestone | | `title` | string | no | The title of a milestone | | `description` | string | no | The description of the milestone | | `due_date` | string | no | The due date of the milestone (`YYYY-MM-DD`) | | `start_date` | string | no | The start date of the milestone (`YYYY-MM-DD`) | | `state_event` | string | no | The state event of the milestone (close or activate) | Delete a milestone ------------------ History * [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0. * [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7. Deletes a specified project milestone. Only for users with the Planner, Reporter, Developer, Maintainer, or Owner role for the project. DELETE /projects/:id/milestones/:milestone_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `milestone_id` | integer | yes | The ID of the project’s milestone | List all issues for a milestone ------------------------------- Lists all issues assigned to a specified project milestone. GET /projects/:id/milestones/:milestone_id/issues Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `milestone_id` | integer | yes | The ID of the project’s milestone | List all merge requests for a milestone --------------------------------------- Lists all merge requests assigned to a specified project milestone. GET /projects/:id/milestones/:milestone_id/merge_requests Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `milestone_id` | integer | yes | The ID of the project’s milestone | Promote a milestone to group milestone -------------------------------------- History * [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0. * [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169256) the minimum user role from Reporter to Planner in GitLab 17.7. Promotes a project milestone to a group milestone. Only for users with the Planner, Reporter, Developer, Maintainer, or Owner role for the group. POST /projects/:id/milestones/:milestone_id/promote Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `milestone_id` | integer | yes | The ID of the project’s milestone | List all burndown chart events for a milestone ---------------------------------------------- * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Lists all burndown chart events for a specified milestone. GET /projects/:id/milestones/:milestone_id/burndown_events Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `milestone_id` | integer | yes | The ID of the project’s milestone | --- # Project badges API | GitLab Docs * * * Project badges API ================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage project [badges](https://docs.gitlab.com/user/project/badges/) . Badges support placeholders that are replaced in real time in both the link and image URL. The following placeholders are available: * `%{project_path}`: Replaced by the project path. * `%{project_title}`: Replaced by the project title. * `%{project_name}`: Replaced by the project name. * `%{project_id}`: Replaced by the project ID. * `%{project_namespace}`: Replaced by the project’s namespace full path. * `%{group_name}`: Replaced by the project’s top-level group name. * `%{gitlab_server}`: Replaced by the project’s server name. * `%{gitlab_pages_domain}`: Replaced by the domain name hosting GitLab Pages. * `%{default_branch}`: Replaced by the project default branch. * `%{commit_sha}`: Replaced by the project’s last commit SHA. * `%{latest_tag}`: Replaced by the project’s last tag. List all badges of a project ---------------------------- Lists all badges for a project, including group badges. GET /projects/:id/badges | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `name` | string | no | Name of the badges to return (case-sensitive). | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/badges?name=Coverage" Example response: [\ {\ "name": "Coverage",\ "id": 1,\ "link_url": "http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}",\ "image_url": "https://shields.io/my/badge",\ "rendered_link_url": "http://example.com/ci_status.svg?project=example-org/example-project&ref=main",\ "rendered_image_url": "https://shields.io/my/badge",\ "kind": "project"\ },\ {\ "name": "Pipeline",\ "id": 2,\ "link_url": "http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}",\ "image_url": "https://shields.io/my/badge",\ "rendered_link_url": "http://example.com/ci_status.svg?project=example-org/example-project&ref=main",\ "rendered_image_url": "https://shields.io/my/badge",\ "kind": "group"\ }\ ] Retrieve a badge of a project ----------------------------- Retrieves a badge of a project. GET /projects/:id/badges/:badge_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `badge_id` | integer | yes | The badge ID | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id" Example response: { "name": "Coverage", "id": 1, "link_url": "http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}", "image_url": "https://shields.io/my/badge", "rendered_link_url": "http://example.com/ci_status.svg?project=example-org/example-project&ref=main", "rendered_image_url": "https://shields.io/my/badge", "kind": "project" } Create a badge for a project ---------------------------- Creates a badge for a project. POST /projects/:id/badges | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `link_url` | string | yes | URL of the badge link | | `image_url` | string | yes | URL of the badge image | | `name` | string | no | Name of the badge | curl --request POST \ --header "PRIVATE-TOKEN: " \ --form "link_url=https://gitlab.com/gitlab-org/gitlab-foss/commits/main" \ --form "image_url=https://shields.io/my/badge1" \ --form "name=mybadge" \ --url "https://gitlab.example.com/api/v4/projects/:id/badges" Example response: { "id": 1, "name": "mybadge", "link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/main", "image_url": "https://shields.io/my/badge1", "rendered_link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/main", "rendered_image_url": "https://shields.io/my/badge1", "kind": "project" } Update a badge of a project --------------------------- Updates a badge of a project. PUT /projects/:id/badges/:badge_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `badge_id` | integer | yes | The badge ID | | `link_url` | string | no | URL of the badge link | | `image_url` | string | no | URL of the badge image | | `name` | string | no | Name of the badge | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id" Example response: { "id": 1, "name": "mybadge", "link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/main", "image_url": "https://shields.io/my/badge", "rendered_link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/main", "rendered_image_url": "https://shields.io/my/badge", "kind": "project" } Delete a badge from a project ----------------------------- Deletes a badge from a project. To delete group badges, use the [Group badges API](https://docs.gitlab.com/api/group_badges/) instead. DELETE /projects/:id/badges/:badge_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `badge_id` | integer | yes | The badge ID | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id" Preview a badge from a project ------------------------------ Returns how the `link_url` and `image_url` final URLs would be after resolving the placeholder interpolation. GET /projects/:id/badges/render | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `link_url` | string | yes | URL of the badge link | | `image_url` | string | yes | URL of the badge image | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/badges/render?link_url=http%3A%2F%2Fexample.com%2Fci_status.svg%3Fproject%3D%25%7Bproject_path%7D%26ref%3D%25%7Bdefault_branch%7D&image_url=https%3A%2F%2Fshields.io%2Fmy%2Fbadge" Example response: { "link_url": "http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}", "image_url": "https://shields.io/my/badge", "rendered_link_url": "http://example.com/ci_status.svg?project=example-org/example-project&ref=main", "rendered_image_url": "https://shields.io/my/badge" } --- # Project-level Secure Files API | GitLab Docs * * * Project-level Secure Files API ============================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/350748) in GitLab 15.7. Feature flag `ci_secure_files` removed. Use this API to manage [secure files](https://docs.gitlab.com/ci/secure_files/) for a project. List all secure files for a project ----------------------------------- Lists all secure files for a specified project. GET /projects/:project_id/secure_files Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `project_id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/secure_files" Example response: [\ {\ "id": 1,\ "name": "myfile.jks",\ "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac",\ "checksum_algorithm": "sha256",\ "created_at": "2022-02-22T22:22:22.222Z",\ "expires_at": null,\ "metadata": null\ },\ {\ "id": 2,\ "name": "myfile.cer",\ "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aa2",\ "checksum_algorithm": "sha256",\ "created_at": "2022-02-22T22:22:22.222Z",\ "expires_at": "2023-09-21T14:55:59.000Z",\ "metadata": {\ "id":"75949910542696343243264405377658443914",\ "issuer": {\ "C":"US",\ "O":"Apple Inc.",\ "CN":"Apple Worldwide Developer Relations Certification Authority",\ "OU":"G3"\ },\ "subject": {\ "C":"US",\ "O":"Organization Name",\ "CN":"Apple Distribution: Organization Name (ABC123XYZ)",\ "OU":"ABC123XYZ",\ "UID":"ABC123XYZ"\ },\ "expires_at":"2023-09-21T14:55:59.000Z"\ }\ }\ ] Retrieve details of a secure file --------------------------------- Retrieves details of a specified secure file in a project. GET /projects/:project_id/secure_files/:id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of a secure file. | | `project_id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/secure_files/1" Example response: { "id": 1, "name": "myfile.jks", "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac", "checksum_algorithm": "sha256", "created_at": "2022-02-22T22:22:22.222Z", "expires_at": null, "metadata": null } Create a secure file -------------------- Creates a secure file in a specified project. POST /projects/:project_id/secure_files Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `file` | file | Yes | The file being uploaded (5 MB limit). | | `name` | string | Yes | The name of the file being uploaded. The filename must be unique in the project. | | `project_id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/secure_files" \ --form "name=myfile.jks" \ --form "file=@/path/to/file/myfile.jks" Example response: { "id": 1, "name": "myfile.jks", "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac", "checksum_algorithm": "sha256", "created_at": "2022-02-22T22:22:22.222Z", "expires_at": null, "metadata": null } Download a secure file ---------------------- Downloads the contents of a specified secure file in a project. GET /projects/:project_id/secure_files/:id/download Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of a secure file. | | `project_id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/secure_files/1/download" \ --output myfile.jks Delete a secure file -------------------- Deletes a specified secure file from a project. DELETE /projects/:project_id/secure_files/:id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of a secure file. | | `project_id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/secure_files/1" --- # Project-level CI/CD variables API | GitLab Docs * * * Project-level CI/CD variables API ================================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * Introduced [`filter`](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9. Use this API to interact with [CI/CD variables](https://docs.gitlab.com/ci/variables/#for-a-project) for a project. List project variables ---------------------- Lists all variables for a project. Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. GET /projects/:id/variables | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/variables" Example response: [\ {\ "variable_type": "env_var",\ "key": "TEST_VARIABLE_1",\ "value": "TEST_1",\ "protected": false,\ "masked": true,\ "hidden": false,\ "raw": false,\ "environment_scope": "*",\ "description": null\ },\ {\ "variable_type": "env_var",\ "key": "TEST_VARIABLE_2",\ "value": "TEST_2",\ "protected": false,\ "masked": false,\ "hidden": false,\ "raw": false,\ "environment_scope": "*",\ "description": null\ }\ ] Retrieve a single variable -------------------------- Retrieves details of a single variable. If there are multiple variables with the same key, use `filter` to select the correct `environment_scope`. GET /projects/:id/variables/:key | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the project. | | `key` | string | Yes | Key of a variable. | | `filter` | hash | No | Filters results when multiple variables share the same key. Possible values: `[environment_scope]`. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/variables/TEST_VARIABLE_1" Example response: { "key": "TEST_VARIABLE_1", "variable_type": "env_var", "value": "TEST_1", "protected": false, "masked": true, "hidden": false, "raw": false, "environment_scope": "*", "description": null } Example request with `filter`: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/variables/SCOPED_VARIABLE_1" \ --form "filter[environment_scope]=production" Create a variable ----------------- History * `masked_and_hidden` and `hidden` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29674) in GitLab 17.4. Creates a new variable. If a variable with the same `key` already exists, the new variable must have a different `environment_scope`. Otherwise, GitLab returns a message similar to: `VARIABLE_NAME has already been taken`. POST /projects/:id/variables | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `key` | string | Yes | The `key` of a variable; must have no more than 255 characters; only `A-Z`, `a-z`, `0-9`, and `_` are allowed | | `value` | string | Yes | The `value` of a variable | | `description` | string | No | The description of the variable. Default: `null`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/409641)
in GitLab 16.2. | | `environment_scope` | string | No | The `environment_scope` of the variable. Default: `*` | | `masked` | boolean | No | Whether the variable is masked. Default: `false` | | `masked_and_hidden` | boolean | No | Whether the variable is masked and hidden. Default: `false` | | `protected` | boolean | No | Whether the variable is protected. Default: `false` | | `raw` | boolean | No | Whether the variable is treated as a raw string. Default: `true`. When `false`, variables in the value are [expanded](https://docs.gitlab.com/ci/variables/#allow-cicd-variable-expansion)
. | | `variable_type` | string | No | The type of a variable. Available types are: `env_var` (default) and `file` | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/variables" \ --form "key=NEW_VARIABLE" \ --form "value=new value" Example response: { "variable_type": "env_var", "key": "NEW_VARIABLE", "value": "new value", "protected": false, "masked": false, "hidden": false, "raw": false, "environment_scope": "*", "description": null } Update a variable ----------------- Updates a project variable. If there are multiple variables with the same key, use `filter` to select the correct `environment_scope`. PUT /projects/:id/variables/:key | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the project. | | `key` | string | Yes | Key of a variable. | | `value` | string | Yes | Value of a variable. | | `description` | string | No | Description of the variable. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/409641)
in GitLab 16.2. Default: `null`. | | `environment_scope` | string | No | Environment scope of the variable. | | `filter` | hash | No | Filters results when multiple variables share the same key. Possible values: `[environment_scope]`. | | `masked` | boolean | No | If `true`, indicates the variable is masked. | | `protected` | boolean | No | If `true`, indicates the variable is protected. | | `raw` | boolean | No | If `true`, indicates the variable is treated as a raw string. When `false`, the variable value is [expanded](https://docs.gitlab.com/ci/variables/#allow-cicd-variable-expansion)
. Default: `true`. | | `variable_type` | string | No | Type of a variable. Available types are: `env_var` (default) and `file`. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/variables/NEW_VARIABLE" \ --form "value=updated value" Example response: { "variable_type": "env_var", "key": "NEW_VARIABLE", "value": "updated value", "protected": true, "masked": false, "hidden": false, "raw": false, "environment_scope": "*", "description": "null" } Example request with `filter`: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/variables/SCOPED_VARIABLE_1" \ --form "value=updated value" \ --form "environment_scope=production" \ --form "filter[environment_scope]=production" Delete a variable ----------------- Deletes a project variable. If there are multiple variables with the same key, use `filter` to select the correct `environment_scope`. DELETE /projects/:id/variables/:key | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the project. | | `key` | string | Yes | Key of a variable. | | `filter` | hash | No | Filters results when multiple variables share the same key. Possible values: `[environment_scope]`. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " --url "https://gitlab.example.com/api/v4/projects/1/variables/VARIABLE_1" Example request with `filter`: curl --request DELETE \ --header "PRIVATE-TOKEN: " --url "https://gitlab.example.com/api/v4/projects/1/variables/SCOPED_VARIABLE_1" \ --form "filter[environment_scope]=production" --- # Project remote mirrors API | GitLab Docs * * * Project remote mirrors API ========================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [remote mirrors](https://docs.gitlab.com/user/project/repository/mirror/push/) . You can query and modify the state of these mirrors with the remote mirror API. For security reasons, the `url` attribute in the API response is always scrubbed of username and password information. [Pull mirrors](https://docs.gitlab.com/user/project/repository/mirror/pull/) use [a different API endpoint](https://docs.gitlab.com/api/project_pull_mirroring/#update-project-pull-mirroring-settings) to display and update them. List all remote mirrors for a project ------------------------------------- History * Attribute `host_keys` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203435) in GitLab 18.4. Lists all remote mirrors for a specified project. GET /projects/:id/remote_mirrors Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `auth_method` | string | Authentication method used for the mirror. | | `enabled` | boolean | If `true`, the mirror is enabled. | | `host_keys` | array | Array of SSH host key fingerprints for the remote mirror. | | `id` | integer | ID of the remote mirror. | | `keep_divergent_refs` | boolean | If `true`, divergent refs are kept when mirroring. | | `last_error` | string | Error message from the last mirror attempt. `null` if successful. | | `last_successful_update_at` | string | Timestamp of the last successful mirror update. ISO 8601 format. | | `last_update_at` | string | Timestamp of the last mirror attempt. ISO 8601 format. | | `last_update_started_at` | string | Timestamp when the last mirror attempt started. ISO 8601 format. | | `only_protected_branches` | boolean | If `true`, only protected branches are mirrored. | | `update_status` | string | Status of the mirror update. Possible values: `none`, `scheduled`, `started`, `finished`, `failed`. | | `url` | string | Mirror URL with credentials scrubbed for security. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/remote_mirrors" Example response: [\ {\ "enabled": true,\ "id": 101486,\ "auth_method": "ssh_public_key",\ "last_error": null,\ "last_successful_update_at": "2020-01-06T17:32:02.823Z",\ "last_update_at": "2020-01-06T17:32:02.823Z",\ "last_update_started_at": "2020-01-06T17:31:55.864Z",\ "only_protected_branches": true,\ "keep_divergent_refs": true,\ "update_status": "finished",\ "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git",\ "host_keys": [\ {\ "fingerprint_sha256": "SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw"\ }\ ]\ }\ ] Retrieve a remote mirror for a project -------------------------------------- History * Attribute `host_keys` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203435) in GitLab 18.4. Retrieves a specified remote mirror for a project. GET /projects/:id/remote_mirrors/:mirror_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `mirror_id` | integer | Yes | ID of the remote mirror. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `enabled` | boolean | If `true`, the mirror is enabled. | | `id` | integer | ID of the remote mirror. | | `host_keys` | array | Array of SSH host key fingerprints for the remote mirror. | | `keep_divergent_refs` | boolean | If `true`, divergent refs are kept when mirroring. | | `last_error` | string | Error message from the last mirror attempt. `null` if successful. | | `last_successful_update_at` | string | Timestamp of the last successful mirror update. ISO 8601 format. | | `last_update_at` | string | Timestamp of the last mirror attempt. ISO 8601 format. | | `last_update_started_at` | string | Timestamp when the last mirror attempt started. ISO 8601 format. | | `only_protected_branches` | boolean | If `true`, only protected branches are mirrored. | | `update_status` | string | Status of the mirror update. Possible values: `none`, `scheduled`, `started`, `finished`, `failed`. | | `url` | string | Mirror URL with credentials scrubbed for security. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486" Example response: { "enabled": true, "id": 101486, "last_error": null, "last_successful_update_at": "2020-01-06T17:32:02.823Z", "last_update_at": "2020-01-06T17:32:02.823Z", "last_update_started_at": "2020-01-06T17:31:55.864Z", "only_protected_branches": true, "keep_divergent_refs": true, "update_status": "finished", "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git", "host_keys": [\ {\ "fingerprint_sha256": "SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw"\ }\ ] } Retrieve a public key for a remote mirror ----------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180291) in GitLab 17.9. Retrieves the public key of a specified remote mirror that uses SSH authentication. GET /projects/:id/remote_mirrors/:mirror_id/public_key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `mirror_id` | integer | Yes | ID of the remote mirror. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `public_key` | string | Public key of the remote mirror. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486/public_key" Example response: { "public_key": "ssh-rsa AAAAB3NzaC1yc2EA..." } Create a pull mirror -------------------- Learn how to [configure a pull mirror](https://docs.gitlab.com/api/project_pull_mirroring/#update-project-pull-mirroring-settings) by using the project pull mirroring API. Create a push mirror -------------------- History * [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/381667) in GitLab 16.0. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/410354) in GitLab 16.2. Feature flag `mirror_only_branches_match_regex` removed. * Field `auth_method` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75155) in GitLab 16.10. * Attribute `host_keys` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203435) in GitLab 18.4. Each project can have a maximum of 10 enabled push mirrors. For more information, see [maximum number of project push mirrors](https://docs.gitlab.com/administration/instance_limits/#maximum-number-of-project-push-mirrors) . Create a push mirror for a project. Push mirroring is disabled by default. To enable it, include the optional parameter `enabled` when you create the mirror. POST /projects/:id/remote_mirrors Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `url` | string | Yes | Target URL to which the repository is mirrored. | | `auth_method` | string | No | Mirror authentication method. Accepted values: `ssh_public_key`, `password`. | | `enabled` | boolean | No | If `true`, the mirror is enabled. | | `host_keys` | array of strings | No | SSH host keys in bare format (`ssh-ed25519 AAAA...`) or full `known_hosts` format (`hostname ssh-ed25519 AAAA...`). Bare keys use the hostname from the mirror URL. | | `keep_divergent_refs` | boolean | No | If `true`, divergent refs are kept when mirroring. | | `mirror_branch_regex` | string | No | Regular expression for branch names to mirror. Only branches with names matching the regex are mirrored. Requires `only_protected_branches` to be disabled. Premium and Ultimate only. | | `only_protected_branches` | boolean | No | If `true`, only protected branches are mirrored. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `auth_method` | string | Authentication method used for the mirror. | | `enabled` | boolean | If `true`, the mirror is enabled. | | `host_keys` | array | Array of SSH host key fingerprints for the remote mirror. | | `id` | integer | ID of the remote mirror. | | `keep_divergent_refs` | boolean | If `true`, divergent refs are kept when mirroring. | | `last_error` | string | Error message from the last mirror attempt. `null` if successful. | | `last_successful_update_at` | string | Timestamp of the last successful mirror update. ISO 8601 format. | | `last_update_at` | string | Timestamp of the last mirror attempt. ISO 8601 format. | | `last_update_started_at` | string | Timestamp when the last mirror attempt started. ISO 8601 format. | | `only_protected_branches` | boolean | If `true`, only protected branches are mirrored. | | `update_status` | string | Status of the mirror update. Possible values: `none`, `scheduled`, `started`, `finished`, `failed`. | | `url` | string | Mirror URL with credentials scrubbed for security. | Example request: curl --request POST \ --data "url=https://username:token@example.com/gitlab/example.git" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/remote_mirrors" Example response: { "enabled": false, "id": 101486, "auth_method": "password", "last_error": null, "last_successful_update_at": null, "last_update_at": null, "last_update_started_at": null, "only_protected_branches": false, "keep_divergent_refs": false, "update_status": "none", "url": "https://*****:*****@example.com/gitlab/example.git", "host_keys": [\ {\ "fingerprint_sha256": "SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw"\ }\ ] } Update a remote mirror in a project ----------------------------------- History * Field `auth_method` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75155) in GitLab 16.10. * Attribute `host_keys` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203435) in GitLab 18.4. Updates the configuration or operational status of a specified remote mirror. PUT /projects/:id/remote_mirrors/:mirror_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `mirror_id` | integer | Yes | ID of the remote mirror. | | `auth_method` | string | No | Mirror authentication method. Accepted values: `ssh_public_key`, `password`. | | `enabled` | boolean | No | If `true`, the mirror is enabled. | | `host_keys` | array of strings | No | SSH host keys in bare format (`ssh-ed25519 AAAA...`) or full `known_hosts` format (`hostname ssh-ed25519 AAAA...`). Bare keys use the hostname from the mirror URL. | | `keep_divergent_refs` | boolean | No | If `true`, divergent refs are kept when mirroring. | | `mirror_branch_regex` | string | No | Regular expression for branch names to mirror. Only branches with names matching the regex are mirrored. Does not work with `only_protected_branches` enabled. Premium and Ultimate only. | | `only_protected_branches` | boolean | No | If `true`, only protected branches are mirrored. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `auth_method` | string | Authentication method used for the mirror. | | `enabled` | boolean | If `true`, the mirror is enabled. | | `host_keys` | array | Array of SSH host key fingerprints for the remote mirror. | | `id` | integer | ID of the remote mirror. | | `keep_divergent_refs` | boolean | If `true`, divergent refs are kept when mirroring. | | `last_error` | string | Error message from the last mirror attempt. `null` if successful. | | `last_successful_update_at` | string | Timestamp of the last successful mirror update. ISO 8601 format. | | `last_update_at` | string | Timestamp of the last mirror attempt. ISO 8601 format. | | `last_update_started_at` | string | Timestamp when the last mirror attempt started. ISO 8601 format. | | `only_protected_branches` | boolean | If `true`, only protected branches are mirrored. | | `update_status` | string | Status of the mirror update. Possible values: `none`, `scheduled`, `started`, `finished`, `failed`. | | `url` | string | Mirror URL with credentials scrubbed for security. | Example request: curl --request PUT \ --data "enabled=false" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486" Example response: { "enabled": false, "id": 101486, "auth_method": "password", "last_error": null, "last_successful_update_at": "2020-01-06T17:32:02.823Z", "last_update_at": "2020-01-06T17:32:02.823Z", "last_update_started_at": "2020-01-06T17:31:55.864Z", "only_protected_branches": true, "keep_divergent_refs": true, "update_status": "finished", "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git", "host_keys": [\ {\ "fingerprint_sha256": "SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw"\ }\ ] } Force push mirror update ------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/388907) in GitLab 16.11. [Force an update](https://docs.gitlab.com/user/project/repository/mirror/#force-an-update) to a push mirror. POST /projects/:id/remote_mirrors/:mirror_id/sync Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `mirror_id` | integer | Yes | ID of the remote mirror. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486/sync" Delete a remote mirror from a project ------------------------------------- Deletes a specified remote mirror from a project. DELETE /projects/:id/remote_mirrors/:mirror_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `mirror_id` | integer | Yes | ID of the remote mirror. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486" --- # Project issue boards API | GitLab Docs * * * Project issue boards API ======================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [issue boards](https://docs.gitlab.com/user/project/issue_board/) . Every call to this API requires authentication. If a user is not a member of a private project, a `GET` request on that project results in a `404` status code. List all project issue boards ----------------------------- Lists all issue boards in a specified project. GET /projects/:id/boards | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards" Example response: [\ {\ "id" : 1,\ "name": "board1",\ "hide_backlog_list": false,\ "hide_closed_list": false,\ "project": {\ "id": 5,\ "name": "Diaspora Project Site",\ "name_with_namespace": "Diaspora / Diaspora Project Site",\ "path": "diaspora-project-site",\ "path_with_namespace": "diaspora/diaspora-project-site",\ "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",\ "web_url": "http://example.com/diaspora/diaspora-project-site"\ },\ "milestone": {\ "id": 12,\ "title": "10.0"\ },\ "lists" : [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ }\ ]\ }\ ] Another example response when no board has been activated or exist in the project: [] Retrieve an issue board ----------------------- Retrieves a specified issue board in a project. GET /projects/:id/boards/:board_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1" Example response: { "id": 1, "name": "project issue board", "hide_backlog_list": false, "hide_closed_list": false, "project": { "id": 5, "name": "Diaspora Project Site", "name_with_namespace": "Diaspora / Diaspora Project Site", "path": "diaspora-project-site", "path_with_namespace": "diaspora/diaspora-project-site", "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git", "web_url": "http://example.com/diaspora/diaspora-project-site" }, "milestone": { "id": 12, "title": "10.0" }, "lists" : [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ }\ ] } Create an issue board --------------------- Creates an issue board in a specified project. POST /projects/:id/boards | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | yes | The name of the new board. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards" \ --data "name=newboard" Example response: { "id": 1, "name": "newboard", "hide_backlog_list": false, "hide_closed_list": false, "project": { "id": 5, "name": "Diaspora Project Site", "name_with_namespace": "Diaspora / Diaspora Project Site", "path": "diaspora-project-site", "path_with_namespace": "diaspora/diaspora-project-site", "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git", "web_url": "http://example.com/diaspora/diaspora-project-site" }, "lists" : [], "group": null, "milestone": null, "assignee" : null, "labels" : [], "weight" : null } Update an issue board --------------------- Updates a specified issue board in a project. PUT /projects/:id/boards/:board_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | | `name` | string | no | The new name of the board. | | `hide_backlog_list` | boolean | no | Hide the Open list. | | `hide_closed_list` | boolean | no | Hide the Closed list. | | `assignee_id` | integer | no | The assignee the board should be scoped to. Premium and Ultimate only. | | `milestone_id` | integer | no | The milestone the board should be scoped to. Premium and Ultimate only. | | `labels` | string | no | Comma-separated list of label names which the board should be scoped to. Premium and Ultimate only. | | `weight` | integer | no | The weight range from 0 to 9, to which the board should be scoped to. Premium and Ultimate only. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1" \ --data "name=new_name&milestone_id=43&assignee_id=1&labels=Doing&weight=4" Example response: { "id": 1, "name": "new_name", "hide_backlog_list": false, "hide_closed_list": false, "project": { "id": 5, "name": "Diaspora Project Site", "name_with_namespace": "Diaspora / Diaspora Project Site", "path": "diaspora-project-site", "path_with_namespace": "diaspora/diaspora-project-site", "created_at": "2018-07-03T05:48:49.982Z", "default_branch": null, "tag_list": [], //deprecated, use `topics` instead "topics": [], "ssh_url_to_repo": "ssh://user@example.com/diaspora/diaspora-project-site.git", "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git", "web_url": "http://example.com/diaspora/diaspora-project-site", "readme_url": null, "avatar_url": null, "star_count": 0, "forks_count": 0, "last_activity_at": "2018-07-03T05:48:49.982Z" }, "lists": [], "group": null, "milestone": { "id": 43, "iid": 1, "project_id": 15, "title": "Milestone 1", "description": "Milestone 1 desc", "state": "active", "created_at": "2018-07-03T06:36:42.618Z", "updated_at": "2018-07-03T06:36:42.618Z", "due_date": null, "start_date": null, "web_url": "http://example.com/root/board1/milestones/1" }, "assignee": { "id": 1, "name": "Administrator", "username": "root", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://example.com/root" }, "labels": [{\ "id": 10,\ "name": "Doing",\ "color": "#5CB85C",\ "description": null\ }], "weight": 4 } Delete an issue board --------------------- Deletes a specified issue board in a project. DELETE /projects/:id/boards/:board_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1" List all board lists in an issue board -------------------------------------- Lists all lists in a specified issue board. Does not include `open` and `closed` lists. GET /projects/:id/boards/:board_id/lists | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1/lists" Example response: [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3,\ "max_issue_count": 0,\ "max_issue_weight": 0,\ "limit_metric": null\ }\ ] Retrieve a board list --------------------- Retrieves a specified list from an issue board. GET /projects/:id/boards/:board_id/lists/:list_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | | `list_id` | integer | yes | The ID of a board’s list. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1" Example response: { "id" : 1, "label" : { "name" : "Testing", "color" : "#F0AD4E", "description" : null }, "position" : 1, "max_issue_count": 0, "max_issue_weight": 0, "limit_metric": null } Create a board list ------------------- Creates a new issue board list. POST /projects/:id/boards/:board_id/lists | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | | `label_id` | integer | no | The ID of a label. | | `assignee_id` | integer | no | The ID of a user. Premium and Ultimate only. | | `milestone_id` | integer | no | The ID of a milestone. Premium and Ultimate only. | | `iteration_id` | integer | no | The ID of a iteration. Premium and Ultimate only. | Label, assignee and milestone arguments are mutually exclusive, that is, only one of them are accepted in a request. Check the [issue board documentation](https://docs.gitlab.com/user/project/issue_board/) for more information regarding the required license for each list type. curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1/lists" \ --data "label_id=5" Example response: { "id" : 1, "label" : { "name" : "Testing", "color" : "#F0AD4E", "description" : null }, "position" : 1, "max_issue_count": 0, "max_issue_weight": 0, "limit_metric": null } Update a board list ------------------- Updates the position of a specified list from an issue board. PUT /projects/:id/boards/:board_id/lists/:list_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | | `list_id` | integer | yes | The ID of a board’s list. | | `position` | integer | yes | The position of the list. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1" \ --data "position=2" Example response: { "id" : 1, "label" : { "name" : "Testing", "color" : "#F0AD4E", "description" : null }, "position" : 1, "max_issue_count": 0, "max_issue_weight": 0, "limit_metric": null } Delete a board list from a board -------------------------------- Deletes a specified list from an issue board. Only for administrators and project owners. DELETE /projects/:id/boards/:board_id/lists/:list_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `board_id` | integer | yes | The ID of a board. | | `list_id` | integer | yes | The ID of a board’s list. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1" --- # Project security settings API | GitLab Docs * * * Project security settings API ============================= * Tier: Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Every API call to project security settings must be [authenticated](https://docs.gitlab.com/api/rest/authentication/) . If a project is private, and a user isn’t a member of the project to which the security setting belongs, requests to that project returns a `404 Not Found` status code. List all project security settings ---------------------------------- Lists all security settings for the project. Prerequisites: * You must have the Security Manager, Developer, Maintainer, or Owner role for the project. GET /projects/:id/security_settings | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/7/security_settings" Example response: { "project_id": 7, "created_at": "2024-08-27T15:30:33.075Z", "updated_at": "2024-10-16T05:09:22.233Z", "auto_fix_container_scanning": true, "auto_fix_dast": true, "auto_fix_dependency_scanning": true, "auto_fix_sast": true, "continuous_vulnerability_scans_enabled": true, "container_scanning_for_registry_enabled": false, "secret_push_protection_enabled": true } Update the `secret_push_protection_enabled` setting --------------------------------------------------- History * [Renamed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/185310) from `pre_receive_secret_detection_enabled` in GitLab 17.11. Updates the `secret_push_protection_enabled` setting for the specified project. Prerequisites: * You must have the Maintainer or Owner role for the project. PUT /projects/:id/security_settings | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `secret_push_protection_enabled` | boolean | Yes | Enables secret push protection for the project. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/7/security_settings?secret_push_protection_enabled=false" Example response: { "project_id": 7, "created_at": "2024-08-27T15:30:33.075Z", "updated_at": "2024-10-16T05:09:22.233Z", "auto_fix_container_scanning": true, "auto_fix_dast": true, "auto_fix_dependency_scanning": true, "auto_fix_sast": true, "continuous_vulnerability_scans_enabled": true, "container_scanning_for_registry_enabled": false, "secret_push_protection_enabled": false } --- # Project forks API | GitLab Docs * * * Project forks API ================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage forks of GitLab projects. For more information, see [forks](https://docs.gitlab.com/user/project/repository/forking_workflow/) . Create a fork of a project -------------------------- Create a fork of the specified project. Prerequisites: * You must be authenticated. The forking operation for a project is asynchronous and is completed in a background job. The request returns immediately. To determine whether the fork of the project has completed, query the `import_status` for the new project. POST /projects/:id/fork | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `branches` | string | No | Branches to fork (empty for all branches). | | `description` | string | No | The description assigned to the resultant project after forking. | | `mr_default_target_self` | boolean | No | For forked projects, target merge requests to this project. If `false`, the target is the upstream project. | | `name` | string | No | The name assigned to the resultant project after forking. | | `namespace_id` | integer | No | The ID of the namespace that the project is forked to. | | `namespace_path` | string | No | The path of the namespace that the project is forked to. | | `namespace` | integer or string | No | _(Deprecated)_ The ID or path of the namespace that the project is forked to. | | `path` | string | No | The path assigned to the resultant project after forking. | | `visibility` | string | No | The [visibility level](https://docs.gitlab.com/api/projects/#project-visibility-level)
assigned to the resultant project after forking. | When using a service account to fork a project, you must provide either `namespace_id` or `namespace_path`. Service accounts cannot fork projects to their personal namespace. For more information, see [add a service account to a group or project](https://docs.gitlab.com/user/profile/service_accounts/#add-a-service-account-to-a-group-or-project) . List all forks of a project --------------------------- List all forks of the specified project. Only returns forks that are accessible to you. GET /projects/:id/forks Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `archived` | boolean | No | Limit by archived status. | | `membership` | boolean | No | Limit by projects that the current user is a member of. | | `min_access_level` | integer | No | Limit to projects where the current user has at least the specified access level. Possible values: `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). | | `order_by` | string | No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `star_count`, or `last_activity_at` fields. Default is `created_at`. | | `owned` | boolean | No | Limit by projects explicitly owned by the current user. | | `search` | string | No | Return list of projects matching the search criteria. | | `simple` | boolean | No | Return only limited fields for each project. Without authentication, this operation is a no-op; only simple fields are returned. | | `sort` | string | No | Return projects sorted in `asc` or `desc` order. Default is `desc`. | | `starred` | boolean | No | Limit by projects starred by the current user. | | `statistics` | boolean | No | Include project statistics. Available only to users with the Reporter, Developer, Maintainer, or Owner role. | | `updated_after` | datetime | No | Limit results to projects last updated after the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979)
in GitLab 15.10. | | `updated_before` | datetime | No | Limit results to projects last updated before the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979)
in GitLab 15.10. | | `visibility` | string | No | Limit by visibility `public`, `internal`, or `private`. | | `with_custom_attributes` | boolean | No | Include [custom attributes](https://docs.gitlab.com/api/custom_attributes/)
in response. _(administrators only)_ | | `with_issues_enabled` | boolean | No | Limit by enabled issues feature. | | `with_merge_requests_enabled` | boolean | No | Limit by enabled merge requests feature. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/forks" Example responses: [\ {\ "id": 3,\ "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",\ "description_html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

",\ "default_branch": "main",\ "visibility": "internal",\ "ssh_url_to_repo": "git@example.com:diaspora/diaspora-project-site.git",\ "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",\ "web_url": "http://example.com/diaspora/diaspora-project-site",\ "readme_url": "http://example.com/diaspora/diaspora-project-site/blob/main/README.md",\ "tag_list": [ //deprecated, use `topics` instead\ "example",\ "disapora project"\ ],\ "topics": [\ "example",\ "disapora project"\ ],\ "name": "Diaspora Project Site",\ "name_with_namespace": "Diaspora / Diaspora Project Site",\ "path": "diaspora-project-site",\ "path_with_namespace": "diaspora/diaspora-project-site",\ "repository_object_format": "sha1",\ "issues_enabled": true,\ "open_issues_count": 1,\ "merge_requests_enabled": true,\ "jobs_enabled": true,\ "wiki_enabled": true,\ "snippets_enabled": false,\ "can_create_merge_request_in": true,\ "resolve_outdated_diff_discussions": false,\ "container_registry_enabled": false, // deprecated, use container_registry_access_level instead\ "container_registry_access_level": "disabled",\ "security_and_compliance_access_level": "disabled",\ "created_at": "2013-09-30T13:46:02Z",\ "updated_at": "2013-09-30T13:46:02Z",\ "last_activity_at": "2013-09-30T13:46:02Z",\ "creator_id": 3,\ "namespace": {\ "id": 3,\ "name": "Diaspora",\ "path": "diaspora",\ "kind": "group",\ "full_path": "diaspora"\ },\ "import_status": "none",\ "archived": true,\ "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",\ "shared_runners_enabled": true,\ "group_runners_enabled": true,\ "forks_count": 0,\ "star_count": 1,\ "public_jobs": true,\ "shared_with_groups": [],\ "only_allow_merge_if_pipeline_succeeds": false,\ "allow_merge_on_skipped_pipeline": false,\ "restrict_user_defined_variables": false,\ "only_allow_merge_if_all_discussions_are_resolved": false,\ "remove_source_branch_after_merge": false,\ "request_access_enabled": false,\ "merge_method": "merge",\ "squash_option": "default_on",\ "autoclose_referenced_issues": true,\ "enforce_auth_checks_on_uploads": true,\ "suggestion_commit_message": null,\ "merge_commit_template": null,\ "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site",\ "_links": {\ "self": "http://example.com/api/v4/projects",\ "issues": "http://example.com/api/v4/projects/1/issues",\ "merge_requests": "http://example.com/api/v4/projects/1/merge_requests",\ "repo_branches": "http://example.com/api/v4/projects/1/repository_branches",\ "labels": "http://example.com/api/v4/projects/1/labels",\ "events": "http://example.com/api/v4/projects/1/events",\ "members": "http://example.com/api/v4/projects/1/members",\ "cluster_agents": "http://example.com/api/v4/projects/1/cluster_agents"\ }\ }\ ] Create a fork relationship -------------------------- Create a fork relationship between two specified projects. Prerequisites: * You must be an administrator or be assigned the Owner role on the project. POST /projects/:id/fork/:forked_from_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `forked_from_id` | ID | Yes | The ID of the project that was forked from. | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Delete a fork relationship -------------------------- Delete a fork relationship between two specified projects. Prerequisites: * You must be an administrator or be assigned the Owner role on the project. DELETE /projects/:id/fork Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | --- # Group repository storage moves API | GitLab Docs * * * Group repository storage moves API ================================== * Tier: Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Use this API to manage [group repository storage moves](https://docs.gitlab.com/administration/operations/moving_repositories/) . This API can help you, for example, [migrate to Gitaly Cluster (Praefect)](https://docs.gitlab.com/administration/gitaly/praefect/#migrate-to-gitaly-cluster-praefect) or migrate a [group wiki](https://docs.gitlab.com/user/project/wiki/group/) . This API does not manage project repositories in a group. To schedule project moves, use the [project repository storage moves API](https://docs.gitlab.com/api/project_repository_storage_moves/) . As GitLab processes a group repository storage move, it transitions through different states. Values of `state` are: * `initial`: The record has been created, but the background job has not yet been scheduled. * `scheduled`: The background job has been scheduled. * `started`: The group repositories are being copied to the destination storage. * `replicated`: The group has been moved. * `failed`: The group repositories failed to copy, or the checksums did not match. * `finished`: The group has been moved, and the repositories on the source storage have been deleted. * `cleanup failed`: The group has been moved, but the repositories on the source storage could not be deleted. To ensure data integrity, GitLab places groups in a temporary read-only state for the duration of the move. During this time, users receive this message if they try to push new commits: The repository is temporarily read-only. Please try again later. This API requires you to [authenticate yourself](https://docs.gitlab.com/api/rest/authentication/) as an administrator. APIs are also available to move other types of repositories: * [Project repository storage moves API](https://docs.gitlab.com/api/project_repository_storage_moves/) . * [Snippet repository storage moves API](https://docs.gitlab.com/api/snippet_repository_storage_moves/) . List all group repository storage moves --------------------------------------- Lists all group repository storage moves for an instance. GET /group_repository_storage_moves By default, `GET` requests return 20 results at a time, because the API results are [paginated](https://docs.gitlab.com/api/rest/#pagination) . Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/group_repository_storage_moves" Example response: [\ {\ "id": 1,\ "created_at": "2020-05-07T04:27:17.234Z",\ "state": "scheduled",\ "source_storage_name": "default",\ "destination_storage_name": "storage2",\ "group": {\ "id": 283,\ "web_url": "https://gitlab.example.com/groups/testgroup",\ "name": "testgroup"\ }\ }\ ] List all repository storage moves for a group --------------------------------------------- Lists all repository storage moves for a specified group. GET /groups/:group_id/repository_storage_moves By default, `GET` requests return 20 results at a time, because the API results are [paginated](https://docs.gitlab.com/api/rest/#pagination) . Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `group_id` | integer | yes | ID of the group. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/repository_storage_moves" Example response: [\ {\ "id": 1,\ "created_at": "2020-05-07T04:27:17.234Z",\ "state": "scheduled",\ "source_storage_name": "default",\ "destination_storage_name": "storage2",\ "group": {\ "id": 283,\ "web_url": "https://gitlab.example.com/groups/testgroup",\ "name": "testgroup"\ }\ }\ ] Retrieve a group repository storage move ---------------------------------------- Retrieves a specified group repository storage move. GET /group_repository_storage_moves/:repository_storage_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `repository_storage_id` | integer | yes | ID of the group repository storage move. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/group_repository_storage_moves/1" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "group": { "id": 283, "web_url": "https://gitlab.example.com/groups/testgroup", "name": "testgroup" } } Retrieve a repository storage move for a group ---------------------------------------------- Retrieves a specified repository storage move for a group. GET /groups/:group_id/repository_storage_moves/:repository_storage_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `group_id` | integer | yes | ID of the group. | | `repository_storage_id` | integer | yes | ID of the group repository storage move. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/repository_storage_moves/1" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "group": { "id": 283, "web_url": "https://gitlab.example.com/groups/testgroup", "name": "testgroup" } } Create a group repository storage move -------------------------------------- Creates a group repository storage move for a specified group. This endpoint: * Moves only group Wiki repositories. * Doesn’t move repositories for projects in a group. To schedule project moves, use the [Project repository storage moves](https://docs.gitlab.com/api/project_repository_storage_moves/) API. POST /groups/:group_id/repository_storage_moves Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `group_id` | integer | yes | ID of the group. | | `destination_storage_name` | string | no | Name of the destination storage shard. The storage is selected [based on storage weights](https://docs.gitlab.com/administration/repository_storage_paths/#configure-where-new-repositories-are-stored)
if not provided. | Example request: curl --request POST --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"destination_storage_name":"storage2"}' \ --url "https://gitlab.example.com/api/v4/groups/1/repository_storage_moves" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "group": { "id": 283, "web_url": "https://gitlab.example.com/groups/testgroup", "name": "testgroup" } } Create group repository storage moves for a storage shard --------------------------------------------------------- Creates repository storage moves for all groups on a specified storage shard. POST /group_repository_storage_moves Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `source_storage_name` | string | yes | Name of the source storage shard. | | `destination_storage_name` | string | no | Name of the destination storage shard. The storage is selected [based on storage weights](https://docs.gitlab.com/administration/repository_storage_paths/#configure-where-new-repositories-are-stored)
if not provided. | Example request: curl --request POST --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"default"}' \ --url "https://gitlab.example.com/api/v4/group_repository_storage_moves" Example response: { "message": "202 Accepted" } Related topics -------------- * [Moving repositories managed by GitLab](https://docs.gitlab.com/administration/operations/moving_repositories/) --- # Project clusters API (certificate-based) (deprecated) | GitLab Docs * * * Project clusters API (certificate-based) (deprecated) ===================================================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. Users need the Maintainer or Owner role to use these endpoints. List all clusters in a project ------------------------------ Lists all clusters in a specified project. GET /projects/:id/clusters Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/26/clusters" Example response: [\ {\ "id":18,\ "name":"cluster-1",\ "domain":"example.com",\ "created_at":"2019-01-02T20:18:12.563Z",\ "managed": true,\ "enabled": true,\ "provider_type":"user",\ "platform_type":"kubernetes",\ "environment_scope":"*",\ "cluster_type":"project_type",\ "user":\ {\ "id":1,\ "name":"Administrator",\ "username":"root",\ "state":"active",\ "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..",\ "web_url":"https://gitlab.example.com/root"\ },\ "platform_kubernetes":\ {\ "api_url":"https://104.197.68.152",\ "namespace":"cluster-1-namespace",\ "authorization_type":"rbac",\ "ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----"\ },\ "management_project":\ {\ "id":2,\ "description":null,\ "name":"project2",\ "name_with_namespace":"John Doe8 / project2",\ "path":"project2",\ "path_with_namespace":"namespace2/project2",\ "created_at":"2019-10-11T02:55:54.138Z"\ }\ },\ {\ "id":19,\ "name":"cluster-2",\ ...\ }\ ] Retrieve a cluster from a project --------------------------------- Retrieves a specified cluster in a project. GET /projects/:id/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `cluster_id` | integer | yes | The ID of the cluster | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/26/clusters/18" Example response: { "id":18, "name":"cluster-1", "domain":"example.com", "created_at":"2019-01-02T20:18:12.563Z", "managed": true, "enabled": true, "provider_type":"user", "platform_type":"kubernetes", "environment_scope":"*", "cluster_type":"project_type", "user": { "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..", "web_url":"https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url":"https://104.197.68.152", "namespace":"cluster-1-namespace", "authorization_type":"rbac", "ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----" }, "management_project": { "id":2, "description":null, "name":"project2", "name_with_namespace":"John Doe8 / project2", "path":"project2", "path_with_namespace":"namespace2/project2", "created_at":"2019-10-11T02:55:54.138Z" }, "project": { "id":26, "description":"", "name":"project-with-clusters-api", "name_with_namespace":"Administrator / project-with-clusters-api", "path":"project-with-clusters-api", "path_with_namespace":"root/project-with-clusters-api", "created_at":"2019-01-02T20:13:32.600Z", "default_branch":null, "tag_list":[], //deprecated, use `topics` instead "topics":[], "ssh_url_to_repo":"ssh://gitlab.example.com/root/project-with-clusters-api.git", "http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git", "web_url":"https://gitlab.example.com/root/project-with-clusters-api", "readme_url":null, "avatar_url":null, "star_count":0, "forks_count":0, "last_activity_at":"2019-01-02T20:13:32.600Z", "namespace": { "id":1, "name":"root", "path":"root", "kind":"user", "full_path":"root", "parent_id":null } } } Add a cluster to a project -------------------------- Adds an existing cluster to a specified project. POST /projects/:id/clusters/user Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `name` | string | yes | The name of the cluster | | `domain` | string | no | The [base domain](https://docs.gitlab.com/user/project/clusters/gitlab_managed_clusters/#base-domain)
of the cluster | | `management_project_id` | integer | no | The ID of the [management project](https://docs.gitlab.com/user/clusters/management_project/)
for the cluster | | `enabled` | boolean | no | Determines if cluster is active or not, defaults to `true` | | `managed` | boolean | no | Determines if GitLab manages namespaces and service accounts for this cluster. Defaults to `true` | | `platform_kubernetes_attributes[api_url]` | string | yes | The URL to access the Kubernetes API | | `platform_kubernetes_attributes[token]` | string | yes | The token to authenticate against Kubernetes | | `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. | | `platform_kubernetes_attributes[namespace]` | string | no | The unique namespace related to the project | | `platform_kubernetes_attributes[authorization_type]` | string | no | The cluster authorization type: `rbac`, `abac` or `unknown_authorization`. Defaults to `rbac`. | | `environment_scope` | string | no | The associated environment to the cluster. Defaults to `*`. Premium and Ultimate only. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Accept: application/json" \ --header "Content-Type:application/json" \ --data '{"name":"cluster-5", "platform_kubernetes_attributes":{"api_url":"https://35.111.51.20","token":"12345","namespace":"cluster-5-namespace","ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----"}}' \ --url "https://gitlab.example.com/api/v4/projects/26/clusters/user" Example response: { "id":24, "name":"cluster-5", "created_at":"2019-01-03T21:53:40.610Z", "managed": true, "enabled": true, "provider_type":"user", "platform_type":"kubernetes", "environment_scope":"*", "cluster_type":"project_type", "user": { "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..", "web_url":"https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url":"https://35.111.51.20", "namespace":"cluster-5-namespace", "authorization_type":"rbac", "ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----" }, "management_project":null, "project": { "id":26, "description":"", "name":"project-with-clusters-api", "name_with_namespace":"Administrator / project-with-clusters-api", "path":"project-with-clusters-api", "path_with_namespace":"root/project-with-clusters-api", "created_at":"2019-01-02T20:13:32.600Z", "default_branch":null, "tag_list":[], //deprecated, use `topics` instead "topics":[], "ssh_url_to_repo":"ssh:://gitlab.example.com/root/project-with-clusters-api.git", "http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git", "web_url":"https://gitlab.example.com/root/project-with-clusters-api", "readme_url":null, "avatar_url":null, "star_count":0, "forks_count":0, "last_activity_at":"2019-01-02T20:13:32.600Z", "namespace": { "id":1, "name":"root", "path":"root", "kind":"user", "full_path":"root", "parent_id":null } } } Update a cluster in a project ----------------------------- Updates a cluster in a specified project. PUT /projects/:id/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `cluster_id` | integer | yes | The ID of the cluster | | `name` | string | no | The name of the cluster | | `domain` | string | no | The [base domain](https://docs.gitlab.com/user/project/clusters/gitlab_managed_clusters/#base-domain)
of the cluster | | `management_project_id` | integer | no | The ID of the [management project](https://docs.gitlab.com/user/clusters/management_project/)
for the cluster | | `enabled` | boolean | no | Determines if cluster is active or not | | `managed` | boolean | no | Determines if GitLab manages namespaces and service accounts for this cluster | | `platform_kubernetes_attributes[api_url]` | string | no | The URL to access the Kubernetes API | | `platform_kubernetes_attributes[token]` | string | no | The token to authenticate against Kubernetes | | `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. | | `platform_kubernetes_attributes[namespace]` | string | no | The unique namespace related to the project | | `environment_scope` | string | no | The associated environment to the cluster | `name`, `api_url`, `ca_cert` and `token` can only be updated if the cluster was added through the [“Add existing Kubernetes cluster”](https://docs.gitlab.com/user/project/clusters/add_existing_cluster/) option or through the [“Add existing cluster to project”](https://docs.gitlab.com/api/project_clusters/#add-a-cluster-to-a-project) endpoint. Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type:application/json" \ --data '{"name":"new-cluster-name","domain":"new-domain.com","api_url":"https://new-api-url.com"}' \ --url "https://gitlab.example.com/api/v4/projects/26/clusters/24" Example response: { "id":24, "name":"new-cluster-name", "domain":"new-domain.com", "created_at":"2019-01-03T21:53:40.610Z", "managed": true, "enabled": true, "provider_type":"user", "platform_type":"kubernetes", "environment_scope":"*", "cluster_type":"project_type", "user": { "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..", "web_url":"https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url":"https://new-api-url.com", "namespace":"cluster-5-namespace", "authorization_type":"rbac", "ca_cert":null }, "management_project": { "id":2, "description":null, "name":"project2", "name_with_namespace":"John Doe8 / project2", "path":"project2", "path_with_namespace":"namespace2/project2", "created_at":"2019-10-11T02:55:54.138Z" }, "project": { "id":26, "description":"", "name":"project-with-clusters-api", "name_with_namespace":"Administrator / project-with-clusters-api", "path":"project-with-clusters-api", "path_with_namespace":"root/project-with-clusters-api", "created_at":"2019-01-02T20:13:32.600Z", "default_branch":null, "tag_list":[], //deprecated, use `topics` instead "topics":[], "ssh_url_to_repo":"ssh:://gitlab.example.com/root/project-with-clusters-api.git", "http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git", "web_url":"https://gitlab.example.com/root/project-with-clusters-api", "readme_url":null, "avatar_url":null, "star_count":0, "forks_count":0, "last_activity_at":"2019-01-02T20:13:32.600Z", "namespace": { "id":1, "name":"root", "path":"root", "kind":"user", "full_path":"root", "parent_id":null } } } Delete cluster from a project ----------------------------- Deletes a specified cluster from a project. Does not remove existing resources in the connected Kubernetes cluster. DELETE /projects/:id/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `cluster_id` | integer | yes | The ID of the cluster | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/26/clusters/23" --- # Pipelines API | GitLab Docs * * * Pipelines API ============= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with [CI/CD pipelines](https://docs.gitlab.com/ci/pipelines/) . List project pipelines ---------------------- History * `name` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115310) in GitLab 15.11 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `pipeline_name_in_api`. Disabled by default. * `name` in request [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115310) in 15.11 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `pipeline_name_search`. Disabled by default. * `name` in response [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/398131) in GitLab 16.3. Feature flag `pipeline_name_in_api` removed. * `name` in request [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/385864) in GitLab 16.9. Feature flag `pipeline_name_search` removed. * Support for returning child pipelines with `source` set to `parent_pipeline` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39503) in GitLab 17.0. Lists pipelines in a project. By default, [child pipelines](https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#parent-child-pipelines) are not included in the results. To return child pipelines, set `source` to `parent_pipeline`. GET /projects/:id/pipelines Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | No | Return pipelines with the specified name. | | `order_by` | string | No | The field to order pipelines by: `id`, `status`, `ref`, `updated_at`, or `user_id` (default: `id`). | | `ref` | string | No | Return pipelines for the specified branch or tag. | | `scope` | string | No | Return pipelines in the specified scope: `running`, `pending`, `finished`, `branches`, or `tags`. | | `sha` | string | No | Return pipelines for the specified commit SHA. | | `sort` | string | No | The sort order: `asc` or `desc` (default: `desc`). | | `source` | string | No | Return pipelines with the specified [source](https://docs.gitlab.com/ci/jobs/job_rules/#ci_pipeline_source-predefined-variable)
. | | `status` | string | No | Return pipelines with the specified status: `created`, `waiting_for_resource`, `preparing`, `pending`, `running`, `success`, `failed`, `canceled`, `skipped`, `manual`, or `scheduled`. | | `updated_after` | datetime | No | Return pipelines updated after the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `updated_before` | datetime | No | Return pipelines updated before the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_after` | datetime | No | Return pipelines created after the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | No | Return pipelines created before the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `username` | string | No | Return pipelines triggered by the specified username. | | `yaml_errors` | boolean | No | Return pipelines with invalid configurations. | When `scope` is set to `branches` or `tags`, the API returns only the latest pipeline for each branch or tag ref. curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines" Example of response [\ {\ "id": 47,\ "iid": 12,\ "project_id": 1,\ "status": "pending",\ "source": "push",\ "ref": "new-pipeline",\ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",\ "name": "Build pipeline",\ "web_url": "https://example.com/foo/bar/pipelines/47",\ "created_at": "2016-08-11T11:28:34.085Z",\ "updated_at": "2016-08-11T11:32:35.169Z"\ },\ {\ "id": 48,\ "iid": 13,\ "project_id": 1,\ "status": "pending",\ "source": "web",\ "ref": "new-pipeline",\ "sha": "eb94b618fb5865b26e80fdd8ae531b7a63ad851a",\ "name": "Build pipeline",\ "web_url": "https://example.com/foo/bar/pipelines/48",\ "created_at": "2016-08-12T10:06:04.561Z",\ "updated_at": "2016-08-12T10:09:56.223Z"\ }\ ] Retrieve a single pipeline -------------------------- History * `name` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115310) in GitLab 15.11 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `pipeline_name_in_api`. Disabled by default. * `name` in response [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/398131) in GitLab 16.3. Feature flag `pipeline_name_in_api` removed. Retrieves a single pipeline from a project. You can also get a single [child pipeline](https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#parent-child-pipelines) . GET /projects/:id/pipelines/:pipeline_id Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `pipeline_id` | integer | Yes | The ID of a pipeline | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46" Example of response { "id": 287, "iid": 144, "project_id": 21, "name": "Build pipeline", "sha": "50f0acb76a40e34a4ff304f7347dcc6587da8a14", "ref": "main", "status": "success", "source": "push", "created_at": "2022-09-21T01:05:07.200Z", "updated_at": "2022-09-21T01:05:50.185Z", "web_url": "http://127.0.0.1:3000/test-group/test-project/-/pipelines/287", "before_sha": "8a24fb3c5877a6d0b611ca41fc86edc174593e2b", "tag": false, "yaml_errors": null, "user": { "id": 1, "username": "root", "name": "Administrator", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://127.0.0.1:3000/root" }, "started_at": "2022-09-21T01:05:14.197Z", "finished_at": "2022-09-21T01:05:50.175Z", "committed_at": null, "duration": 34, "queued_duration": 6, "coverage": null, "detailed_status": { "icon": "status_success", "text": "passed", "label": "passed", "group": "success", "tooltip": "passed", "has_details": false, "details_path": "/test-group/test-project/-/pipelines/287", "illustration": null, "favicon": "/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png" }, "archived": false } Retrieve the latest pipeline ---------------------------- History * `name` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115310) in GitLab 15.11 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `pipeline_name_in_api`. Disabled by default. * `name` in response [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/398131) in GitLab 16.3. Feature flag `pipeline_name_in_api` removed. Retrieves the latest pipeline for the most recent commit on a specific ref in a project. If no pipeline exists for the commit, a `403` status code is returned. GET /projects/:id/pipelines/latest Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `ref` | string | No | The branch or tag to check for the latest pipeline. Defaults to the default branch when not specified. | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/latest" Example of response { "id": 287, "iid": 144, "project_id": 21, "name": "Build pipeline", "sha": "50f0acb76a40e34a4ff304f7347dcc6587da8a14", "ref": "main", "status": "success", "source": "push", "created_at": "2022-09-21T01:05:07.200Z", "updated_at": "2022-09-21T01:05:50.185Z", "web_url": "http://127.0.0.1:3000/test-group/test-project/-/pipelines/287", "before_sha": "8a24fb3c5877a6d0b611ca41fc86edc174593e2b", "tag": false, "yaml_errors": null, "user": { "id": 1, "username": "root", "name": "Administrator", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://127.0.0.1:3000/root" }, "started_at": "2022-09-21T01:05:14.197Z", "finished_at": "2022-09-21T01:05:50.175Z", "committed_at": null, "duration": 34, "queued_duration": 6, "coverage": null, "detailed_status": { "icon": "status_success", "text": "passed", "label": "passed", "group": "success", "tooltip": "passed", "has_details": false, "details_path": "/test-group/test-project/-/pipelines/287", "illustration": null, "favicon": "/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png" }, "archived": false } Retrieve pipeline variables --------------------------- Retrieves the [pipeline variables](https://docs.gitlab.com/ci/variables/#use-pipeline-variables) of a pipeline. GET /projects/:id/pipelines/:pipeline_id/variables Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `pipeline_id` | integer | Yes | The ID of a pipeline | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46/variables" Example of response [\ {\ "key": "RUN_NIGHTLY_BUILD",\ "variable_type": "env_var",\ "value": "true"\ },\ {\ "key": "foo",\ "value": "bar"\ }\ ] Retrieve a test report for a pipeline ------------------------------------- This API route is part of the [Unit test report](https://docs.gitlab.com/ci/testing/unit_test_reports/) feature. GET /projects/:id/pipelines/:pipeline_id/test_report Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `pipeline_id` | integer | Yes | The ID of a pipeline | Sample request: curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46/test_report" Sample response: { "total_time": 5, "total_count": 1, "success_count": 1, "failed_count": 0, "skipped_count": 0, "error_count": 0, "test_suites": [\ {\ "name": "Secure",\ "total_time": 5,\ "total_count": 1,\ "success_count": 1,\ "failed_count": 0,\ "skipped_count": 0,\ "error_count": 0,\ "test_cases": [\ {\ "status": "success",\ "name": "Security Reports can create an auto-remediation MR",\ "classname": "vulnerability_management_spec",\ "execution_time": 5,\ "system_output": null,\ "stack_trace": null\ }\ ]\ }\ ] } Retrieve a test report summary for a pipeline --------------------------------------------- This API route is part of the [Unit test report](https://docs.gitlab.com/ci/testing/unit_test_reports/) feature. GET /projects/:id/pipelines/:pipeline_id/test_report_summary Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to control the pagination of results. | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `pipeline_id` | integer | Yes | The ID of a pipeline | Sample request: curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46/test_report_summary" Sample response: { "total": { "time": 1904, "count": 3363, "success": 3351, "failed": 0, "skipped": 12, "error": 0, "suite_error": null }, "test_suites": [\ {\ "name": "test",\ "total_time": 1904,\ "total_count": 3363,\ "success_count": 3351,\ "failed_count": 0,\ "skipped_count": 12,\ "error_count": 0,\ "build_ids": [\ 66004\ ],\ "suite_error": null\ }\ ] } Create a new pipeline --------------------- History * `iid` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/342223) in GitLab 14.6. * `inputs` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/519958) in GitLab 17.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `ci_inputs_for_pipelines`. Enabled by default. * `inputs` attribute [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/536548) in GitLab 18.1. Feature flag `ci_inputs_for_pipelines` removed. POST /projects/:id/pipeline | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `ref` | string | Yes | The branch or tag to run the pipeline on. For merge request pipelines use the [merge requests endpoint](https://docs.gitlab.com/api/merge_requests/#create-merge-request-pipeline)
. | | `variables` | array | No | An [array of hashes](https://docs.gitlab.com/api/rest/#array-of-hashes)
containing the variables available in the pipeline, matching the structure `[{ 'key': 'UPLOAD_TO_S3', 'variable_type': 'file', 'value': 'true' }, {'key': 'TEST', 'value': 'test variable'}]`. If `variable_type` is excluded, it defaults to `env_var`. | | `inputs` | hash | No | A [hash](https://docs.gitlab.com/api/rest/#hash)
containing the inputs, as key-value pairs, to use when creating the pipeline. | Basic example: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipeline?ref=main" Example request with [inputs](https://docs.gitlab.com/ci/inputs/) : curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"inputs": {"environment": "environment", "scan_security": false, "level": 3}}' \ --url "https://gitlab.example.com/api/v4/projects/1/pipeline?ref=main" Example of response { "id": 61, "iid": 21, "project_id": 1, "sha": "384c444e840a515b23f21915ee5766b87068a70d", "ref": "main", "status": "pending", "before_sha": "0000000000000000000000000000000000000000", "tag": false, "yaml_errors": null, "user": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://localhost:3000/root" }, "created_at": "2016-11-04T09:36:13.747Z", "updated_at": "2016-11-04T09:36:13.977Z", "started_at": null, "finished_at": null, "committed_at": null, "duration": null, "queued_duration": 0.010, "coverage": null, "web_url": "https://example.com/foo/bar/pipelines/61", "archived": false } Retry jobs in a pipeline ------------------------ History * `iid` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/342223) in GitLab 14.6. Retries failed or canceled jobs in a pipeline. If there are no failed or canceled jobs in the pipeline, calling this endpoint has no effect. POST /projects/:id/pipelines/:pipeline_id/retry | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `pipeline_id` | integer | Yes | The ID of a pipeline | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46/retry" Response: { "id": 46, "iid": 11, "project_id": 1, "status": "pending", "ref": "main", "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", "before_sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", "tag": false, "yaml_errors": null, "user": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://localhost:3000/root" }, "created_at": "2016-08-11T11:28:34.085Z", "updated_at": "2016-08-11T11:32:35.169Z", "started_at": null, "finished_at": "2016-08-11T11:32:35.145Z", "committed_at": null, "duration": null, "queued_duration": 0.010, "coverage": null, "web_url": "https://example.com/foo/bar/pipelines/46", "archived": false } Cancel all jobs for a pipeline ------------------------------ POST /projects/:id/pipelines/:pipeline_id/cancel This endpoint returns a success response `200` regardless of the pipeline’s state. For more information, see [issue 414963](https://gitlab.com/gitlab-org/gitlab/-/issues/414963) . | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `pipeline_id` | integer | Yes | The ID of a pipeline | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46/cancel" Response: { "id": 46, "iid": 11, "project_id": 1, "status": "canceled", "ref": "main", "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", "before_sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", "tag": false, "yaml_errors": null, "user": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://localhost:3000/root" }, "created_at": "2016-08-11T11:28:34.085Z", "updated_at": "2016-08-11T11:32:35.169Z", "started_at": null, "finished_at": "2016-08-11T11:32:35.145Z", "committed_at": null, "duration": null, "queued_duration": 0.010, "coverage": null, "web_url": "https://example.com/foo/bar/pipelines/46", "archived": false } Delete a pipeline ----------------- Deleting a pipeline expires all pipeline caches, and deletes all immediately related objects, such as builds, logs, artifacts, and triggers. **This action cannot be undone**. Deleting a pipeline does not automatically delete its [child pipelines](https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#parent-child-pipelines) . See the [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/39503) for details. DELETE /projects/:id/pipelines/:pipeline_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `pipeline_id` | integer | Yes | The ID of a pipeline | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46" Update pipeline metadata ------------------------ Updates pipeline metadata. The metadata contains the name of the pipeline. PUT /projects/:id/pipelines/:pipeline_id/metadata | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `name` | string | Yes | The new name of the pipeline | | `pipeline_id` | integer | Yes | The ID of a pipeline | Sample request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"name": "Some new pipeline name"}' \ --url "https://gitlab.example.com/api/v4/projects/1/pipelines/46/metadata" Sample response: { "id": 46, "iid": 11, "project_id": 1, "status": "running", "ref": "main", "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", "before_sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", "tag": false, "yaml_errors": null, "user": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://localhost:3000/root" }, "created_at": "2016-08-11T11:28:34.085Z", "updated_at": "2016-08-11T11:32:35.169Z", "started_at": null, "finished_at": "2016-08-11T11:32:35.145Z", "committed_at": null, "duration": null, "queued_duration": 0.010, "coverage": null, "web_url": "https://example.com/foo/bar/pipelines/46", "name": "Some new pipeline name", "archived": false } --- # Project vulnerabilities API | GitLab Docs * * * Project vulnerabilities API =========================== * Tier: Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * `last_edited_at` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/268154) in GitLab 16.7. * `start_date` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/268154) in GitLab 16.7. * `updated_by_id` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/268154) in GitLab 16.7. * `last_edited_by_id` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/268154) in GitLab 16.7. * `due_date` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/268154) in GitLab 16.7. This API is in the process of being deprecated and considered unstable. The response payload may be subject to change or breakage across GitLab releases. Use the [GraphQL API](https://docs.gitlab.com/api/graphql/reference/#queryvulnerabilities) instead. Use this API to manage [project vulnerabilities](https://docs.gitlab.com/user/application_security/vulnerabilities/) . Every call to this API requires authentication. If a user isn’t a member of a private project, requests to the private project return a `404 Not Found` status code. List project vulnerabilities ---------------------------- List all of a project’s vulnerabilities. If an authenticated user does not have permission to [use the Project Security Dashboard](https://docs.gitlab.com/user/permissions/#project-permissions) , `GET` requests for vulnerabilities of this project result in a `403` status code. Responses are [paginated](https://docs.gitlab.com/api/rest/#pagination) and return 20 results by default. GET /projects/:id/vulnerabilities | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/4/vulnerabilities" Example response: [\ {\ "author_id": 1,\ "confidence": "medium",\ "created_at": "2020-04-07T14:01:04.655Z",\ "description": null,\ "dismissed_at": null,\ "dismissed_by_id": null,\ "finding": {\ "confidence": "medium",\ "created_at": "2020-04-07T14:01:04.630Z",\ "id": 103,\ "location_fingerprint": "228998b5db51d86d3b091939e2f5873ada0a14a1",\ "metadata_version": "2.0",\ "name": "Regular Expression Denial of Service in debug",\ "primary_identifier_id": 135,\ "project_id": 24,\ "raw_metadata": "{\"category\":\"dependency_scanning\",\"name\":\"Regular Expression Denial of Service\",\"message\":\"Regular Expression Denial of Service in debug\",\"description\":\"The debug module is vulnerable to regular expression denial of service when untrusted user input is passed into the `o` formatter. It takes around 50k characters to block for 2 seconds making this a low severity issue.\",\"cve\":\"yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a\",\"severity\":\"Unknown\",\"solution\":\"Upgrade to latest versions.\",\"scanner\":{\"id\":\"gemnasium\",\"name\":\"Gemnasium\"},\"location\":{\"file\":\"yarn.lock\",\"dependency\":{\"package\":{\"name\":\"debug\"},\"version\":\"1.0.5\"}},\"identifiers\":[{\"type\":\"gemnasium\",\"name\":\"Gemnasium-37283ed4-0380-40d7-ada7-2d994afcc62a\",\"value\":\"37283ed4-0380-40d7-ada7-2d994afcc62a\",\"url\":\"https://deps.sec.gitlab.com/packages/npm/debug/versions/1.0.5/advisories\"}],\"links\":[{\"url\":\"https://nodesecurity.io/advisories/534\"},{\"url\":\"https://github.com/visionmedia/debug/issues/501\"},{\"url\":\"https://github.com/visionmedia/debug/pull/504\"}],\"remediations\":[null]}",\ "report_type": "dependency_scanning",\ "scanner_id": 63,\ "severity": "low",\ "updated_at": "2020-04-07T14:01:04.664Z",\ "uuid": "f1d528ae-d0cc-47f6-a72f-936cec846ae7",\ "vulnerability_id": 103\ },\ "id": 103,\ "project": {\ "created_at": "2020-04-07T13:54:25.634Z",\ "description": "",\ "id": 24,\ "name": "security-reports",\ "name_with_namespace": "gitlab-org / security-reports",\ "path": "security-reports",\ "path_with_namespace": "gitlab-org/security-reports"\ },\ "project_default_branch": "main",\ "report_type": "dependency_scanning",\ "resolved_at": null,\ "resolved_by_id": null,\ "resolved_on_default_branch": false,\ "severity": "low",\ "state": "detected",\ "title": "Regular Expression Denial of Service in debug",\ "updated_at": "2020-04-07T14:01:04.655Z"\ }\ ] Create a vulnerability ---------------------- Creates a new vulnerability. If an authenticated user does not have a permission to [create a new vulnerability](https://docs.gitlab.com/user/permissions/#project-permissions) , this request results in a `403` status code. POST /projects/:id/vulnerabilities?finding_id= | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
which the authenticated user is a member of | | `finding_id` | integer or string | yes | The ID of a Vulnerability Finding to create the new Vulnerability from | The other attributes of a newly created Vulnerability are populated from its source Vulnerability Finding, or with these default values: | Attribute | Value | | --- | --- | | `author` | The authenticated user | | `title` | The `name` attribute of a Vulnerability Finding | | `state` | `opened` | | `severity` | The `severity` attribute of a Vulnerability Finding | | `confidence` | The `confidence` attribute of a Vulnerability Finding | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/vulnerabilities?finding_id=1" Example response: { "author_id": 1, "confidence": "medium", "created_at": "2020-04-07T14:01:04.655Z", "description": null, "dismissed_at": null, "dismissed_by_id": null, "finding": { "confidence": "medium", "created_at": "2020-04-07T14:01:04.630Z", "id": 103, "location_fingerprint": "228998b5db51d86d3b091939e2f5873ada0a14a1", "metadata_version": "2.0", "name": "Regular Expression Denial of Service in debug", "primary_identifier_id": 135, "project_id": 24, "raw_metadata": "{\"category\":\"dependency_scanning\",\"name\":\"Regular Expression Denial of Service\",\"message\":\"Regular Expression Denial of Service in debug\",\"description\":\"The debug module is vulnerable to regular expression denial of service when untrusted user input is passed into the `o` formatter. It takes around 50k characters to block for 2 seconds making this a low severity issue.\",\"cve\":\"yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a\",\"severity\":\"Unknown\",\"solution\":\"Upgrade to latest versions.\",\"scanner\":{\"id\":\"gemnasium\",\"name\":\"Gemnasium\"},\"location\":{\"file\":\"yarn.lock\",\"dependency\":{\"package\":{\"name\":\"debug\"},\"version\":\"1.0.5\"}},\"identifiers\":[{\"type\":\"gemnasium\",\"name\":\"Gemnasium-37283ed4-0380-40d7-ada7-2d994afcc62a\",\"value\":\"37283ed4-0380-40d7-ada7-2d994afcc62a\",\"url\":\"https://deps.sec.gitlab.com/packages/npm/debug/versions/1.0.5/advisories\"}],\"links\":[{\"url\":\"https://nodesecurity.io/advisories/534\"},{\"url\":\"https://github.com/visionmedia/debug/issues/501\"},{\"url\":\"https://github.com/visionmedia/debug/pull/504\"}],\"remediations\":[null]}", "report_type": "dependency_scanning", "scanner_id": 63, "severity": "low", "updated_at": "2020-04-07T14:01:04.664Z", "uuid": "f1d528ae-d0cc-47f6-a72f-936cec846ae7", "vulnerability_id": 103 }, "id": 103, "project": { "created_at": "2020-04-07T13:54:25.634Z", "description": "", "id": 24, "name": "security-reports", "name_with_namespace": "gitlab-org / security-reports", "path": "security-reports", "path_with_namespace": "gitlab-org/security-reports" }, "project_default_branch": "main", "report_type": "dependency_scanning", "resolved_at": null, "resolved_by_id": null, "resolved_on_default_branch": false, "severity": "low", "state": "detected", "title": "Regular Expression Denial of Service in debug", "updated_at": "2020-04-07T14:01:04.655Z" } ### Errors This error occurs when a Finding chosen to create a Vulnerability from is not found, or is already associated with a different Vulnerability: A Vulnerability Finding is not found or already attached to a different Vulnerability Status code: `400` Example response: { "message": { "base": [\ "finding is not found or is already attached to a vulnerability"\ ] } } --- # REST API third-party clients | GitLab Docs * * * REST API third-party clients ============================ * Tier: Free * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated You can integrate third-party API client libraries with GitLab. The following libraries are maintained by community members and not officially supported by GitLab. Report bugs and feature proposals to the respective projects. For questions about these integrations, use the [GitLab community forum](https://forum.gitlab.com/) . Administrators can monitor usage of these API clients by [parsing logs](https://docs.gitlab.com/administration/logs/log_parsing/#print-top-api-user-agents) . `C#` ---- * [`GitLabApiClient`](https://github.com/nmklotas/GitLabApiClient) * [`NGitLab`](https://github.com/ubisoft/NGitLab) Go -- * GitLab [`client-go`](https://gitlab.com/gitlab-org/api/client-go) Haskell ------- * [`gitlab-haskell`](https://hackage.haskell.org/package/gitlab-haskell) Java ---- * [`gitlab4j-api`](https://github.com/gmessner/gitlab4j-api) * [`java-gitlab-api`](https://github.com/timols/java-gitlab-api) Node.js ------- * [`gitlab-yaac`](https://www.npmjs.com/package/gitlab-yaac) * [`backbone-gitlab`](https://github.com/oreillymedia/backbone-gitlab) * [`@gitbeaker/rest`](https://www.npmjs.com/package/@gitbeaker/rest) Perl ---- * [`GitLab::API::v4`](https://metacpan.org/pod/GitLab::API::v4) PHP --- * [`php-gitlab-api`](https://github.com/GitLabPHP/Client) Python ------ * [`python-gitlab`](https://github.com/python-gitlab/python-gitlab) * Blog post: [Efficient DevSecOps workflows: Hands-on `python-gitlab` API automation](https://about.gitlab.com/blog/efficient-devsecops-workflows-hands-on-python-gitlab-api-automation/) * [`libsaas_gitlab`](https://gitlab.com/bor-sh-infrastructure/libsaas_gitlab) Ruby ---- * [Ruby wrapper and CLI for the GitLab REST API](https://github.com/NARKOZ/gitlab) Rust ---- * [`gitlab` crate](https://crates.io/crates/gitlab/) Swift ----- * [`RxGitLabKit`](https://github.com/Qase/RxGitLabKit) --- # Protected packages API | GitLab Docs * * * Protected packages API ====================== * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151741) in GitLab 17.1 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `packages_protected_packages`. Disabled by default. * [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/472655) in GitLab 17.5. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/472655) in GitLab 17.6. Feature flag `packages_protected_packages` removed. * [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180063) `minimum_access_level_for_delete` attribute in GitLab 17.11 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `packages_protected_packages_delete`. Disabled by default. Use this API to manage [protection rules for packages](https://docs.gitlab.com/user/packages/package_registry/package_protection_rules/) . List all package protection rules --------------------------------- Lists all package protection rules for a specified project. GET /api/v4/projects/:id/packages/protection/rules Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and a list of package protection rules. Can return the following status codes: * `200 OK`: A list of package protection rules. * `401 Unauthorized`: The access token is invalid. * `403 Forbidden`: The user does not have permission to list package protection rules for this project. * `404 Not Found`: The project was not found. Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/7/packages/protection/rules" Example response: [\ {\ "id": 1,\ "project_id": 7,\ "package_name_pattern": "@flightjs/flight-package-0",\ "package_type": "npm",\ "minimum_access_level_for_delete": "owner",\ "minimum_access_level_for_push": "maintainer"\ },\ {\ "id": 2,\ "project_id": 7,\ "package_name_pattern": "@flightjs/flight-package-1",\ "package_type": "npm",\ "minimum_access_level_for_delete": "owner",\ "minimum_access_level_for_push": "maintainer"\ }\ ] Create a package protection rule -------------------------------- Creates a package protection rule for a specified project. POST /api/v4/projects/:id/packages/protection/rules Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `package_name_pattern` | string | Yes | Package name protected by the protection rule. For example `@my-scope/my-package-*`. Wildcard character `*` allowed. | | `package_type` | string | Yes | Package type protected by the protection rule. For example `npm`. | | `minimum_access_level_for_delete` | string | Yes | Minimum GitLab access level required to delete a package. Valid values include `null`, `owner` or `admin`. If the value is `null`, the default minimum access level is `maintainer`. Must be provided when `minimum_access_level_for_push` is not set. Behind a feature flag named `packages_protected_packages_delete`. Disabled by default. | | `minimum_access_level_for_push` | string | Yes | Minimum GitLab access level required to push a package. Valid values include `null`, `maintainer`, `owner` or `admin`. If the value is `null`, the default minimum access level is `developer`. Must be provided when `minimum_access_level_for_delete` is not set. | If successful, returns [`201`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the created package protection rule. Can return the following status codes: * `201 Created`: The package protection rule was created successfully. * `400 Bad Request`: The package protection rule is invalid. * `401 Unauthorized`: The access token is invalid. * `403 Forbidden`: The user does not have permission to create a package protection rule. * `404 Not Found`: The project was not found. * `422 Unprocessable Entity`: The package protection rule could not be created, for example, because the `package_name_pattern` is already taken. Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/projects/7/packages/protection/rules" \ --data '{ "package_name_pattern": "package-name-pattern-*", "package_type": "npm", "minimum_access_level_for_delete": "owner", "minimum_access_level_for_push": "maintainer" }' Update a package protection rule -------------------------------- Updates a package protection rule for a specified project. PATCH /api/v4/projects/:id/packages/protection/rules/:package_protection_rule_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `package_protection_rule_id` | integer | Yes | ID of the package protection rule to be updated. | | `package_name_pattern` | string | No | Package name protected by the protection rule. For example `@my-scope/my-package-*`. Wildcard character `*` allowed. | | `package_type` | string | No | Package type protected by the protection rule. For example `npm`. | | `minimum_access_level_for_delete` | string | No | Minimum GitLab access level required to delete a package. Valid values include `null`, `owner` or `admin`. If the value is `null`, the default minimum access level is `maintainer`. Must be provided when `minimum_access_level_for_push` is not set. Behind a feature flag named `packages_protected_packages_delete`. Disabled by default. | | `minimum_access_level_for_push` | string | No | Minimum GitLab access level required to push a package. Valid values include `null`, `maintainer`, `owner` or `admin`. If the value is `null`, the default minimum access level is `developer`. Must be provided when `minimum_access_level_for_delete` is not set. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the updated package protection rule. Can return the following status codes: * `200 OK`: The package protection rule was patched successfully. * `400 Bad Request`: The patch is invalid. * `401 Unauthorized`: The access token is invalid. * `403 Forbidden`: The user does not have permission to patch a package protection rule. * `404 Not Found`: The project was not found. * `422 Unprocessable Entity`: The package protection rule could not be patched, for example, because the `package_name_pattern` is already taken. Example request: curl --request PATCH \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/projects/7/packages/protection/rules/32" \ --data '{ "package_name_pattern": "new-package-name-pattern-*" }' Delete a package protection rule -------------------------------- Deletes a package protection rule from a specified project. DELETE /api/v4/projects/:id/packages/protection/rules/:package_protection_rule_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `package_protection_rule_id` | integer | Yes | ID of the package protection rule to be deleted. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Can return the following status codes: * `204 No Content`: The package protection rule was deleted successfully. * `400 Bad Request`: The `id` or the `package_protection_rule_id` are missing or are invalid. * `401 Unauthorized`: The access token is invalid. * `403 Forbidden`: The user does not have permission to delete the package protection rule. * `404 Not Found`: The project or the package protection rule was not found. Example request: curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/7/packages/protection/rules/32" --- # Pull mirroring API | GitLab Docs * * * Pull mirroring API ================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage project [pull mirroring](https://docs.gitlab.com/user/project/repository/mirror/pull/) . Retrieve project pull mirror details ------------------------------------ History * [Extended response](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168377) to include mirror configuration information in GitLab 17.5. The following configuration settings are included: `enabled`, `mirror_trigger_builds`, `only_mirror_protected_branches`, `mirror_overwrites_diverged_branches`, and `mirror_branch_regex`. Retrieves pull mirror details for a specified project. GET /projects/:id/mirror/pull Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `enabled` | boolean | If `true`, the mirror is active. | | `id` | integer | Unique identifier of the mirror configuration. | | `last_error` | string or null | Most recent error message, if any. `null` if no errors occurred. | | `last_successful_update_at` | string | Timestamp of the last successful mirror update. | | `last_update_at` | string | Timestamp of the most recent mirror update attempt. | | `last_update_started_at` | string | Timestamp when the last mirror update process started. | | `mirror_branch_regex` | string or null | Regex pattern for filtering which branches to mirror. `null` if not set. | | `mirror_overwrites_diverged_branches` | boolean | If `true`, overwrites diverged branches during mirroring. | | `mirror_trigger_builds` | boolean | If `true`, triggers builds for mirror updates. | | `only_mirror_protected_branches` | boolean or null | If `true`, only protected branches are mirrored. If not set, the value is `null`. | | `update_status` | string | Status of the mirror update process. | | `url` | string | URL of the mirrored repository. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/mirror/pull" Example response: { "id": 101486, "last_error": null, "last_successful_update_at": "2020-01-06T17:32:02.823Z", "last_update_at": "2020-01-06T17:32:02.823Z", "last_update_started_at": "2020-01-06T17:31:55.864Z", "update_status": "finished", "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git", "enabled": true, "mirror_trigger_builds": true, "only_mirror_protected_branches": null, "mirror_overwrites_diverged_branches": false, "mirror_branch_regex": null } Update project pull mirroring settings -------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/494294) in GitLab 17.6. Updates pull mirroring settings for a project. PUT /projects/:id/mirror/pull Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `auth_password` | string | No | Password used for authentication of a project to pull mirror. | | `auth_user` | string | No | Username used for authentication of a project to pull mirror. | | `enabled` | boolean | No | If `true`, enables pull mirroring on project when set to `true`. | | `mirror_branch_regex` | string | No | Contains a regular expression. Only branches with names matching the regex are mirrored. Requires `only_mirror_protected_branches` to be disabled. | | `mirror_overwrites_diverged_branches` | boolean | No | If `true`, overwrites diverged branches. | | `mirror_trigger_builds` | boolean | No | If `true`, triggers pipelines for mirror updates. | | `only_mirror_protected_branches` | boolean | No | If `true`, limits mirroring to only protected branches. | | `url` | string | No | URL of remote repository being mirrored. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the updated pull mirror configuration. Example request to add pull mirroring: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "enabled": true, "url": "https://gitlab.example.com/group/project.git", "auth_user": "user", "auth_password": "password" }' \ --url "https://gitlab.example.com/api/v4/projects/:id/mirror/pull" Example request to remove pull mirroring: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --data "enabled=false" \ --url "https://gitlab.example.com/api/v4/projects/:id/mirror/pull" Example response: { "id": 101486, "last_error": null, "last_successful_update_at": "2020-01-06T17:32:02.823Z", "last_update_at": "2020-01-06T17:32:02.823Z", "last_update_started_at": "2020-01-06T17:31:55.864Z", "update_status": "finished", "url": "https://gitlab.example.com/group/project.git", "enabled": true, "mirror_trigger_builds": false, "only_mirror_protected_branches": null, "mirror_overwrites_diverged_branches": false, "mirror_branch_regex": null } Update pull mirroring for a project (deprecated) ------------------------------------------------ History * Feature flag `mirror_only_branches_match_regex` [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/381667) in GitLab 16.0. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/410354) in GitLab 16.2. Feature flag `mirror_only_branches_match_regex` removed. * [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/494294) in GitLab 17.6. This configuration option was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/494294) in GitLab 17.6 and is planned for removal in v5 of the API. Use the [new configuration and endpoint](https://docs.gitlab.com/api/project_pull_mirroring/#update-project-pull-mirroring-settings) instead. This change is a breaking change. If the remote repository is publicly accessible or uses `username:token` authentication, use the API to configure pull mirroring when [creating](https://docs.gitlab.com/api/projects/#create-a-project) or [updating](https://docs.gitlab.com/api/projects/#update-a-project) a project. If your HTTP repository is not publicly accessible, you can add the authentication information to the URL. For example, `https://username:token@gitlab.company.com/group/project.git` where `token` is a [personal access token](https://docs.gitlab.com/user/profile/personal_access_tokens/) with the `api` scope enabled. Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `import_url` | string | Yes | URL of remote repository being mirrored (with `user:token` if needed). | | `mirror` | boolean | Yes | If `true`, enables pull mirroring. | | `mirror_branch_regex` | string | No | Contains a regular expression. Only branches with names matching the regex are mirrored. Requires `only_mirror_protected_branches` to be disabled. | | `mirror_trigger_builds` | boolean | No | If `true`, triggers pipelines for mirror updates. | | `only_mirror_protected_branches` | boolean | No | If `true`, limits mirroring to only protected branches. | Example creating a project with pull mirroring: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "name": "new_project", "namespace_id": "1", "mirror": true, "import_url": "https://username:token@gitlab.example.com/group/project.git" }' \ --url "https://gitlab.example.com/api/v4/projects/" Example adding pull mirroring: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --data "mirror=true&import_url=https://username:token@gitlab.example.com/group/project.git" \ --url "https://gitlab.example.com/api/v4/projects/:id" Example removing pull mirroring: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --data "mirror=false" \ --url "https://gitlab.example.com/api/v4/projects/:id" Start the pull mirroring process for a project ---------------------------------------------- Start the pull mirroring process for a project. POST /projects/:id/mirror/pull Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`202 Accepted`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/mirror/pull" --- # PyPI API | GitLab Docs * * * PyPI API ======== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with the [PyPI package manager client](https://docs.gitlab.com/user/packages/pypi_repository/) . This API is used by the [PyPI package manager client](https://pypi.org/) and is generally not meant for manual consumption. These endpoints do not adhere to the standard API authentication methods. See the [PyPI package registry documentation](https://docs.gitlab.com/user/packages/pypi_repository/) for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future. [Twine 3.4.2](https://twine.readthedocs.io/en/stable/changelog.html?highlight=FIPS#id28) or greater is recommended when FIPS mode is enabled. Download a package file for a group ----------------------------------- Downloads a specified PyPI package file for a group. The [simple API](https://docs.gitlab.com/api/packages/pypi/#retrieve-package-descriptor-for-a-group) usually supplies this URL. GET groups/:id/-/packages/pypi/files/:sha256/:file_identifier | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the group. | | `sha256` | string | yes | The PyPI package file’s sha256 checksum. | | `file_identifier` | string | yes | The PyPI package file’s name. | curl --user : \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" To write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" >> my.pypi.package-0.0.1.tar.gz This writes the downloaded file to `my.pypi.package-0.0.1.tar.gz` in the current directory. List all packages for a group ----------------------------- Lists all packages for the specified group in an HTML file. GET groups/:id/-/packages/pypi/simple | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the group. | curl --user : \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/pypi/simple" Example response: Links for Group

Links for Group

my.pypi.package
package_2
To write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/pypi/simple" >> simple_index.html This writes the downloaded file to `simple_index.html` in the current directory. Retrieve package descriptor for a group --------------------------------------- Retrieves the package descriptor as an HTML file for a specified package in a group. GET groups/:id/-/packages/pypi/simple/:package_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the group. | | `package_name` | string | yes | The name of the package. | curl --user : \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/pypi/simple/my.pypi.package" Example response: Links for my.pypi.package

Links for my.pypi.package

my.pypi.package-0.0.1-py3-none-any.whl
my.pypi.package-0.0.1.tar.gz
To write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/groups/1/-/packages/pypi/simple/my.pypi.package" >> simple.html This writes the downloaded file to `simple.html` in the current directory. Download a package file for a project ------------------------------------- Downloads a specified PyPI package file for a project. The [simple API](https://docs.gitlab.com/api/packages/pypi/#retrieve-package-descriptor-for-a-project) usually supplies this URL. GET projects/:id/packages/pypi/files/:sha256/:file_identifier | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `sha256` | string | yes | PyPI package file sha256 check sum. | | `file_identifier` | string | yes | The PyPI package filename. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" To write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/pypi/files/5y57017232013c8ac80647f4ca153k3726f6cba62d055cd747844ed95b3c65ff/my.pypi.package-0.0.1.tar.gz" >> my.pypi.package-0.0.1.tar.gz This writes the downloaded file to `my.pypi.package-0.0.1.tar.gz` in the current directory. List all packages for a project ------------------------------- Lists all packages for the specified project in an HTML file. GET projects/:id/packages/pypi/simple | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/pypi/simple" Example response: Links for Project

Links for Project

my.pypi.package
package_2
To write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/pypi/simple" >> simple_index.html This writes the downloaded file to `simple_index.html` in the current directory. Retrieve package descriptor for a project ----------------------------------------- Retrieves the package descriptor as an HTML file for a specified package in a project. GET projects/:id/packages/pypi/simple/:package_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `package_name` | string | yes | The name of the package. | curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/pypi/simple/my.pypi.package" Example response: Links for my.pypi.package

Links for my.pypi.package

my.pypi.package-0.0.1-py3-none-any.whl
my.pypi.package-0.0.1.tar.gz
To write the output to a file: curl --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/pypi/simple/my.pypi.package" >> simple.html This writes the downloaded file to `simple.html` in the current directory. Upload a package ---------------- Uploads a PyPI package for a specified project. POST projects/:id/packages/pypi | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Yes | The ID or full path of the project. | | `requires_python` | string | No | The PyPI required version. | | `sha256_digest` | string | No | The SHA256 checksum of the package file. Not required for uploads, but without this attribute, `pip install` fails because package index URLs lack required checksums. | curl --request POST \ --form 'content=@path/to/my.pypi.package-0.0.1.tar.gz' \ --form "sha256_digest=$(shasum -a 256 < path/to/my.pypi.package-0.0.1.tar.gz | cut -d' ' -f1)" \ --form 'name=my.pypi.package' \ --form 'version=1.3.7' \ --user : \ --url "https://gitlab.example.com/api/v4/projects/1/packages/pypi" --- # Ruby gems API | GitLab Docs * * * Ruby gems API ============= * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Use this API to interact with the [Ruby gems and Bundler package manager clients](https://docs.gitlab.com/user/packages/rubygems_registry/) . This API is used by the [Ruby gems and Bundler package manager clients](https://maven.apache.org/) and is generally not meant for manual consumption. This API is under development and is not ready for production use due to limited functionality. These endpoints do not adhere to the standard API authentication methods. See the [Ruby gems registry documentation](https://docs.gitlab.com/user/packages/rubygems_registry/) for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future. Enable the Ruby gems API ------------------------ The Ruby gems API for GitLab is behind a feature flag that is disabled by default. GitLab administrators with access to the GitLab Rails console can enable this API for your instance. To enable it: Feature.enable(:rubygem_packages) To disable it: Feature.disable(:rubygem_packages) To enable or disable it for specific projects: Feature.enable(:rubygem_packages, Project.find(1)) Feature.disable(:rubygem_packages, Project.find(2)) Download a gem file ------------------- Downloads a specified gem file for a project. GET projects/:id/packages/rubygems/gems/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `file_name` | string | yes | The name of the `.gem` file. | curl --header "Authorization:" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/gems/my_gem-1.0.0.gem" Write the output to file: curl --header "Authorization:" "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/gems/my_gem-1.0.0.gem" >> my_gem-1.0.0.gem This writes the downloaded file to `my_gem-1.0.0.gem` in the current directory. Download a gemspec file ----------------------- Downloads a gemspec file in Marshal format for a specific gem version. GET projects/:id/packages/rubygems/quick/Marshal.4.8/:file_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `file_name` | string | yes | The gemspec file name in the format `-.gemspec.rz`. | The response is a deflate-compressed, marshalled `Gem::Specification` object. curl --header "Authorization:" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/quick/Marshal.4.8/my_gem-1.0.0.gemspec.rz" Retrieve dependencies --------------------- Retrieves a list of dependencies for specified gems. The response is a marshalled array of hashes for all versions of the requested gems. Because the response is marshalled, you can store it in a file. GET projects/:id/packages/rubygems/api/v1/dependencies | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | | `gems` | string | no | Comma-separated list of gems to fetch dependencies for. | curl --header "Authorization:" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/api/v1/dependencies?gems=my_gem,foo" If Ruby is installed, you can use the following Ruby command to read the response. For this to work, you must either [set your credentials in `~/.gem/credentials`](https://docs.gitlab.com/user/packages/rubygems_registry/#authenticate-to-the-package-registry) , or pass your access token to the request: $ ruby -ropen-uri -rpp -e \ 'pp Marshal.load(URI.open("https://gitlab.example.com/api/v4/projects/1/packages/rubygems/api/v1/dependencies?gems=my_gem,rails,foo", "Authorization" => ))' [{:name=>"my_gem", :number=>"0.0.1", :platform=>"ruby", :dependencies=>[]},\ {:name=>"my_gem",\ :number=>"0.0.3",\ :platform=>"ruby",\ :dependencies=>\ [["dependency_1", "~> 1.2.3"],\ ["dependency_2", "= 3.0.0"],\ ["dependency_3", ">= 1.0.0"],\ ["dependency_4", ">= 0"]]},\ {:name=>"my_gem",\ :number=>"0.0.2",\ :platform=>"ruby",\ :dependencies=>\ [["dependency_1", "~> 1.2.3"],\ ["dependency_2", "= 3.0.0"],\ ["dependency_3", ">= 1.0.0"],\ ["dependency_4", ">= 0"]]},\ {:name=>"foo",\ :number=>"0.0.2",\ :platform=>"ruby",\ :dependencies=>\ ["dependency_2", "= 3.0.0"],\ ["dependency_4", ">= 0"]]}] Upload a gem ------------ Uploads a gem for a specified project. POST projects/:id/packages/rubygems/api/v1/gems | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | The ID or full path of the project. | curl --request POST \ --upload-file path/to/my_gem_file.gem \ --header "Authorization:" \ --url "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/api/v1/gems" --- # Group activity analytics API | GitLab Docs * * * Group activity analytics API ============================ * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to retrieve information about group activities. For more information, see [group activity analytics](https://docs.gitlab.com/user/group/manage/#group-activity-analytics) . Retrieve count of recently created issues for a group ----------------------------------------------------- Retrieves the count of recently created issues for a specified group. GET /analytics/group_activity/issues_count Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `group_path` | string | yes | Group path | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/analytics/group_activity/issues_count?group_path=gitlab-org" Example response: { "issues_count": 10 } Retrieve count of recently created merge requests for a group ------------------------------------------------------------- Retrieves the count of recently created merge requests for a specified group. GET /analytics/group_activity/merge_requests_count Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `group_path` | string | yes | Group path | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/analytics/group_activity/merge_requests_count?group_path=gitlab-org" Example response: { "merge_requests_count": 10 } Retrieve count of members recently added to a group --------------------------------------------------- Retrieves the count of members recently added to a specified group. GET /analytics/group_activity/new_members_count Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `group_path` | string | yes | Group path | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/analytics/group_activity/new_members_count?group_path=gitlab-org" Example response: { "new_members_count": 10 } --- # Project relations export API | GitLab Docs * * * Project relations export API ============================ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated This API is used by the destination instance during [group migration by direct transfer](https://docs.gitlab.com/user/group/import/) to migrate a project structure. You don’t usually need to use this API yourself. In this context, a ​ is an exportable item such as a merge request. When exported, the relation includes any items related to the relation such as a label. If you want to use this API, your GitLab instance must meet certain [prerequisites](https://docs.gitlab.com/user/group/import/direct_transfer_migrations/#prerequisites) . This API can’t be used with the [group import and export API](https://docs.gitlab.com/api/group_import_export/) , which is for file-based migration. Schedule a new export for a project ----------------------------------- Schedules a relations export for a specified project. POST /projects/:id/export_relations | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID of the project. | | `batched` | boolean | No | Whether to export in batches. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/export_relations" { "message": "202 Accepted" } Retrieve the status of an export -------------------------------- Retrieve the status of a relations export. GET /projects/:id/export_relations/status | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID of the project. | | `relation` | string | No | Name of the project top-level relation to view. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/export_relations/status" The status can be one of the following: * `0`: `started` * `1`: `finished` * `-1`: `failed` [\ {\ "relation": "project_badges",\ "status": 1,\ "error": null,\ "updated_at": "2021-05-04T11:25:20.423Z",\ "batched": true,\ "batches_count": 1,\ "batches": [\ {\ "status": 1,\ "batch_number": 1,\ "objects_count": 1,\ "error": null,\ "updated_at": "2021-05-04T11:25:20.423Z"\ }\ ]\ },\ {\ "relation": "boards",\ "status": 1,\ "error": null,\ "updated_at": "2021-05-04T11:25:20.085Z",\ "batched": false,\ "batches_count": 0\ }\ ] Download an export ------------------ Download the finished relations export. GET /projects/:id/export_relations/download | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID of the project. | | `relation` | string | Yes | Name of the project top-level relation to download. | | `batched` | boolean | No | Whether the export is batched. | | `batch_number` | integer | No | Number of export batch to download. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --remote-header-name \ --remote-name \ --url "https://gitlab.example.com/api/v4/projects/1/export_relations/download?relation=labels" ls labels.ndjson.gz labels.ndjson.gz Related topics -------------- * [Group relations export API](https://docs.gitlab.com/api/group_relations_export/) --- # Project labels API | GitLab Docs * * * Project labels API ================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * `archived` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4233) in GitLab 18.3 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `labels_archive`. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/556700) in GitLab 18.10. Feature flag `labels_archive` removed. Use this API to manage [project labels](https://docs.gitlab.com/user/project/labels/) . For group labels, use the [group labels API](https://docs.gitlab.com/api/group_labels/) . List all project labels ----------------------- Lists all labels for a specified project. By default, this request returns 20 results at a time because the API results [are paginated](https://docs.gitlab.com/api/rest/#pagination) . GET /projects/:id/labels | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. | | `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. | | `search` | string | no | Keyword to filter labels by. | | `archived` | boolean | no | If `true`, returns only archived labels. If unset, returns all labels. | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/labels?with_counts=true" Example response: [\ {\ "id" : 1,\ "name" : "bug",\ "color" : "#d9534f",\ "text_color" : "#FFFFFF",\ "description": "Bug reported by user",\ "description_html": "Bug reported by user",\ "open_issues_count": 1,\ "closed_issues_count": 0,\ "open_merge_requests_count": 1,\ "subscribed": false,\ "priority": 10,\ "is_project_label": true,\ "archived": false\ },\ {\ "id" : 4,\ "color" : "#d9534f",\ "text_color" : "#FFFFFF",\ "name" : "confirmed",\ "description": "Confirmed issue",\ "description_html": "Confirmed issue",\ "open_issues_count": 2,\ "closed_issues_count": 5,\ "open_merge_requests_count": 0,\ "subscribed": false,\ "priority": null,\ "is_project_label": true,\ "archived": false\ },\ {\ "id" : 7,\ "name" : "critical",\ "color" : "#d9534f",\ "text_color" : "#FFFFFF",\ "description": "Critical issue. Need fix ASAP",\ "description_html": "Critical issue. Need fix ASAP",\ "open_issues_count": 1,\ "closed_issues_count": 3,\ "open_merge_requests_count": 1,\ "subscribed": false,\ "priority": null,\ "is_project_label": true,\ "archived": false\ },\ {\ "id" : 8,\ "name" : "documentation",\ "color" : "#f0ad4e",\ "text_color" : "#FFFFFF",\ "description": "Issue about documentation",\ "description_html": "Issue about documentation",\ "open_issues_count": 1,\ "closed_issues_count": 0,\ "open_merge_requests_count": 2,\ "subscribed": false,\ "priority": null,\ "is_project_label": false,\ "archived": false\ },\ {\ "id" : 9,\ "color" : "#5cb85c",\ "text_color" : "#FFFFFF",\ "name" : "enhancement",\ "description": "Enhancement proposal",\ "description_html": "Enhancement proposal",\ "open_issues_count": 1,\ "closed_issues_count": 0,\ "open_merge_requests_count": 1,\ "subscribed": true,\ "priority": null,\ "is_project_label": true,\ "archived": false\ }\ ] Retrieve a project label ------------------------ Retrieves a specified label for a project. GET /projects/:id/labels/:label_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `label_id` | integer or string | yes | The ID or title of a project’s label. | | `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/labels/bug" Example response: { "id" : 1, "name" : "bug", "color" : "#d9534f", "text_color" : "#FFFFFF", "description": "Bug reported by user", "description_html": "Bug reported by user", "open_issues_count": 1, "closed_issues_count": 0, "open_merge_requests_count": 1, "subscribed": false, "priority": 10, "is_project_label": true, "archived": false } Create a project label ---------------------- Creates a label for a specified project with the specified name and color. POST /projects/:id/labels | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `name` | string | yes | The name of the label | | `color` | string | yes | The color of the label given in 6-digit hex notation with leading ‘#’ sign (for example, #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) | | `description` | string | no | The description of the label | | `priority` | integer | no | The priority of the label. Must be greater or equal than zero or `null` to remove the priority. | | `archived` | boolean | no | If `true`, marks the label as archived. Default value: `false`. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/labels" \ --data "name=feature&color=#5843AD" Example response: { "id" : 10, "name" : "feature", "color" : "#5843AD", "text_color" : "#FFFFFF", "description":null, "description_html":null, "open_issues_count": 0, "closed_issues_count": 0, "open_merge_requests_count": 0, "subscribed": false, "priority": null, "is_project_label": true, "archived": false } Delete a project label ---------------------- Deletes a specified label from a project. DELETE /projects/:id/labels/:label_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `label_id` | integer or string | yes | The ID or title of a group’s label. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/labels/bug" An older endpoint `DELETE /projects/:id/labels` with `name` in the parameters is still available, but deprecated. Update a project label ---------------------- Updates a specified label for a project with a new name or color. At least one parameter is required to update the label. PUT /projects/:id/labels/:label_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `label_id` | integer or string | yes | The ID or title of a group’s label. | | `new_name` | string | yes if `color` is not provided | The new name of the label | | `color` | string | yes if `new_name` is not provided | The color of the label given in 6-digit hex notation with leading ‘#’ sign (for example, #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) | | `description` | string | no | The new description of the label | | `priority` | integer | no | The new priority of the label. Must be greater or equal than zero or `null` to remove the priority. | | `archived` | boolean | no | If `true`, marks the label as archived. Default value: `false`. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/labels/documentation" \ --data "new_name=docs&color=#8E44AD&description=Documentation" Example response: { "id" : 8, "name" : "docs", "color" : "#8E44AD", "text_color" : "#FFFFFF", "description": "Documentation", "description_html": "Documentation", "open_issues_count": 1, "closed_issues_count": 0, "open_merge_requests_count": 2, "subscribed": false, "priority": null, "is_project_label": true, "archived": false } An older endpoint `PUT /projects/:id/labels` with `name` or `label_id` in the parameters is still available, but deprecated. Promote a project label to a group label ---------------------------------------- Promotes a specified project label to a group label. The label keeps its ID. PUT /projects/:id/labels/:label_id/promote | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `label_id` | integer or string | yes | The ID or title of a group’s label. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/labels/documentation/promote" Example response: { "id" : 8, "name" : "documentation", "color" : "#8E44AD", "description": "Documentation", "description_html": "Documentation", "open_issues_count": 1, "closed_issues_count": 0, "open_merge_requests_count": 2, "subscribed": false, "archived": false } An older endpoint `PUT /projects/:id/labels/promote` with `name` in the parameters is still available, but deprecated. Subscribe to a project label ---------------------------- Subscribes the authenticated user to a specified project label to receive notifications. If the user is already subscribed to the label, status code `304` is returned. POST /projects/:id/labels/:label_id/subscribe | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `label_id` | integer or string | yes | The ID or title of a project’s label | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/labels/1/subscribe" Example response: { "id" : 1, "name" : "bug", "color" : "#d9534f", "text_color" : "#FFFFFF", "description": "Bug reported by user", "description_html": "Bug reported by user", "open_issues_count": 1, "closed_issues_count": 0, "open_merge_requests_count": 1, "subscribed": true, "priority": null, "is_project_label": true, "archived": false } Unsubscribe from a project label -------------------------------- Unsubscribes the authenticated user from a specified project label to stop receiving notifications. If the user is not subscribed to the label, status code `304` is returned. POST /projects/:id/labels/:label_id/unsubscribe | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `label_id` | integer or string | yes | The ID or title of a project’s label | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/labels/1/unsubscribe" --- # Group badges API | GitLab Docs * * * Group badges API ================ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with group badges. For more information, see [group badges](https://docs.gitlab.com/user/project/badges/#group-badges) . Badges support placeholders that are replaced in real time in both the link and image URL. The following placeholders are available: * `%{project_path}`: replaced by the project path. * `%{project_title}`: replaced by the project title. * `%{project_name}`: replaced by the project name. * `%{project_id}`: replaced by the project ID. * `%{project_namespace}`: replaced by the project’s namespace full path. * `%{group_name}`: replaced by the project’s top-level group name. * `%{gitlab_server}`: replaced by the project’s server name. * `%{gitlab_pages_domain}`: replaced by the domain name hosting GitLab Pages. * `%{default_branch}`: replaced by the project default branch. * `%{commit_sha}`: replaced by the project’s last commit SHA. * `%{latest_tag}`: replaced by the project’s last tag. Because these endpoints aren’t inside a project’s context, the information used to replace the placeholders comes from the first group’s project by creation date. If the group has no project, the original URL with the placeholders is returned. List all group badges --------------------- Lists badges for a specified group. GET /groups/:id/badges | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `name` | string | no | Name of the badges to return (case-sensitive). | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/badges?name=Coverage" Example response: [\ {\ "name": "Coverage",\ "id": 1,\ "link_url": "http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}",\ "image_url": "https://shields.io/my/badge",\ "rendered_link_url": "http://example.com/ci_status.svg?project=example-org/example-project&ref=main",\ "rendered_image_url": "https://shields.io/my/badge",\ "kind": "group"\ }\ ] Retrieve a group badge ---------------------- Retrieves a specified badge for a group. GET /groups/:id/badges/:badge_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `badge_id` | integer | yes | The badge ID | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id" Example response: { "name": "Coverage", "id": 1, "link_url": "http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}", "image_url": "https://shields.io/my/badge", "rendered_link_url": "http://example.com/ci_status.svg?project=example-org/example-project&ref=main", "rendered_image_url": "https://shields.io/my/badge", "kind": "group" } Create a group badge -------------------- Creates a badge for a specified group. POST /groups/:id/badges | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `link_url` | string | yes | URL of the badge link | | `image_url` | string | yes | URL of the badge image | | `name` | string | no | Name of the badge | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/badges" \ --data "link_url=https://gitlab.com/gitlab-org/gitlab-foss/commits/master&image_url=https://shields.io/my/badge1&name=mybadge&position=0" Example response: { "id": 1, "name": "mybadge", "link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/master", "image_url": "https://shields.io/my/badge1", "rendered_link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/master", "rendered_image_url": "https://shields.io/my/badge1", "kind": "group" } Update a group badge -------------------- Updates a specified badge for a group. PUT /groups/:id/badges/:badge_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `badge_id` | integer | yes | The badge ID | | `link_url` | string | no | URL of the badge link | | `image_url` | string | no | URL of the badge image | | `name` | string | no | Name of the badge | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id" Example response: { "id": 1, "name": "mybadge", "link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/master", "image_url": "https://shields.io/my/badge", "rendered_link_url": "https://gitlab.com/gitlab-org/gitlab-foss/commits/master", "rendered_image_url": "https://shields.io/my/badge", "kind": "group" } Delete a group badge -------------------- Deletes a specified badge from a group. DELETE /groups/:id/badges/:badge_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `badge_id` | integer | yes | The badge ID | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id" Retrieve a group badge preview ------------------------------ Retrieves a preview of the final `link_url` and `image_url` URLs for a specified group after resolving the placeholder interpolation. GET /groups/:id/badges/render | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `link_url` | string | yes | URL of the badge link | | `image_url` | string | yes | URL of the badge image | curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/:id/badges/render?link_url=http%3A%2F%2Fexample.com%2Fci_status.svg%3Fproject%3D%25%7Bproject_path%7D%26ref%3D%25%7Bdefault_branch%7D&image_url=https%3A%2F%2Fshields.io%2Fmy%2Fbadge" Example response: { "link_url": "http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}", "image_url": "https://shields.io/my/badge", "rendered_link_url": "http://example.com/ci_status.svg?project=example-org/example-project&ref=main", "rendered_image_url": "https://shields.io/my/badge" } --- # Group epic boards API | GitLab Docs * * * Group epic boards API ===================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/385903) in GitLab 15.9. Use this API to manage [group epic boards](https://docs.gitlab.com/user/group/epics/epic_boards/) . Every request to this API must be authenticated. If a user is not a member of a group and the group is private, a `GET` request results in `404` status code. List all epic boards in a group ------------------------------- Lists all epic boards for a specified group. GET /groups/:id/epic_boards | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group accessible by the authenticated user | curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/5/epic_boards" Example response: [\ {\ "id": 1,\ "name": "group epic board",\ "hide_backlog_list": false,\ "hide_closed_list": false,\ "group": {\ "id": 5,\ "name": "Documentcloud",\ "web_url": "http://example.com/groups/documentcloud"\ },\ "hide_backlog_list": false,\ "hide_closed_list": false,\ "labels": [\ {\ "id": 1,\ "title": "Board Label",\ "color": "#c21e56",\ "description": "label applied to the epic board",\ "group_id": 5,\ "project_id": null,\ "template": false,\ "text_color": "#FFFFFF",\ "created_at": "2023-01-27T10:40:59.738Z",\ "updated_at": "2023-01-27T10:40:59.738Z"\ }\ ],\ "lists": [\ {\ "id": 1,\ "label": {\ "id": 69,\ "name": "Testing",\ "color": "#F0AD4E",\ "description": null\ },\ "position": 1,\ "list_type": "label"\ },\ {\ "id": 2,\ "label": {\ "id": 70,\ "name": "Ready",\ "color": "#FF0000",\ "description": null\ },\ "position": 2,\ "list_type": "label"\ },\ {\ "id": 3,\ "label": {\ "id": 71,\ "name": "Production",\ "color": "#FF5F00",\ "description": null\ },\ "position": 3,\ "list_type": "label"\ }\ ]\ }\ ] Retrieve a group epic board --------------------------- Retrieves a specified group epic board. GET /groups/:id/epic_boards/:board_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group accessible by the authenticated user | | `board_id` | integer | yes | The ID of an epic board | curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/5/epic_boards/1" Example response: { "id": 1, "name": "group epic board", "hide_backlog_list": false, "hide_closed_list": false, "group": { "id": 5, "name": "Documentcloud", "web_url": "http://example.com/groups/documentcloud" }, "labels": [\ {\ "id": 1,\ "title": "Board Label",\ "color": "#c21e56",\ "description": "label applied to the epic board",\ "group_id": 5,\ "project_id": null,\ "template": false,\ "text_color": "#FFFFFF",\ "created_at": "2023-01-27T10:40:59.738Z",\ "updated_at": "2023-01-27T10:40:59.738Z"\ }\ ], "lists" : [\ {\ "id" : 1,\ "label" : {\ "id": 69,\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1,\ "list_type": "label"\ },\ {\ "id" : 2,\ "label" : {\ "id": 70,\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2,\ "list_type": "label"\ },\ {\ "id" : 3,\ "label" : {\ "id": 71,\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3,\ "list_type": "label"\ }\ ] } List group epic board lists --------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/385904) in GitLab 15.9. Lists all group epic board lists for a specified board. Does not include `open` and `closed` lists. GET /groups/:id/epic_boards/:board_id/lists | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group accessible by the authenticated user | | `board_id` | integer | yes | The ID of an epic board | curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/5/epic_boards/1/lists" Example response: [\ {\ "id" : 1,\ "label" : {\ "name" : "Testing",\ "color" : "#F0AD4E",\ "description" : null\ },\ "position" : 1,\ "list_type" : "label",\ "collapsed" : false\ },\ {\ "id" : 2,\ "label" : {\ "name" : "Ready",\ "color" : "#FF0000",\ "description" : null\ },\ "position" : 2,\ "list_type" : "label",\ "collapsed" : false\ },\ {\ "id" : 3,\ "label" : {\ "name" : "Production",\ "color" : "#FF5F00",\ "description" : null\ },\ "position" : 3,\ "list_type" : "label",\ "collapsed" : false\ }\ ] Retrieve a group epic board list -------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/385904) in GitLab 15.9. Retrieves a specified group epic board list. GET /groups/:id/epic_boards/:board_id/lists/:list_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group accessible by the authenticated user | | `board_id` | integer | yes | The ID of an epic board | | `list_id` | integer | yes | The ID of an epic board’s list | curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/5/epic_boards/1/lists/1" Example response: { "id" : 1, "label" : { "name" : "Testing", "color" : "#F0AD4E", "description" : null }, "position" : 1, "list_type" : "label", "collapsed" : false } --- # Project wikis API | GitLab Docs * * * Project wikis API ================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [project wikis](https://docs.gitlab.com/user/project/wiki/) . An API for [group wikis](https://docs.gitlab.com/api/group_wikis/) is also available. Comments on a wiki page are called `notes`. To interact with them, use the [notes API](https://docs.gitlab.com/api/notes/#project-wikis) . List all wiki pages ------------------- Lists all wiki pages for a specified project. GET /projects/:id/wikis | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `with_content` | boolean | No | Include pages’ content. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/wikis?with_content=1" Example response: [\ {\ "content" : "Here is an instruction how to deploy this project.",\ "format" : "markdown",\ "slug" : "deploy",\ "title" : "deploy",\ "encoding": "UTF-8"\ },\ {\ "content" : "Our development process is described here.",\ "format" : "markdown",\ "slug" : "development",\ "title" : "development",\ "encoding": "UTF-8"\ },{\ "content" : "* [Deploy](deploy)\n* [Development](development)",\ "format" : "markdown",\ "slug" : "home",\ "title" : "home",\ "encoding": "UTF-8"\ }\ ] Retrieve a wiki page -------------------- Retrieves a specified wiki page for a project. GET /projects/:id/wikis/:slug | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `slug` | string | Yes | URL encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name`. | | `render_html` | boolean | No | Return the rendered HTML of the wiki page. | | `version` | string | No | Wiki page version SHA. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/wikis/home" Example response: { "content" : "home page", "format" : "markdown", "slug" : "home", "title" : "home", "encoding": "UTF-8" } Create a wiki page ------------------ Creates a wiki page for a specified project with the given title, slug, and content. POST /projects/:id/wikis | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `content` | string | Yes | The content of the wiki page. | | `title` | string | Yes | The title of the wiki page. | | `format` | string | No | The format of the wiki page. Available formats are: `markdown` (default), `rdoc`, `asciidoc`, and `org`. | curl --data "format=rdoc&title=Hello&content=Hello world" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/wikis" Example response: { "content" : "Hello world", "format" : "markdown", "slug" : "Hello", "title" : "Hello", "encoding": "UTF-8" } For Markdown content with special characters and diagrams, use `--data-urlencode` with a file reference to handle encoding automatically. For example, create a file named `content.md` with your wiki content, then run: curl --request POST \ --header "PRIVATE-TOKEN: " \ --data-urlencode "title=Page with Complex Content" \ --data-urlencode "content@content.md" \ --url "https://gitlab.example.com/api/v4/projects/1/wikis" The `--data-urlencode "content@content.md"` option URL-encodes the contents of the Markdown file and assigns it to the `content` attribute. This encoding handles special characters, line breaks, and complex Markdown syntax that might otherwise cause errors. Example response: { "content": "", "format": "markdown", "slug": "Page-with-Complex-Content", "title": "Page with Complex Content", "encoding": "UTF-8" } Update a wiki page ------------------ Updates a specified wiki page. At least one parameter is required to update the wiki page. PUT /projects/:id/wikis/:slug | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `content` | string | Yes, if `title` is not provided | The content of the wiki page. | | `title` | string | Yes, if `content` is not provided | The title of the wiki page. | | `format` | string | No | The format of the wiki page. Available formats are: `markdown` (default), `rdoc`, `asciidoc`, and `org`. | | `slug` | string | Yes | URL-encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name`. | curl --request PUT \ --data "format=rdoc&content=documentation&title=Docs" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/wikis/foo" Example response: { "content" : "documentation", "format" : "markdown", "slug" : "Docs", "title" : "Docs", "encoding": "UTF-8" } Delete a wiki page ------------------ Deletes a specified wiki page. DELETE /projects/:id/wikis/:slug | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `slug` | string | Yes | URL-encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name`. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/wikis/foo" If successful, a `204 No Content` HTTP response with an empty body is expected. Upload an attachment to the wiki repository ------------------------------------------- Uploads a file to the attachment folder inside the wiki’s repository. The attachment folder is the `uploads` folder. POST /projects/:id/wikis/attachments | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `file` | string | Yes | The attachment to be uploaded. | | `branch` | string | No | The name of the branch. Defaults to the wiki repository default branch. | To upload a file from your file system, use the `--form` argument. This causes cURL to post data using the header `Content-Type: multipart/form-data`. The `file=` parameter must point to a file on your file system and be preceded by `@`. For example: curl --request POST \ --header "PRIVATE-TOKEN: " \ --form "file=@dk.png" \ --url "https://gitlab.example.com/api/v4/projects/1/wikis/attachments" Example response: { "file_name" : "dk.png", "file_path" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png", "branch" : "main", "link" : { "url" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png", "markdown" : "![A description of the attachment](uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png)" } } --- # Query users by using GraphQL | GitLab Docs * * * Query users by using GraphQL ============================ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated You can query a subset of users in a GitLab instance by using: * GraphiQL. * [`cURL`](https://docs.gitlab.com/api/graphql/getting_started/#command-line) . Use GraphiQL ------------ 1. Open GraphiQL: * For GitLab.com, use: `https://gitlab.com/-/graphql-explorer` * For GitLab Self-Managed, use: `https://gitlab.example.com/-/graphql-explorer` 2. Copy the following text and paste it in the left window. This query looks for a subset of users in a GitLab instance by username. Alternately, you can use their [Global IDs](https://docs.gitlab.com/api/graphql/#global-ids) . { users(usernames: ["user1", "user3", "user4"]) { pageInfo { endCursor startCursor hasNextPage } nodes { id username, publicEmail location webUrl userPermissions { createSnippet } } } } 3. Select **Play**. [The GraphQL API returns a GlobalID, rather than a standard ID](https://docs.gitlab.com/api/graphql/getting_started/#queries-and-mutations) . It also expects a GlobalID as an input rather than a single integer. This query returns the specified information for the three users with the listed username. * Because GraphiQL uses the session token to authorize access to resources, the output is limited to the projects and groups accessible to the currently authenticated user. * If you are signed in as an instance administrator, you have access to all resources. ### Show administrators only If you are signed in as an administrator, you can show the matching administrators on the instance by adding the `admins: true` parameter to the query. Change the second line to: users(usernames: ["user1", "user3", "user4"], admins: true) { ... } Or you can get all of the administrators: users(admins: true) { ... } Pagination and graph nodes -------------------------- The query includes: * [`pageInfo`](https://docs.gitlab.com/api/graphql/users_example/#pageinfo) * [`nodes`](https://docs.gitlab.com/api/graphql/users_example/#nodes) ### `pageInfo` This contains the data needed to implement pagination. GitLab uses cursor-based [pagination](https://docs.gitlab.com/api/graphql/getting_started/#pagination) . For more information, see [Pagination](https://graphql.org/learn/pagination/) in the GraphQL documentation. ### `nodes` In a GraphQL query, `nodes` represents a collection of [`nodes` on a graph](https://en.wikipedia.org/wiki/Vertex_%28graph_theory%29) . In this case, the collection of nodes is a collection of `User` objects. For each one, the output includes: * The user’s `id`. * The `membership` fragment, which represents project or group membership that belongs to that user. Fragments are indicated by the `...memberships` notation. Related topics -------------- * [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) * [GraphQL-specific entities, like fragments and interfaces](https://graphql.org/learn/) --- # Group access tokens API | GitLab Docs * * * Group access tokens API ======================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with group access tokens. For more information, see [Group access tokens](https://docs.gitlab.com/user/group/settings/group_access_tokens/) . List all group access tokens ---------------------------- History * `state` attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/462217) in GitLab 17.2. Lists all group access tokens for the specified group. GET /groups/:id/access_tokens GET /groups/:id/access_tokens?state=inactive | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a group. | | `created_after` | datetime (ISO 8601) | No | If defined, returns tokens created after the specified time. | | `created_before` | datetime (ISO 8601) | No | If defined, returns tokens created before the specified time. | | `expires_after` | date (ISO 8601) | No | If defined, returns tokens that expire after the specified time. | | `expires_before` | date (ISO 8601) | No | If defined, returns tokens that expire before the specified time. | | `last_used_after` | datetime (ISO 8601) | No | If defined, returns tokens last used after the specified time. | | `last_used_before` | datetime (ISO 8601) | No | If defined, returns tokens last used before the specified time. | | `revoked` | boolean | No | If `true`, only returns revoked tokens. | | `search` | string | No | If defined, returns tokens that include the specified value in the name. | | `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `expires_asc`, `expires_desc`, `last_used_asc`, `last_used_desc`, `name_asc`, `name_desc`. | | `state` | string | No | If defined, returns tokens with the specified state. Possible values: `active` and `inactive`. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups//access_tokens" [\ {\ "user_id" : 141,\ "scopes" : [\ "api"\ ],\ "name" : "token",\ "expires_at" : "2021-01-31",\ "id" : 42,\ "active" : true,\ "created_at" : "2021-01-20T22:11:48.151Z",\ "description": "Test Token description",\ "revoked" : false,\ "last_used_at": null,\ "access_level": 40\ },\ {\ "user_id" : 141,\ "scopes" : [\ "read_api"\ ],\ "name" : "token-2",\ "expires_at" : "2021-01-31",\ "id" : 43,\ "active" : false,\ "created_at" : "2021-01-21T12:12:38.123Z",\ "description": "Test Token description",\ "revoked" : true,\ "last_used_at": "2021-02-13T10:34:57.178Z",\ "access_level": 40\ }\ ] Retrieve details on a group access token ---------------------------------------- Retrieves details on a specified group access token. GET /groups/:id/access_tokens/:token_id | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a group. | | `token_id` | integer or string | yes | ID | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups//access_tokens/" { "user_id" : 141, "scopes" : [\ "api"\ ], "name" : "token", "expires_at" : "2021-01-31", "id" : 42, "active" : true, "created_at" : "2021-01-20T22:11:48.151Z", "description": "Test Token description", "revoked" : false, "access_level": 40 } Create a group access token --------------------------- History * The `expires_at` attribute default was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120213) in GitLab 16.0. Creates a group access token for a specified group. Prerequisites: * You must have the Owner role for the group. POST /groups/:id/access_tokens | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a group. | | `name` | String | yes | Name of the token. | | `description` | string | no | Description of the group access token. Maximum: 255 characters. | | `scopes` | `Array[String]` | yes | List of [scopes](https://docs.gitlab.com/user/group/settings/group_access_tokens/#group-access-token-scopes)
available to the token. | | `access_level` | Integer | no | Role for the token. Possible values: `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), and `50` (Owner). Default value: `40`. | | `expires_at` | date | no | Expiration date of the access token in ISO format (`YYYY-MM-DD`). If undefined, the date is set to the [maximum allowable lifetime limit](https://docs.gitlab.com/user/profile/personal_access_tokens/#access-token-expiration)
. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type:application/json" \ --data '{ "name":"test_token", "scopes":["api", "read_repository"], "expires_at":"2021-01-31", "access_level": 30 }' \ --url "https://gitlab.example.com/api/v4/groups//access_tokens" { "scopes" : [\ "api",\ "read_repository"\ ], "active" : true, "name" : "test", "revoked" : false, "created_at" : "2021-01-21T19:35:37.921Z", "description": "Test Token description", "user_id" : 166, "id" : 58, "expires_at" : "2021-01-31", "token" : "D4y...Wzr", "access_level": 30 } Rotate a group access token --------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/403042) in GitLab 16.0 * `expires_at` attribute [added](https://gitlab.com/gitlab-org/gitlab/-/issues/416795) in GitLab 16.6. Rotates a specified group access token. This immediately revokes the previous token and creates a new token. Generally, this endpoint rotates a specific group access token by authenticating with a personal access token. You can also use a group access token to rotate itself. For more information, see [Self-rotate](https://docs.gitlab.com/api/group_access_tokens/#self-rotate) . If you attempt to use this endpoint to rotate a token that was previously revoked, any active tokens from the same token family are revoked. For more information, see [automatic reuse detection](https://docs.gitlab.com/api/personal_access_tokens/#automatic-reuse-detection) . Prerequisites: * To rotate another group access token, you must have a personal access token with the [`api` scope](https://docs.gitlab.com/user/profile/personal_access_tokens/#personal-access-token-scopes) . * To [self-rotate](https://docs.gitlab.com/api/group_access_tokens/#self-rotate) a group access token, the token must have the [`api` or `self_rotate` scope](https://docs.gitlab.com/user/profile/personal_access_tokens/#personal-access-token-scopes) . POST /groups/:id/access_tokens/:token_id/rotate | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a group. | | `token_id` | integer or string | yes | ID of a group access token or the keyword `self`. | | `expires_at` | date | no | Expiration date of the access token in ISO format (`YYYY-MM-DD`). If the token requires an expiration date, defaults to 1 week. If not required, defaults to the [maximum allowable lifetime limit](https://docs.gitlab.com/user/profile/personal_access_tokens/#access-token-expiration)
. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups//access_tokens//rotate" Example response: { "id": 42, "name": "Rotated Token", "revoked": false, "created_at": "2023-08-01T15:00:00.000Z", "description": "Test group access token", "scopes": ["api"], "user_id": 1337, "last_used_at": null, "active": true, "expires_at": "2023-08-15", "access_level": 30, "token": "s3cr3t" } If successful, returns `200: OK`. Other possible responses: * `400: Bad Request` if not rotated successfully. * `401: Unauthorized` if any of the following conditions are true: * The token does not exist. * The token has expired. * The token was revoked. * You do not have access to the specified token. * You’re using a group access token to rotate another group access token. See [Self-rotate](https://docs.gitlab.com/api/group_access_tokens/#self-rotate) instead. * `403: Forbidden` if the token is not allowed to rotate itself. * `404: Not Found` if the user is an administrator but the token does not exist. * `405: Method Not Allowed` if the token is not an access token. ### Self-rotate Instead of rotating a specific group access token, you can rotate the same group access token you used to authenticate the request. To self-rotate a group access token, you must: * Rotate a group access token with the [`api` or `self_rotate` scope](https://docs.gitlab.com/user/profile/personal_access_tokens/#personal-access-token-scopes) . * Use the `self` keyword in the request URL. Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups//access_tokens/self/rotate" Revoke a group access token --------------------------- Revokes a specified group access token. DELETE /groups/:id/access_tokens/:token_id | Attribute | Type | required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a group. | | `token_id` | integer | yes | ID of a group access token. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups//access_tokens/" If successful, returns `204 No content`. Other possible responses: * `400: Bad Request` if not revoked successfully. * `404: Not Found` if the access token does not exist. --- # OAuth 2.0 identity provider API | GitLab Docs * * * OAuth 2.0 identity provider API =============================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to allow third-party services to access GitLab resources for a user with the [OAuth 2.0](https://oauth.net/2/) protocol. For more information, see [Configure GitLab as an OAuth 2.0 authentication identity provider](https://docs.gitlab.com/integration/oauth_provider/) . This functionality is based on the [doorkeeper Ruby gem](https://github.com/doorkeeper-gem/doorkeeper) . Cross-origin resource sharing ----------------------------- History * CORS preflight request support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/364680) in GitLab 15.1. Many `/oauth` endpoints support cross-origin resource sharing (CORS). From GitLab 15.1, the following endpoints also support [CORS preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) : * `/oauth/revoke` * `/oauth/token` * `/oauth/userinfo` Only certain headers can be used for preflight requests: * The headers listed for [simple requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) . * The `Authorization` header. For example, the `X-Requested-With` header can’t be used for preflight requests. Supported OAuth 2.0 flows ------------------------- GitLab supports the following authorization flows: * **Authorization code with [Proof Key for Code Exchange (PKCE)](https://www.rfc-editor.org/rfc/rfc7636) **: Most secure. Without PKCE, you’d have to include client secrets on mobile clients, and is recommended for both client and server apps. * **Authorization code**: Secure and common flow. Recommended option for secure server-side apps. * **Resource owner password credentials**: To be used **only** for securely hosted, first-party services. GitLab recommends against use of this flow. * **Device Authorization Grant** (GitLab 17.1 and later) Secure flow oriented toward devices without browser access. Requires a secondary device to complete the authorization flow. The draft specification for [OAuth 2.1](https://oauth.net/2.1/) specifically omits both the Implicit grant and Resource Owner Password Credentials flows. Refer to the [OAuth RFC](https://www.rfc-editor.org/rfc/rfc6749) to find out how all those flows work and pick the right one for your use case. Authorization code (with or without PKCE) flow requires `application` to be registered first via the `/user_settings/applications` page in your user’s account. During registration, by enabling proper scopes, you can limit the range of resources which the `application` can access. Upon creation, you obtain the `application` credentials: _Application ID_ and _Client Secret_. The _Client Secret_ **must be kept secure**. It is also advantageous to keep the _Application ID_ secret when your application architecture allows. For a list of scopes in GitLab, see [the provider documentation](https://docs.gitlab.com/integration/oauth_provider/#view-all-authorized-applications) . ### Prevent CSRF attacks To [protect redirect-based flows](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-13#section-3.1) , the OAuth specification recommends the use of “One-time use CSRF tokens carried in the state parameter, which are securely bound to the user agent”, with each request to the `/oauth/authorize` endpoint. This can prevent [CSRF attacks](https://wiki.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29) . ### Use HTTPS in production For production, use HTTPS for your `redirect_uri`. For development, GitLab allows insecure HTTP redirect URIs. As OAuth 2.0 bases its security entirely on the transport layer, you should not use unprotected URIs. For more information, see the [OAuth 2.0 RFC](https://www.rfc-editor.org/rfc/rfc6749#section-3.1.2.1) and the [OAuth 2.0 Threat Model RFC](https://www.rfc-editor.org/rfc/rfc6819#section-4.4.2.1) . In the following sections you can find detailed instructions on how to obtain authorization with each flow. ### Authorization code with Proof Key for Code Exchange (PKCE) History * Group SAML SSO support for OAuth applications [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/461212) in GitLab 18.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `ff_oauth_redirect_to_sso_login`. Disabled by default. * Group SAML SSO support for OAuth applications [enabled on GitLab.com, GitLab Self-Managed and GitLab Dedicated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/200682) in GitLab 18.3. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/561778) in GitLab 18.5. Feature flag `ff_oauth_redirect_to_sso_login` removed. The [PKCE RFC](https://www.rfc-editor.org/rfc/rfc7636#section-1.1) includes a detailed flow description, from authorization request through access token. The following steps describe our implementation of the flow. The Authorization code with PKCE flow, PKCE for short, makes it possible to securely perform the OAuth exchange of client credentials for access tokens on public clients without requiring access to the _Client Secret_ at all. This makes the PKCE flow advantageous for single page JavaScript applications or other client side apps where keeping secrets from the user is a technical impossibility. Before starting the flow, generate the `STATE`, the `CODE_VERIFIER` and the `CODE_CHALLENGE`. * The `STATE` a value that can’t be predicted used by the client to maintain state between the request and callback. It should also be used as a CSRF token. * The `CODE_VERIFIER` is a random string, between 43 and 128 characters in length, which use the characters `A-Z`, `a-z`, `0-9`, `-`, `.`, `_`, and `~`. * The `CODE_CHALLENGE` is a URL-safe base64-encoded string of the SHA256 hash of the `CODE_VERIFIER`: * The SHA256 hash must be in binary format before encoding. * In Ruby, you can set that up with `Base64.urlsafe_encode64(Digest::SHA256.digest(CODE_VERIFIER), padding: false)`. * For reference, a `CODE_VERIFIER` string of `ks02i3jdikdo2k0dkfodf3m39rjfjsdk0wk349rj3jrhf` when hashed and encoded using the previous Ruby snippet produces a `CODE_CHALLENGE` string of `2i0WFA-0AerkjQm4X4oDEhqA17QIAKNjXpagHBXmO_U`. 1. Request authorization code. To do that, you should redirect the user to the `/oauth/authorize` page with the following query parameters: https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=STATE&scope=REQUESTED_SCOPES&code_challenge=CODE_CHALLENGE&code_challenge_method=S256&root_namespace_id=ROOT_NAMESPACE_ID This page asks the user to approve the request from the app to access their account based on the scopes specified in `REQUESTED_SCOPES`. The user is then redirected back to the specified `REDIRECT_URI`. The [scope parameter](https://docs.gitlab.com/integration/oauth_provider/#view-all-authorized-applications) is a space-separated list of scopes associated with the user. For example,`scope=read_user+profile` requests the `read_user` and `profile` scopes. The `root_namespace_id` is the root namespace ID associated with the project. This optional parameter should be used when [SAML SSO](https://docs.gitlab.com/user/group/saml_sso/) is configured for the associated group. The redirect includes the authorization `code`, for example: https://example.com/oauth/redirect?code=1234567890&state=STATE 2. With the authorization `code` returned from the previous request (denoted as `RETURNED_CODE` in the following example), you can request an `access_token`, with any HTTP client. The following example uses Ruby’s `rest-client`: parameters = 'client_id=APP_ID&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI&code_verifier=CODE_VERIFIER' RestClient.post 'https://gitlab.example.com/oauth/token', parameters Example response: { "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", "token_type": "bearer", "expires_in": 7200, "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1", "created_at": 1607635748 } 3. To retrieve a new `access_token`, use the `refresh_token` parameter. Refresh tokens may be used even after the `access_token` itself expires. This request: * Invalidates the existing `access_token` and `refresh_token`. * Sends new tokens in the response. parameters = 'client_id=APP_ID&refresh_token=REFRESH_TOKEN&grant_type=refresh_token&redirect_uri=REDIRECT_URI' RestClient.post 'https://gitlab.example.com/oauth/token', parameters Example response: { "access_token": "c97d1fe52119f38c7f67f0a14db68d60caa35ddc86fd12401718b649dcfa9c68", "token_type": "bearer", "expires_in": 7200, "refresh_token": "803c1fd487fec35562c205dac93e9d8e08f9d3652a24079d704df3039df1158f", "created_at": 1628711391 } The `redirect_uri` must match the `redirect_uri` used in the original authorization request. You can now make requests to the API with the access token. ### Authorization code flow History * Group SAML SSO support for OAuth applications [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/461212) in GitLab 18.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `ff_oauth_redirect_to_sso_login`. Disabled by default. * Group SAML SSO support for OAuth applications [enabled on GitLab.com, GitLab Self-Managed and GitLab Dedicated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/200682) in GitLab 18.3. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/561778) in GitLab 18.5. Feature flag `ff_oauth_redirect_to_sso_login` removed. Check the [RFC spec](https://www.rfc-editor.org/rfc/rfc6749#section-4.1) for a detailed flow description. The authorization code flow is essentially the same as [authorization code flow with PKCE](https://docs.gitlab.com/api/oauth2/#authorization-code-with-proof-key-for-code-exchange-pkce) , Before starting the flow, generate the `STATE`. It is a value that can’t be predicted used by the client to maintain state between the request and callback. It should also be used as a CSRF token. 1. Request authorization code. To do that, you should redirect the user to the `/oauth/authorize` page with the following query parameters: https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=STATE&scope=REQUESTED_SCOPES&root_namespace_id=ROOT_NAMESPACE_ID This page asks the user to approve the request from the app to access their account based on the scopes specified in `REQUESTED_SCOPES`. The user is then redirected back to the specified `REDIRECT_URI`. The [scope parameter](https://docs.gitlab.com/integration/oauth_provider/#view-all-authorized-applications) is a space-separated list of scopes associated with the user. For example,`scope=read_user+profile` requests the `read_user` and `profile` scopes. The `root_namespace_id` is the root namespace ID associated with the project. This optional parameter should be used when [SAML SSO](https://docs.gitlab.com/user/group/saml_sso/) is configured for the associated group. The redirect includes the authorization `code`, for example: https://example.com/oauth/redirect?code=1234567890&state=STATE 2. With the authorization `code` returned from the previous request (shown as `RETURNED_CODE` in the following example), you can request an `access_token`, with any HTTP client. The following example uses Ruby’s `rest-client`: parameters = 'client_id=APP_ID&client_secret=APP_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI' RestClient.post 'https://gitlab.example.com/oauth/token', parameters Example response: { "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", "token_type": "bearer", "expires_in": 7200, "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1", "created_at": 1607635748 } 3. To retrieve a new `access_token`, use the `refresh_token` parameter. Refresh tokens may be used even after the `access_token` itself expires. This request: * Invalidates the existing `access_token` and `refresh_token`. * Sends new tokens in the response. parameters = 'client_id=APP_ID&client_secret=APP_SECRET&refresh_token=REFRESH_TOKEN&grant_type=refresh_token&redirect_uri=REDIRECT_URI' RestClient.post 'https://gitlab.example.com/oauth/token', parameters Example response: { "access_token": "c97d1fe52119f38c7f67f0a14db68d60caa35ddc86fd12401718b649dcfa9c68", "token_type": "bearer", "expires_in": 7200, "refresh_token": "803c1fd487fec35562c205dac93e9d8e08f9d3652a24079d704df3039df1158f", "created_at": 1628711391 } The `redirect_uri` must match the `redirect_uri` used in the original authorization request. You can now make requests to the API with the access token returned. ### Device authorization grant flow History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332682) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `oauth2_device_grant_flow`. * [Enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/468479) by default in 17.3. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/505557) in GitLab 17.9. Feature flag `oauth2_device_grant_flow` removed. Check the [RFC spec](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1) for a detailed description of the device authorization grant flow, from device authorization request to token response from the browser login. The device authorization grant flow makes it possible to securely authenticate your GitLab identity from input constrained devices where browser interactions are not an option. This makes the device authorization grant flow ideal for users attempting to use GitLab services from headless servers or other devices with no, or limited, UI. 1. To request device authorization, a request is sent from the input-limited device client to `https://gitlab.example.com/oauth/authorize_device`. For example: parameters = 'client_id=UID&scope=read' RestClient.post 'https://gitlab.example.com/oauth/authorize_device', parameters After a successful request, a response containing a `verification_uri` is returned to the user. For example: { "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS", "user_code": "0A44L90H", "verification_uri": "https://gitlab.example.com/oauth/device", "verification_uri_complete": "https://gitlab.example.com/oauth/device?user_code=0A44L90H", "expires_in": 300, "interval": 5 } 2. The device client displays the `user_code` and `verification_uri` from the response to the requesting user. That user then, on a secondary device with browser access: 1. Goes to the provided URI. 2. Enters the user code. 3. Completes an authentication as prompted. 3. Immediately after displaying the `verification_uri` and `user_code`, the device client begins polling the token endpoint with the associated `device_code` returned in the initial response: parameters = 'grant_type=urn:ietf:params:oauth:grant-type:device_code &device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS &client_id=1406020730' RestClient.post 'https://gitlab.example.com/oauth/token', parameters 4. The device client receives a response from the token endpoint. If the authorization was successful, a success response is returned, otherwise, an error response is returned. Potential error responses are categorized by either of the following: * Those defined by the OAuth Authorization Framework access token error responses. * Those specific to the device authorization grant flow described here. Those error responses specific to the device flow are described in the following content. For more information on each potential response, see the relevant [RFC spec for device authorization grant](https://datatracker.ietf.org/doc/html/rfc8628#section-3.5) and the [RFC spec for authorization tokens](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2) . Example response: { "error": "authorization_pending", "error_description": "..." } On receipt of this response, the device client continues polling. If the polling interval is too short, a slow down error response is returned. For example: { "error": "slow_down", "error_description": "..." } On receipt of this response, the device client reduces its polling rate and continues polling at the new rate. If the device code expires before authentication is complete, an expired token error response is returned. For example: { "error": "expired_token", "error_description": "..." } At that point, the device-client should stop and initiate a new device authorization request. If the authorization request was denied, an access denied error response is returned. For example: { "error": "access_denied", "error_description": "..." } The authentication request has been rejected. The user should verify their credentials or contact their system administrator 5. After the user successfully authenticates, a success response is returned: { "access_token": "TOKEN", "token_type": "Bearer", "expires_in": 7200, "scope": "read", "created_at": 1593096829 } At this point, the device authentication flow is complete. The returned `access_token` can be provided to GitLab to authenticate the user identity when accessing GitLab resources, such as when cloning over HTTPS or accessing the API. A sample application that implements the client side device flow can be found at: [https://gitlab.com/johnwparent/git-auth-over-https](https://gitlab.com/johnwparent/git-auth-over-https) . ### Resource owner password credentials flow Check the [RFC spec](https://www.rfc-editor.org/rfc/rfc6749#section-4.3) for a detailed flow description. Resource owner password credentials are disabled for users with [two-factor authentication](https://docs.gitlab.com/user/profile/account/two_factor_authentication/) turned on and [enterprise users](https://docs.gitlab.com/user/enterprise_user/) with [password authentication disabled for their group](https://docs.gitlab.com/user/enterprise_user/#restrict-authentication-methods) . These users can access the API using [personal access tokens](https://docs.gitlab.com/user/profile/personal_access_tokens/) instead. Ensure the [**Allow password authentication for Git over HTTP(S)**](https://docs.gitlab.com/administration/settings/sign_in_restrictions/#allow-password-authentication-for-git-over-https) checkbox is selected for the GitLab instance to support the password credentials flow. In this flow, a token is requested in exchange for the resource owner credentials (username and password). The credentials should only be used when: * There is a high degree of trust between the resource owner and the client. For example, the client is part of the device operating system or a highly privileged application. * Other authorization grant types are not available (such as an authorization code). Never store the user’s credentials and only use this grant type when your client is deployed to a trusted environment, in 99% of cases [personal access tokens](https://docs.gitlab.com/user/profile/personal_access_tokens/) are a better choice. Even though this grant type requires direct client access to the resource owner credentials, the resource owner credentials are used for a single request and are exchanged for an access token. This grant type can eliminate the need for the client to store the resource owner credentials for future use, by exchanging the credentials with a long-lived access token or refresh token. To request an access token, you must make a POST request to `/oauth/token` with the following parameters: { "grant_type" : "password", "username" : "user@example.com", "password" : "secret" } Example cURL request: echo 'grant_type=password&username=&password=' > auth.txt curl --request POST \ --url "https://gitlab.example.com/oauth/token" \ --data "@auth.txt" You can also use this grant flow with registered OAuth applications, by using HTTP Basic Authentication with the application’s `client_id` and `client_secret`: echo 'grant_type=password&username=&password=' > auth.txt curl --request POST \ --url "https://gitlab.example.com/oauth/token" \ --data "@auth.txt" \ --user client_id:client_secret Then, you receive a response containing the access token: { "access_token": "1f0af717251950dbd4d73154fdf0a474a5c5119adad999683f5b450c460726aa", "token_type": "bearer", "expires_in": 7200 } By default, the scope of the access token is `api`, which provides complete read/write access. For testing, you can use the `oauth2` Ruby gem: client = OAuth2::Client.new('the_client_id', 'the_client_secret', :site => "https://example.com") access_token = client.password.get_token('user@example.com', 'secret') puts access_token.token Access GitLab API with `access token` ------------------------------------- The `access token` allows you to make requests to the API on behalf of a user. You can pass the token either as GET parameter: GET https://gitlab.example.com/api/v4/user?access_token=OAUTH-TOKEN or you can put the token to the Authorization header: curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/user" Access Git over HTTPS with `access token` ----------------------------------------- A token with [scope](https://docs.gitlab.com/integration/oauth_provider/#view-all-authorized-applications) `read_repository` or `write_repository` can access Git over HTTPS. Use the token as the password. You can set the username to any string value. You should use `oauth2`: https://oauth2:@gitlab.example.com/project_path/project_name.git Alternatively, you can use a [Git credential helper](https://docs.gitlab.com/user/profile/account/two_factor_authentication/#oauth-credential-helpers) to authenticate to GitLab with OAuth. This handles OAuth token refresh automatically. Retrieve the token information ------------------------------ To verify the details of a token, use the `token/info` endpoint provided by the Doorkeeper gem. For more information, see [`/oauth/token/info`](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples#get----oauthtokeninfo) . You must supply the access token, either: * As a parameter: GET https://gitlab.example.com/oauth/token/info?access_token= * In the Authorization header: curl --header "Authorization: Bearer " "https://gitlab.example.com/oauth/token/info" The following is an example response: { "resource_owner_id": 1, "scope": ["api"], "expires_in": null, "application": {"uid": "1cb242f495280beb4291e64bee2a17f330902e499882fe8e1e2aa875519cab33"}, "created_at": 1575890427 } ### Deprecated fields The fields `scopes` and `expires_in_seconds` are included in the response but are now deprecated. The `scopes` field is an alias for `scope`, and the `expires_in_seconds` field is an alias for `expires_in`. For more information, see [Doorkeeper API changes](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions#api-changes-5) . Revoke a token -------------- To revoke a token, use the `revoke` endpoint. The API returns a 200 response code and an empty JSON hash to indicate success. parameters = 'client_id=APP_ID&client_secret=APP_SECRET&token=TOKEN' RestClient.post 'https://gitlab.example.com/oauth/revoke', parameters OAuth 2.0 tokens and GitLab registries -------------------------------------- Standard OAuth 2.0 tokens support different degrees of access to GitLab registries, as they: * Do not allow users to authenticate to: * The GitLab [container registry](https://docs.gitlab.com/user/packages/container_registry/authenticate_with_container_registry/) . * Packages listed in the GitLab [Package registry](https://docs.gitlab.com/user/packages/package_registry/) . * [Virtual registries](https://docs.gitlab.com/user/packages/virtual_registry/) . * Allow users to get, list, and delete registries through the [container registry API](https://docs.gitlab.com/api/container_registry/) . * Allow users to get, list, and delete registry objects through the [Maven virtual registry API](https://docs.gitlab.com/api/maven_virtual_registries/) . --- # Protected environments API | GitLab Docs * * * Protected environments API ========================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with [protected environments](https://docs.gitlab.com/ci/environments/protected_environments/) . For group-level protected environments, see [group-level protected environments API](https://docs.gitlab.com/api/group_protected_environments/) Valid access levels ------------------- The access levels are defined in the `ProtectedEnvironments::DeployAccessLevel::ALLOWED_ACCESS_LEVELS` method. Currently, these levels are recognized: 30 => Developer access 40 => Maintainer access 60 => Admin access Group inheritance types ----------------------- Group inheritance allows deploy access levels and access rules to take inherited group membership into account. The group inheritance types are defined by `ProtectedEnvironments::Authorizable::GROUP_INHERITANCE_TYPE`. The following types are recognized: 0 => Direct group membership only (default) 1 => All inherited groups List protected environments --------------------------- Gets a list of protected environments from a project: GET /projects/:id/protected_environments | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_environments/" Example response: [\ {\ "name":"production",\ "deploy_access_levels":[\ {\ "id": 12,\ "access_level":40,\ "access_level_description":"Maintainers",\ "user_id":null,\ "group_id":null,\ "group_inheritance_type": 0\ }\ ],\ "required_approval_count": 0\ }\ ] Get a single protected environment ---------------------------------- Gets a single protected environment: GET /projects/:id/protected_environments/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `name` | string | yes | The name of the protected environment | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_environments/production" Example response: { "name":"production", "deploy_access_levels":[\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null,\ "group_inheritance_type": 0\ }\ ], "required_approval_count": 0 } Protect a single environment ---------------------------- Protects a single environment: POST /projects/:id/protected_environments | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | yes | The name of the environment. | | `deploy_access_levels` | array | yes | Array of access levels allowed to deploy, with each described by a hash. | | `approval_rules` | array | no | Array of access levels allowed to approve, with each described by a hash. See [Multiple approval rules](https://docs.gitlab.com/ci/environments/deployment_approvals/#add-multiple-approval-rules)
. | Elements in the `deploy_access_levels` and `approval_rules` array should be one of `user_id`, `group_id` or `access_level`, and take the form `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}`. Optionally, you can specify the `group_inheritance_type` on each as one of the [valid group inheritance types](https://docs.gitlab.com/api/protected_environments/#group-inheritance-types) . Each user must have access to the project and each group must [have this project shared](https://docs.gitlab.com/user/project/members/sharing_projects_groups/) . curl --header 'Content-Type: application/json' \ --request POST \ --data '{"name": "production", "deploy_access_levels": [{"group_id": 9899826}], "approval_rules": [{"group_id": 134}, {"group_id": 135, "required_approvals": 2}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_environments" Example response: { "name": "production", "deploy_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "protected-access-group",\ "user_id": null,\ "group_id": 9899826,\ "group_inheritance_type": 0\ }\ ], "required_approval_count": 0, "approval_rules": [\ {\ "id": 38,\ "user_id": null,\ "group_id": 134,\ "access_level": null,\ "access_level_description": "qa-group",\ "required_approvals": 1,\ "group_inheritance_type": 0\ },\ {\ "id": 39,\ "user_id": null,\ "group_id": 135,\ "access_level": null,\ "access_level_description": "security-group",\ "required_approvals": 2,\ "group_inheritance_type": 0\ }\ ] } Update a protected environment ------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/351854) in GitLab 15.4. Updates a single environment. PUT /projects/:id/protected_environments/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | yes | The name of the environment. | | `deploy_access_levels` | array | no | Array of access levels allowed to deploy, with each described by a hash. | | `approval_rules` | array | no | Array of access levels allowed to approve, with each described by a hash. See [Multiple approval rules](https://docs.gitlab.com/ci/environments/deployment_approvals/#add-multiple-approval-rules)
for more information. | Elements in the `deploy_access_levels` and `approval_rules` array should be one of `user_id`, `group_id` or `access_level`, and take the form `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}`. Optionally you can specify the `group_inheritance_type` on each as one of the [valid group inheritance types](https://docs.gitlab.com/api/protected_environments/#group-inheritance-types) . To update: * **`user_id`**: Ensure the updated user has access to the project. You must also pass the `id` of either a `deploy_access_level` or `approval_rule` in the respective hash. * **`group_id`**: Ensure the updated group [have this project shared](https://docs.gitlab.com/user/project/members/sharing_projects_groups/) . You must also pass the `id` of either a `deploy_access_level` or `approval_rule` in the respective hash. To delete: * You must pass `_destroy` set to `true`. See the following examples. ### Example: Create a `deploy_access_level` record curl --header 'Content-Type: application/json' \ --request PUT \ --data '{"deploy_access_levels": [{"group_id": 9899829, access_level: 40}]' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_environments/production" Example response: { "name": "production", "deploy_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "protected-access-group",\ "user_id": null,\ "group_id": 9899829,\ "group_inheritance_type": 1\ }\ ], "required_approval_count": 0 } ### Example: Update a `deploy_access_level` record curl --header 'Content-Type: application/json' \ --request PUT \ --data '{"deploy_access_levels": [{"id": 12, "group_id": 22034120}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_environments/production" { "name": "production", "deploy_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "protected-access-group",\ "user_id": null,\ "group_id": 22034120,\ "group_inheritance_type": 0\ }\ ], "required_approval_count": 2 } ### Example: Delete a `deploy_access_level` record curl --header 'Content-Type: application/json' \ --request PUT \ --data '{"deploy_access_levels": [{"id": 12, "_destroy": true}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_environments/production" Example response: { "name": "production", "deploy_access_levels": [], "required_approval_count": 0 } ### Example: Create an `approval_rule` record curl --header 'Content-Type: application/json' \ --request PUT \ --data '{"approval_rules": [{"group_id": 134, "required_approvals": 1}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_environments/production" Example response: { "name": "production", "approval_rules": [\ {\ "id": 38,\ "user_id": null,\ "group_id": 134,\ "access_level": null,\ "access_level_description": "qa-group",\ "required_approvals": 1,\ "group_inheritance_type": 0\ }\ ] } ### Example: Update an `approval_rule` record curl --header 'Content-Type: application/json' \ --request PUT \ --data '{"approval_rules": [{"id": 38, "group_id": 135, "required_approvals": 2}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_environments/production" { "name": "production", "approval_rules": [\ {\ "id": 38,\ "user_id": null,\ "group_id": 135,\ "access_level": null,\ "access_level_description": "security-group",\ "required_approvals": 2,\ "group_inheritance_type": 0\ }\ ] } ### Example: Delete an `approval_rule` record curl --header 'Content-Type: application/json' \ --request PUT \ --data '{"approval_rules": [{"id": 38, "_destroy": true}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_environments/production" Example response: { "name": "production", "approval_rules": [] } Unprotect a single environment ------------------------------ Unprotects the given protected environment: DELETE /projects/:id/protected_environments/:name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | yes | The name of the protected environment. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_environments/staging" --- # Release links API | GitLab Docs * * * Release links API ================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/250819) authentication with a [GitLab CI/CD job token](https://docs.gitlab.com/ci/jobs/ci_job_token/) in GitLab 15.1. Use this API to interact with links to [releases](https://docs.gitlab.com/user/project/releases/) . GitLab supports asset links with the following protocols: * `http` * `https` * `ftp` To interact with project releases directly, see the [project release API](https://docs.gitlab.com/api/releases/) . List all release links ---------------------- Lists all assets as links from a release. GET /projects/:id/releases/:tag_name/assets/links | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The tag associated with the Release. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links" Example response: [\ {\ "id":2,\ "name":"awesome-v0.2.msi",\ "url":"http://192.168.10.15:3000/msi",\ "link_type":"other"\ },\ {\ "id":1,\ "name":"awesome-v0.2.dmg",\ "url":"http://192.168.10.15:3000",\ "link_type":"other"\ }\ ] Retrieve a release link ----------------------- Retrieves a specified asset as a link from a release. GET /projects/:id/releases/:tag_name/assets/links/:link_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The tag associated with the Release. | | `link_id` | integer | yes | The ID of the link. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links/1" Example response: { "id":1, "name":"awesome-v0.2.dmg", "url":"http://192.168.10.15:3000", "link_type":"other" } Create a release link --------------------- Creates an asset link for a specified release. POST /projects/:id/releases/:tag_name/assets/links | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The tag associated with the Release. | | `name` | string | yes | The name of the link. Link names must be unique in the release. | | `url` | string | yes | The URL of the link. Link URLs must be unique in the release. | | `direct_asset_path` | string | no | Optional path for a [direct asset link](https://docs.gitlab.com/user/project/releases/release_fields/#permanent-links-to-release-assets)
. | | `link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --data name="hellodarwin-amd64" \ --data url="https://gitlab.example.com/mynamespace/hello/-/jobs/688/artifacts/raw/bin/hello-darwin-amd64" \ --data direct_asset_path="/bin/hellodarwin-amd64" \ "https://gitlab.example.com/api/v4/projects/20/releases/v1.7.0/assets/links" Example response: { "id":2, "name":"hellodarwin-amd64", "url":"https://gitlab.example.com/mynamespace/hello/-/jobs/688/artifacts/raw/bin/hello-darwin-amd64", "direct_asset_url":"https://gitlab.example.com/mynamespace/hello/-/releases/v1.7.0/downloads/bin/hellodarwin-amd64", "link_type":"other" } Update a release link --------------------- Updates a specified asset link for a release. PUT /projects/:id/releases/:tag_name/assets/links/:link_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The tag associated with the Release. | | `link_id` | integer | yes | The ID of the link. | | `name` | string | no | The name of the link. | | `url` | string | no | The URL of the link. | | `direct_asset_path` | string | no | Optional path for a [direct asset link](https://docs.gitlab.com/user/project/releases/release_fields/#permanent-links-to-release-assets)
. | | `link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`. | You have to specify at least one of `name` or `url` Example request: curl --request PUT --data name="new name" --data link_type="runbook" \ --header "PRIVATE-TOKEN: " \ "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links/1" Example response: { "id":1, "name":"new name", "url":"http://192.168.10.15:3000", "link_type":"runbook" } Delete a release link --------------------- Deletes a specified asset link from a release. DELETE /projects/:id/releases/:tag_name/assets/links/:link_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The tag associated with the Release. | | `link_id` | integer | yes | The ID of the link. | Example request: curl --request DELETE --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links/1" Example response: { "id":1, "name":"new name", "url":"http://192.168.10.15:3000", "link_type":"other" } --- # Use custom emoji with GraphQL | GitLab Docs * * * Use custom emoji with GraphQL ============================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37911) in GitLab 13.6 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `custom_emoji`. Disabled by default. * Enabled on GitLab.com in GitLab 14.0. * [Enabled on GitLab Self-Managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/138969) in GitLab 16.7. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/) in GitLab 16.9. Feature flag `custom_emoji` removed. To use [custom emoji](https://docs.gitlab.com/user/emoji_reactions/) in comments and descriptions, you can add them to a top-level group by using the GraphQL API. Create a custom emoji --------------------- mutation CreateCustomEmoji($groupPath: ID!) { createCustomEmoji(input: {groupPath: $groupPath, name: "party-parrot", url: "https://cultofthepartyparrot.com/parrots/hd/parrot.gif"}) { clientMutationId customEmoji { name } errors } } After you add a custom emoji to the group, members can use it in the same way as other emoji in the comments. ### Attributes The query accepts these attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `group_path` | integer or string | Yes | ID or [URL-encoded path of the top-level group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the custom emoji. | | `file` | string | Yes | URL of the custom emoji image. | Use GraphiQL ------------ You can use GraphiQL to query the emoji for a group. 1. Open GraphiQL: * For GitLab.com, use: `https://gitlab.com/-/graphql-explorer` * For GitLab Self-Managed, use: `https://gitlab.example.com/-/graphql-explorer` 2. Copy the following text and paste it in the left window. In this query, `gitlab-org` is the group path. query GetCustomEmoji { group(fullPath: "gitlab-org") { id customEmoji { nodes { name, url } } } } 3. Select **Play**. Related topics -------------- * [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) * [GraphQL-specific entities, like fragments and interfaces](https://graphql.org/learn/) --- # REST API authentication | GitLab Docs * * * REST API authentication ======================= Most API requests require authentication, or return only public data when authentication isn’t provided. When authentication is not required, the documentation for each endpoint specifies this. For example, the [`/projects/:id` endpoint](https://docs.gitlab.com/api/projects/#retrieve-a-project) does not require authentication. You can authenticate with the GitLab REST API in several ways: * [OAuth 2.0 tokens](https://docs.gitlab.com/api/rest/authentication/#oauth-20-tokens) * [Personal access tokens](https://docs.gitlab.com/user/profile/personal_access_tokens/) * [Project access tokens](https://docs.gitlab.com/user/project/settings/project_access_tokens/) * [Group access tokens](https://docs.gitlab.com/user/group/settings/group_access_tokens/) * [Session cookie](https://docs.gitlab.com/api/rest/authentication/#session-cookie) * [CI/CD job tokens](https://docs.gitlab.com/api/rest/authentication/#job-tokens) (specific endpoints only) Project access tokens are supported by: * GitLab Self-Managed: Free, Premium, and Ultimate. * GitLab.com: Premium and Ultimate. If you are an administrator, you or your application can authenticate as a specific user, using either: * [Impersonation tokens](https://docs.gitlab.com/api/rest/authentication/#impersonation-tokens) * [Sudo](https://docs.gitlab.com/api/rest/authentication/#sudo) If authentication information is not valid or is missing, GitLab returns an error message with a status code of `401`: { "message": "401 Unauthorized" } Deploy tokens can’t be used with the GitLab public API. For details, see [Deploy Tokens](https://docs.gitlab.com/user/project/deploy_tokens/) . OAuth 2.0 tokens ---------------- You can use an [OAuth 2.0 token](https://docs.gitlab.com/api/oauth2/) to authenticate with the API by passing it in either the `access_token` parameter or the `Authorization` header. Example of using the OAuth 2.0 token in a parameter: curl --request GET \ --url "https://gitlab.example.com/api/v4/projects?access_token=OAUTH-TOKEN" Example of using the OAuth 2.0 token in a header: curl --request GET \ --header "Authorization: Bearer OAUTH-TOKEN" \ --url "https://gitlab.example.com/api/v4/projects" Read more about [GitLab as an OAuth 2.0 provider](https://docs.gitlab.com/api/oauth2/) . All OAuth access tokens are valid for two hours after they are created. You can use the `refresh_token` parameter to refresh tokens. See [OAuth 2.0 token](https://docs.gitlab.com/api/oauth2/) documentation for how to request a new access token using a refresh token. Personal, project, and group access tokens ------------------------------------------ You can use access tokens to authenticate with the API. Pass the token using the `PRIVATE-TOKEN` header (recommended) or other methods. For example, using the recommended header method: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects" You can also use personal, project, or group access tokens with OAuth-compliant headers. For example: curl --request GET \ --header "Authorization: Bearer " \ --url "https://gitlab.example.com/api/v4/projects" Job tokens ---------- You can use job tokens to authenticate with [specific API endpoints](https://docs.gitlab.com/ci/jobs/ci_job_token/#job-token-access) . In GitLab CI/CD jobs, the token is available as the `CI_JOB_TOKEN` variable. Pass the token using the `JOB-TOKEN` header (recommended) or other methods. For all authentication methods, see [CI/CD job token authentication](https://docs.gitlab.com/ci/jobs/ci_job_token/#rest-api-authentication) . For example, using the header method: curl --request GET \ --header "JOB-TOKEN: $CI_JOB_TOKEN" \ --url "https://gitlab.example.com/api/v4/projects/1/releases" Session cookie -------------- Signing in to the main GitLab application sets a `_gitlab_session` cookie. The API uses this cookie for authentication if it’s present. Using the API to generate a new session cookie isn’t supported. The primary user of this authentication method is the web frontend of GitLab itself. The web frontend can use the API as the authenticated user to get a list of projects without explicitly passing an access token. Impersonation tokens -------------------- Impersonation tokens are a type of [personal access token](https://docs.gitlab.com/user/profile/personal_access_tokens/) . They can be created only by an administrator, and are used to authenticate with the API as a specific user. Use impersonation tokens as an alternative to: * The user’s password or one of their personal access tokens. * The [Sudo](https://docs.gitlab.com/api/rest/authentication/#sudo) feature. The user’s or administrator’s password or token may not be known, or may change over time. For more details, see the [User tokens API](https://docs.gitlab.com/api/user_tokens/#create-an-impersonation-token) documentation. Impersonation tokens are used exactly like regular personal access tokens, and can be passed in either the `private_token` parameter or the `PRIVATE-TOKEN` header. ### Disable impersonation By default, impersonation is enabled. To disable impersonation: Linux package (Omnibus) 1. Edit the `/etc/gitlab/gitlab.rb` file: gitlab_rails['impersonation_enabled'] = false 2. Save the file, and then [reconfigure](https://docs.gitlab.com/administration/restart_gitlab/#reconfigure-a-linux-package-installation) GitLab for the changes to take effect. Self-compiled (source) 1. Edit the `config/gitlab.yml` file: gitlab: impersonation_enabled: false 2. Save the file, and then [restart](https://docs.gitlab.com/administration/restart_gitlab/#self-compiled-installations) GitLab for the changes to take effect. To re-enable impersonation, remove this configuration and reconfigure GitLab (Linux package installations) or restart GitLab (self-compiled installations). Sudo ---- All API requests support performing an API request as if you were another user, provided you’re authenticated as an administrator with an OAuth or personal access token that has the `sudo` scope. The API requests are executed with the permissions of the impersonated user. As an [administrator](https://docs.gitlab.com/user/permissions/) , pass the `sudo` parameter either by using query string or a header with an ID or username (case-insensitive) of the user you want to perform the operation as. If passed as a header, the header name must be `Sudo`. If a non administrative access token is provided, GitLab returns an error message with a status code of `403`: { "message": "403 Forbidden - Must be admin to use sudo" } If an access token without the `sudo` scope is provided, an error message is returned with a status code of `403`: { "error": "insufficient_scope", "error_description": "The request requires higher privileges than provided by the access token.", "scope": "sudo" } If the sudo user ID or username cannot be found, an error message is returned with a status code of `404`: { "message": "404 User with ID or username '123' Not Found" } Example of a valid API request and a request using cURL with sudo request, providing a username: GET /projects?private_token=&sudo=username curl --request GET \ --header "PRIVATE-TOKEN: " \ --header "Sudo: username" \ --url "https://gitlab.example.com/api/v4/projects" Example of a valid API request and a request using cURL with sudo request, providing an ID: GET /projects?private_token=&sudo=23 curl --request GET \ --header "PRIVATE-TOKEN: " \ --header "Sudo: 23" \ --url "https://gitlab.example.com/api/v4/projects" --- # Merge request approvals API | GitLab Docs * * * Merge request approvals API =========================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * Endpoint `/approvals` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/353097) in GitLab 16.0. Use this API to manage [merge request approvals](https://docs.gitlab.com/user/project/merge_requests/approvals/) . All endpoints require authentication. Approve merge request --------------------- Approves the specified merge request. The currently authenticated user must be an [eligible approver](https://docs.gitlab.com/user/project/merge_requests/approvals/rules/#eligible-approvers) . 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](https://docs.gitlab.com/api/merge_requests/#merge-a-merge-request) . POST /projects/:id/merge_requests/:merge_request_iid/approve Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approval_password` | string | No | Current user’s password. Required if [**Require user re-authentication to approve**](https://docs.gitlab.com/user/project/merge_requests/approvals/settings/#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_iid` | integer | Yes | The IID of the merge request. | | `sha` | string | No | The `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"\ },\ "approved_at": "2016-06-10T04:21:41.050Z"\ },\ {\ "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"\ },\ "approved_at": "2016-06-10T09:17:13.520Z"\ }\ ] } ### Prevent approval resets in 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](https://docs.gitlab.com/user/project/merge_requests/approvals/settings/#remove-all-approvals-when-commits-are-added-to-the-source-branch) . 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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `merge_request_iid` | integer | Yes | The IID of a merge request. | Reset approvals for a merge request ----------------------------------- Resets all approvals for a specified merge request. Available only to [bot users](https://docs.gitlab.com/user/project/settings/project_access_tokens/#bot-users-for-projects) with a valid project or group token. Human users receive a `401 Unauthorized` response. PUT /projects/:id/merge_requests/:merge_request_iid/reset_approvals | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the project. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | curl --request PUT \ --header "PRIVATE-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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
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](https://docs.gitlab.com/user/project/merge_requests/approvals/rules/#eligible-approvers) . POST /projects/:id/approvals Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approvals_before_merge` (deprecated) | integer | No | The number of required approvals before a merge request can merge. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/11132)
in GitLab 12.3. [Create an approval rule](https://docs.gitlab.com/api/merge_request_approvals/#create-an-approval-rule-for-a-project)
instead. | | `disable_overriding_approvers_per_merge_request` | boolean | No | If `true`, prevents overrides of approvers in a merge request. | | `merge_requests_author_approval` | boolean | No | If `true`, authors can self-approve their own merge requests. | | `merge_requests_disable_committers_approval` | boolean | No | If `true`, users who commit on a merge request cannot approve it. | | `require_password_to_approve` (deprecated) | boolean | No | If `true`, require approvers to authenticate with a password before adding the approval. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/431346)
in GitLab 16.9. Use `require_reauthentication_to_approve` instead. | | `require_reauthentication_to_approve` | boolean | No | If `true`, requires approver to authenticate before adding the approval. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/431346)
in GitLab 17.1. | | `reset_approvals_on_push` | boolean | No | If `true`, approvals are reset on push. | | `selective_code_owner_removals` | boolean | No | If `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](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters. Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approval_rule_id` | integer | Yes | The 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](https://docs.gitlab.com/user/project/merge_requests/approvals/rules/) . * `report_approver`: Used when GitLab creates an approval rule from configured and enabled [merge request approval policies](https://docs.gitlab.com/user/application_security/policies/merge_request_approval_policies/) . Do not use this value when creating approval rules with this API. POST /projects/:id/approval_rules Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approvals_required` | integer | Yes | The number of required approvals for this rule. | | `name` | string | Yes | The name of the approval rule. Limited to 1024 characters. | | `applies_to_all_protected_branches` | boolean | No | If `true`, applies the rule to all protected branches and ignores the `protected_branch_ids` attribute. | | `group_ids` | Array | No | The IDs of groups as approvers. | | `protected_branch_ids` | Array | No | The IDs of protected branches to scope the rule by. To identify the ID, use the [List protected branches](https://docs.gitlab.com/api/protected_branches/#list-protected-branches)
API. | | `report_type` | string | No | The report type. Required when the rule type is `report_approver`. The supported report types are `license_scanning` [(Deprecated in GitLab 15.9)](https://docs.gitlab.com/update/deprecations/#license-check-and-the-policies-tab-on-the-license-compliance-page)
and `code_coverage`. | | `rule_type` | string | No | The rule type. Supported values include `any_approver`, `regular`, and `report_approver`. | | `user_ids` | Array | No | The IDs of users as approvers. If used with `usernames`, adds both lists of users. | | `usernames` | string array | No | The 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: " \ --header 'Content-Type: application/json' \ --data '{"name": "Any name", "rule_type": "any_approver", "approvals_required": 2}' \ --url "https://gitlab.example.com/api/v4/projects//approval_rules" Another example is to create a user-specific rule: curl --request POST \ --header "PRIVATE-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//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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `approval_rule_id` | integer | Yes | The ID of a approval rule. | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `applies_to_all_protected_branches` | boolean | No | If `true`, applies the rule to all protected branches and ignores the `protected_branch_ids` attribute. | | `approvals_required` | integer | No | The number of required approvals for this rule. | | `group_ids` | Array | No | The IDs of groups as approvers. | | `name` | string | No | The name of the approval rule. Limited to 1024 characters. | | `protected_branch_ids` | Array | No | The IDs of protected branches to scope the rule by. To identify the ID, use the [List protected branches](https://docs.gitlab.com/api/protected_branches/#list-protected-branches)
API. | | `remove_hidden_groups` | boolean | No | If `true`, removes hidden groups from the approval rule. | | `user_ids` | Array | No | The IDs of users as approvers. If used with `usernames`, adds both lists of users. | | `usernames` | string array | No | The 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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approval_rule_id` | integer | Yes | The 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. In the response, `approved_by` contains information about all approvers of the merge request, regardless of whether those approvals satisfy any approval rule. For more detailed information about the approval rules in a merge request, and whether the approvals received satisfy those rules, see the [`/approval_state` endpoint](https://docs.gitlab.com/api/merge_request_approvals/#retrieve-approval-details-for-a-merge-request) . GET /projects/:id/merge_requests/:merge_request_iid/approvals Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `merge_request_iid` | integer | Yes | The 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"\ },\ "approved_at": "2016-06-09T01:45:21.720Z"\ }\ ] } ### 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. Users not matching an approval rule are not returned. To return all approving users, see the [`/approvals` endpoint](https://docs.gitlab.com/api/merge_request_approvals/#retrieve-approval-state-for-a-merge-request) . GET /projects/:id/merge_requests/:merge_request_iid/approval_state Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `merge_request_iid` | integer | Yes | The 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](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to restrict the list of approval rules. GET /projects/:id/merge_requests/:merge_request_iid/approval_rules Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `merge_request_iid` | integer | Yes | The 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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approval_rule_id` | integer | Yes | The ID of an approval rule. | | `merge_request_iid` | integer | Yes | The 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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approvals_required` | integer | Yes | The number of required approvals for this rule. | | `merge_request_iid` | integer | Yes | The IID of the merge request. | | `name` | string | Yes | The name of the approval rule. Limited to 1024 characters. | | `approval_project_rule_id` | integer | No | The ID of a project’s approval rule. | | `group_ids` | Array | No | The IDs of groups as approvers. | | `user_ids` | Array | No | The IDs of users as approvers. If used with `usernames`, adds both lists of users. | | `usernames` | string array | No | The 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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approval_rule_id` | integer | Yes | The ID of an approval rule. | | `merge_request_iid` | integer | Yes | The IID of a merge request. | | `approvals_required` | integer | No | The number of required approvals for this rule. | | `group_ids` | Array | No | The IDs of groups as approvers. | | `name` | string | No | The name of the approval rule. Limited to 1024 characters. | | `remove_hidden_groups` | boolean | No | If `true`, removes hidden groups. | | `user_ids` | Array | No | The IDs of users as approvers. If used with `usernames`, adds both lists of users. | | `usernames` | string array | No | The 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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | | `approval_rule_id` | integer | Yes | The ID of an approval rule. | | `merge_request_iid` | integer | Yes | The IID of the merge request. | Approval rules for groups ------------------------- * Status: Experiment History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/428051) in GitLab 16.7 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `approval_group_rules`. Disabled by default. This feature is an [experiment](https://docs.gitlab.com/policy/development_stages_support/) . On GitLab Self-Managed, by default this feature is not available. To make it available, an administrator can [enable the feature flag](https://docs.gitlab.com/administration/feature_flags/) 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 * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/440638) in GitLab 16.10. Lists all approval rules and any associated details for a specified group. Restricted to group administrators. Use the `page` and `per_page` [pagination](https://docs.gitlab.com/api/rest/#offset-based-pagination) parameters to restrict the list of approval rules. GET /groups/:id/approval_rules Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a project. | Example request: curl --request GET \ --header "PRIVATE-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: * `any_approver`: A pre-configured default rule with `approvals_required` set to `0`. * `regular`: Used for regular [merge request approval rules](https://docs.gitlab.com/user/project/merge_requests/approvals/rules/) . * `report_approver`: Used when GitLab creates an approval rule from configured and enabled [merge request approval policies](https://docs.gitlab.com/user/application_security/policies/merge_request_approval_policies/) . POST /groups/:id/approval_rules Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of a group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `approvals_required` | integer | Yes | The number of required approvals for this rule. | | `name` | string | Yes | The name of the approval rule. Limited to 1024 characters. | | `group_ids` | array | No | The IDs of groups as approvers. | | `rule_type` | string | No | The rule type. Supported values include `any_approver`, `regular`, and `report_approver`. | | `user_ids` | array | No | The IDs of users as approvers. | Example request: curl --request POST \ --header "PRIVATE-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 * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/440639) in GitLab 16.10. 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: * `any_approver`: A pre-configured default rule with `approvals_required` set to `0`. * `regular`: Used for regular [merge request approval rules](https://docs.gitlab.com/user/project/merge_requests/approvals/rules/) . * `report_approver`: Used when GitLab creates an approval rule from configured and enabled [merge request approval policies](https://docs.gitlab.com/user/application_security/policies/merge_request_approval_policies/) . PUT /groups/:id/approval_rules/:approval_rule_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `approval_rule_id` | integer | Yes | The ID of the approval rule. | | `id` | integer or string | Yes | The ID or [URL-encoded path of a group](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `approvals_required` | string | No | The number of required approvals for this rule. | | `group_ids` | integer | No | The IDs of users as approvers. | | `name` | string | No | The name of the approval rule. Limited to 1024 characters. | | `rule_type` | array | No | The rule type. Supported values include `any_approver`, `regular`, and `report_approver`. | | `user_ids` | array | No | The IDs of groups as approvers. | Example request: curl --request PUT \ --header "PRIVATE-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 } --- # Web API fuzz testing | GitLab Docs * * * Web API fuzz testing ==================== * Tier: Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Web API fuzz testing passes unexpected values to API operation parameters to cause unexpected behavior and errors in the backend. Use fuzz testing to discover bugs and potential vulnerabilities that other QA processes might miss. You should use fuzz testing in addition to the other security scanners in [GitLab Secure](https://docs.gitlab.com/user/application_security/) and your own test processes. If you’re using [GitLab CI/CD](https://docs.gitlab.com/ci/) , you can run fuzz tests as part your CI/CD workflow. For an overview, see [Web API fuzzing - Advanced Security Testing](https://www.youtube.com/watch?v=oUHsfvLGhDk) . Getting started --------------- Get started with API fuzzing by editing your CI/CD configuration. Prerequisites: * A web API using one of the supported API types: * REST API * SOAP * GraphQL * Form bodies, JSON, or XML * An API specification in one of the following formats: * OpenAPI v2 or v3 Specification * GraphQL Schema * HTTP Archive (HAR) * Postman Collection v2.0 or v2.1 * An available GitLab Runner with the `docker` executor on Linux/amd64. * A deployed target application. * The `fuzz` stage is added to your CI/CD pipeline definition, after the `deploy` stage: stages: - build - test - deploy - fuzz To enable API fuzzing: * Use the [Web API fuzzing configuration form](https://docs.gitlab.com/user/application_security/api_fuzzing/configuration/enabling_the_analyzer/#web-api-fuzzing-configuration-form) . The form lets you choose values for the most common API fuzzing options, and builds a YAML snippet that you can paste in your GitLab CI/CD configuration. Understanding the results ------------------------- To view the output of a security scan: 1. In the top bar, select **Search or go to** and find your project. 2. In the left sidebar, select **Build** > **Pipelines**. 3. Select the pipeline. 4. Select the **Security** tab. 5. Select a vulnerability to view its details, including: * Status: Indicates whether the vulnerability has been triaged or resolved. * Description: Explains the cause of the vulnerability, its potential impact, and recommended remediation steps. * Severity: Categorized into six levels based on impact. For more information, see [severity levels](https://docs.gitlab.com/user/application_security/vulnerabilities/severities/) . * Scanner: Identifies which analyzer detected the vulnerability. * Method: Establishes the vulnerable server interaction type. * URL: Shows the location of the vulnerability. * Evidence: Describes test case to prove the presence of a given vulnerability * Identifiers: A list of references used to classify the vulnerability, such as CWE identifiers. You can also download the security scan results: * In the pipeline’s **Security** tab, select **Download results**. For more details, see the [pipeline security report](https://docs.gitlab.com/user/application_security/detect/security_scanning_results/) . Findings are generated on feature branches. When they are merged into the default branch, they become vulnerabilities. This distinction is important when evaluating your security posture. Optimization ------------ To get the most out of API fuzzing, follow these recommendations: * To run the latest versions of the analyzers, configure runners to use `pull_policy: always`. * By default, API fuzzing downloads all artifacts defined by previous jobs in the pipeline. If your API fuzzing job does not rely on `environment_url.txt` to define the URL under test or any other files created in previous jobs, you should not download artifacts. To avoid downloading artifacts, extend the analyzer CI/CD job to specify no dependencies. For example, for the API fuzzing analyzer, add the following to your `.gitlab-ci.yml` file: apifuzzer_fuzz: dependencies: [] ### Application deployment options API fuzzing requires a deployed application to be available to scan. Depending on the complexity of the target application, there are a few options as to how to deploy and configure the API fuzzing template. #### Review apps Review apps are the most involved method of deploying your API fuzzing target application. To assist in the process, GitLab created a review app deployment using Google Kubernetes Engine (GKE). This example can be found in the [Review apps - GKE](https://gitlab.com/gitlab-org/security-products/demos/dast/review-app-gke) project, plus detailed instructions to configure review apps in DAST. #### Docker services If your application uses Docker containers, you have another option for deploying and scanning with API fuzzing. After your Docker build job completes and your image is added to your container registry, you can use the image as a service. By using service definitions in your `.gitlab-ci.yml`, you can scan services with the DAST analyzer. When adding a `services` section to the job, the `alias` is used to define the hostname that can be used to access the service. In the following example, the `alias: yourapp` portion of the `dast` job definition means that the URL to the deployed application uses `yourapp` as the hostname: `https://yourapp/`. stages: - build - fuzz include: - template: API-Fuzzing.gitlab-ci.yml # Deploys the container to the GitLab container registry deploy: services: - name: docker:dind alias: dind image: docker:20.10.16 stage: build script: - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - docker pull $CI_REGISTRY_IMAGE:latest || true - docker build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest . - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - docker push $CI_REGISTRY_IMAGE:latest apifuzzer_fuzz: services: # use services to link your app container to the dast job - name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA alias: yourapp variables: FUZZAPI_TARGET_URL: https://yourapp Most applications depend on multiple services such as databases or caching services. By default, services defined in the services fields cannot communicate with each another. To allow communication between services, enable the `FF_NETWORK_PER_BUILD` feature flag. variables: FF_NETWORK_PER_BUILD: "true" # enable network per build so all services can communicate on the same network services: # use services to link the container to the dast job - name: mongo:latest alias: mongo - name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA alias: yourapp Roll out -------- Web API fuzzing runs in the `fuzz` stage of the CI/CD pipeline. To ensure API fuzzing scans the latest code, your CI/CD pipeline should deploy changes to a test environment in one of the stages preceding the `fuzz` stage. If your pipeline is configured to deploy to the same web server on each run, running a pipeline while another is still running could cause a race condition in which one pipeline overwrites the code from another. The API to scan should be excluded from changes for the duration of a fuzzing scan. The only changes to the API should be from the fuzzing scanner. Any changes made to the API (for example, by users, scheduled tasks, database changes, code changes, other pipelines, or other scanners) during a scan could cause inaccurate results. You can run a web API fuzzing scan using the following methods: * OpenAPI specification (versions 2 and 3) * GraphQL schema * HTTP archive (HAR) * Postman collection (versions 2.0 and 2.1) ### Example API fuzzing projects * [Example OpenAPI v2 Specification project](https://gitlab.com/gitlab-org/security-products/demos/api-fuzzing-example/-/tree/openapi) * [Example HTTP Archive (HAR) project](https://gitlab.com/gitlab-org/security-products/demos/api-fuzzing-example/-/tree/har) * [Example Postman Collection project](https://gitlab.com/gitlab-org/security-products/demos/api-fuzzing/postman-api-fuzzing-example) * [Example GraphQL project](https://gitlab.com/gitlab-org/security-products/demos/api-fuzzing/graphql-api-fuzzing-example) * [Example SOAP project](https://gitlab.com/gitlab-org/security-products/demos/api-fuzzing/soap-api-fuzzing-example) * [Authentication Token using Selenium](https://gitlab.com/gitlab-org/security-products/demos/api-fuzzing/auth-token-selenium) Get support or request an improvement ------------------------------------- To get support for your particular problem use the [getting help channels](https://about.gitlab.com/get-help/) . The [GitLab issue tracker on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues) is the right place for bugs and feature proposals about API security and API fuzzing. Use `~"Category:API Security"` label when opening a new issue regarding API fuzzing to ensure it is quickly reviewed by the right people. Search the issue tracker for similar entries before submitting your own, there’s a good chance somebody else had the same issue or feature proposal. Show your support with an emoji reaction or join the discussion. When experiencing a behavior not working as expected, consider providing contextual information: * GitLab version if using a GitLab Self-Managed instance. * `.gitlab-ci.yml` job definition. * Full job console output. * Scanner log file available as a job artifact named `gl-api-security-scanner.log`. Do not include sensitive information when you submit an issue. Remove credentials like passwords, tokens, and keys. Glossary -------- * Assert: Assertions are detection modules used by checks to trigger a fault. Many assertions have configurations. A check can use multiple Assertions. For example, Log Analysis, Response Analysis, and Status Code are common Assertions used together by checks. Checks with multiple Assertions allow them to be turned on and off. * Check: Performs a specific type of test, or performed a check for a type of vulnerability. For example, the JSON Fuzzing Check performs fuzz testing of JSON payloads. The API fuzzer is comprised of several checks. Checks can be turned on and off in a profile. * Fault: During fuzzing, a failure identified by an Assert is called a fault. Faults are investigated to determine if they are a security vulnerability, a non-security issue, or a false positive. Faults don’t have a known vulnerability type until they are investigated. Example vulnerability types are SQL Injection and Denial of Service. * Profile: A configuration file has one or more testing profiles, or sub-configurations. You may have a profile for feature branches and another with extra testing for a main branch. --- # Group clusters API (certificate-based) (deprecated) | GitLab Docs * * * Group clusters API (certificate-based) (deprecated) =================================================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. Similarly to [project-level](https://docs.gitlab.com/user/project/clusters/) and [instance-level](https://docs.gitlab.com/user/instance/clusters/) Kubernetes clusters, group-level Kubernetes clusters allow you to connect a Kubernetes cluster to your group, enabling you to use the same cluster across multiple projects. Users need the Maintainer or Owner role for the group to use these endpoints. List group clusters ------------------- Lists all group clusters for a specified group. GET /groups/:id/clusters Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/26/clusters" Example response: [\ {\ "id":18,\ "name":"cluster-1",\ "domain":"example.com",\ "created_at":"2019-01-02T20:18:12.563Z",\ "managed": true,\ "enabled": true,\ "provider_type":"user",\ "platform_type":"kubernetes",\ "environment_scope":"*",\ "cluster_type":"group_type",\ "user":\ {\ "id":1,\ "name":"Administrator",\ "username":"root",\ "state":"active",\ "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..",\ "web_url":"https://gitlab.example.com/root"\ },\ "platform_kubernetes":\ {\ "api_url":"https://104.197.68.152",\ "authorization_type":"rbac",\ "ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----"\ },\ "management_project":\ {\ "id":2,\ "description":null,\ "name":"project2",\ "name_with_namespace":"John Doe8 / project2",\ "path":"project2",\ "path_with_namespace":"namespace2/project2",\ "created_at":"2019-10-11T02:55:54.138Z"\ }\ },\ {\ "id":19,\ "name":"cluster-2",\ ...\ }\ ] Retrieve a group cluster ------------------------ Retrieves a specified group cluster. GET /groups/:id/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `cluster_id` | integer | yes | The ID of the cluster | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/26/clusters/18" Example response: { "id":18, "name":"cluster-1", "domain":"example.com", "created_at":"2019-01-02T20:18:12.563Z", "managed": true, "enabled": true, "provider_type":"user", "platform_type":"kubernetes", "environment_scope":"*", "cluster_type":"group_type", "user": { "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..", "web_url":"https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url":"https://104.197.68.152", "authorization_type":"rbac", "ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----" }, "management_project": { "id":2, "description":null, "name":"project2", "name_with_namespace":"John Doe8 / project2", "path":"project2", "path_with_namespace":"namespace2/project2", "created_at":"2019-10-11T02:55:54.138Z" }, "group": { "id":26, "name":"group-with-clusters-api", "web_url":"https://gitlab.example.com/group-with-clusters-api" } } Create a group cluster ---------------------- Creates a group cluster for a specified group by adding an existing Kubernetes cluster. POST /groups/:id/clusters/user Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `name` | string | yes | The name of the cluster | | `domain` | string | no | The [base domain](https://docs.gitlab.com/user/group/clusters/#base-domain)
of the cluster | | `management_project_id` | integer | no | The ID of the [management project](https://docs.gitlab.com/user/clusters/management_project/)
for the cluster | | `enabled` | boolean | no | Determines if cluster is active or not, defaults to `true` | | `managed` | boolean | no | Determines if GitLab manages namespaces and service accounts for this cluster. Defaults to `true` | | `platform_kubernetes_attributes[api_url]` | string | yes | The URL to access the Kubernetes API | | `platform_kubernetes_attributes[token]` | string | yes | The token to authenticate against Kubernetes | | `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. | | `platform_kubernetes_attributes[authorization_type]` | string | no | The cluster authorization type: `rbac`, `abac` or `unknown_authorization`. Defaults to `rbac`. | | `environment_scope` | string | no | The associated environment to the cluster. Defaults to `*`. Premium and Ultimate only. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Accept: application/json" \ --header "Content-Type:application/json" \ --url "https://gitlab.example.com/api/v4/groups/26/clusters/user" \ --data '{ "name":"cluster-5", "platform_kubernetes_attributes":{ "api_url":"https://35.111.51.20", "token":"12345", "ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----" } }' Example response: { "id":24, "name":"cluster-5", "created_at":"2019-01-03T21:53:40.610Z", "managed": true, "enabled": true, "provider_type":"user", "platform_type":"kubernetes", "environment_scope":"*", "cluster_type":"group_type", "user": { "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..", "web_url":"https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url":"https://35.111.51.20", "authorization_type":"rbac", "ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----" }, "management_project":null, "group": { "id":26, "name":"group-with-clusters-api", "web_url":"https://gitlab.example.com/root/group-with-clusters-api" } } Update a group cluster ---------------------- Updates a specified group cluster. PUT /groups/:id/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `cluster_id` | integer | yes | The ID of the cluster | | `name` | string | no | The name of the cluster | | `domain` | string | no | The [base domain](https://docs.gitlab.com/user/group/clusters/#base-domain)
of the cluster | | `management_project_id` | integer | no | The ID of the [management project](https://docs.gitlab.com/user/clusters/management_project/)
for the cluster | | `enabled` | boolean | no | Determines if cluster is active or not | | `managed` | boolean | no | Determines if GitLab manages namespaces and service accounts for this cluster | | `platform_kubernetes_attributes[api_url]` | string | no | The URL to access the Kubernetes API | | `platform_kubernetes_attributes[token]` | string | no | The token to authenticate against Kubernetes | | `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate. Required if API is using a self-signed TLS certificate. | | `environment_scope` | string | no | The associated environment to the cluster. Premium and Ultimate only. | `name`, `api_url`, `ca_cert` and `token` can only be updated if the cluster was added through the [“Add existing Kubernetes cluster”](https://docs.gitlab.com/user/project/clusters/add_existing_cluster/) option or through the [“Create a group cluster”](https://docs.gitlab.com/api/group_clusters/#create-a-group-cluster) endpoint. Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type:application/json" \ --url "https://gitlab.example.com/api/v4/groups/26/clusters/24" \ --data '{ "name":"new-cluster-name", "domain":"new-domain.com", "platform_kubernetes_attributes":{ "api_url":"https://10.10.101.1:6433" } }' Example response: { "id":24, "name":"new-cluster-name", "domain":"new-domain.com", "created_at":"2019-01-03T21:53:40.610Z", "managed": true, "enabled": true, "provider_type":"user", "platform_type":"kubernetes", "environment_scope":"*", "cluster_type":"group_type", "user": { "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/4249f4df72b..", "web_url":"https://gitlab.example.com/root" }, "platform_kubernetes": { "api_url":"https://new-api-url.com", "authorization_type":"rbac", "ca_cert":null }, "management_project": { "id":2, "description":null, "name":"project2", "name_with_namespace":"John Doe8 / project2", "path":"project2", "path_with_namespace":"namespace2/project2", "created_at":"2019-10-11T02:55:54.138Z" }, "group": { "id":26, "name":"group-with-clusters-api", "web_url":"https://gitlab.example.com/group-with-clusters-api" } } Delete a group cluster ---------------------- Deletes a specified group cluster. Does not remove existing resources within the connected Kubernetes cluster. DELETE /groups/:id/clusters/:cluster_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `cluster_id` | integer | yes | The ID of the cluster | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/26/clusters/23" --- # Group enterprise users API | GitLab Docs * * * Group enterprise users API ========================== * Tier: Premium, Ultimate * Offering: GitLab.com Use these API endpoints to interact with enterprise users accounts. For more information, see [enterprise users](https://docs.gitlab.com/user/enterprise_user/) . These API endpoints only work for top-level groups. Users do not have to be a member of the group. Prerequisites: * You must have the Owner role in the top-level group. List all enterprise users ------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/438366) in GitLab 17.7. Lists all enterprise users for a specified top-level group. Use the `page` and `per_page` [pagination parameters](https://docs.gitlab.com/api/rest/#offset-based-pagination) to filter the results. GET /groups/:id/enterprise_users Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a top-level group. | | `username` | string | no | Return a user with a given username. | | `search` | string | no | Return users with a matching name, email, or username. Use partial values to increase results. | | `active` | boolean | no | Return only active users. | | `blocked` | boolean | no | Return only blocked users. | | `created_after` | datetime | no | Return users created after the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). | | `created_before` | datetime | no | Return users created before the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). | | `two_factor` | string | no | Return users based on their two-factor authentication (2FA) enrollment status. Possible values: `enabled`, `disabled`. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/:id/enterprise_users" Example response: [\ {\ "id": 66,\ "username": "user22",\ "name": "Sidney Jones22",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/xxx?s=80&d=identicon",\ "web_url": "http://my.gitlab.com/user22",\ "created_at": "2021-09-10T12:48:22.381Z",\ "bio": "",\ "location": null,\ "public_email": "",\ "linkedin": "",\ "twitter": "",\ "website_url": "",\ "organization": null,\ "job_title": "",\ "pronouns": null,\ "bot": false,\ "work_information": null,\ "followers": 0,\ "following": 0,\ "local_time": null,\ "last_sign_in_at": null,\ "confirmed_at": "2021-09-10T12:48:22.330Z",\ "last_activity_on": null,\ "email": "user22@example.org",\ "theme_id": 1,\ "color_scheme_id": 1,\ "projects_limit": 100000,\ "current_sign_in_at": null,\ "identities": [\ {\ "provider": "group_saml",\ "extern_uid": "2435223452345",\ "saml_provider_id": 1\ }\ ],\ "can_create_group": true,\ "can_create_project": true,\ "two_factor_enabled": false,\ "external": false,\ "private_profile": false,\ "commit_email": "user22@example.org",\ "shared_runners_minutes_limit": null,\ "extra_shared_runners_minutes_limit": null,\ "scim_identities": [\ {\ "extern_uid": "2435223452345",\ "group_id": 1,\ "active": true\ }\ ]\ },\ ...\ ] Retrieve an enterprise user --------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176328) in GitLab 17.9. Retrieves a specified enterprise user. GET /groups/:id/enterprise_users/:user_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a top-level group. | | `user_id` | integer | yes | ID of user account. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/:id/enterprise_users/:user_id" Example response: { "id": 66, "username": "user22", "name": "Sidney Jones22", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/xxx?s=80&d=identicon", "web_url": "http://my.gitlab.com/user22", "created_at": "2021-09-10T12:48:22.381Z", "bio": "", "location": null, "public_email": "", "linkedin": "", "twitter": "", "website_url": "", "organization": null, "job_title": "", "pronouns": null, "bot": false, "work_information": null, "followers": 0, "following": 0, "local_time": null, "last_sign_in_at": null, "confirmed_at": "2021-09-10T12:48:22.330Z", "last_activity_on": null, "email": "user22@example.org", "theme_id": 1, "color_scheme_id": 1, "projects_limit": 100000, "current_sign_in_at": null, "identities": [\ {\ "provider": "group_saml",\ "extern_uid": "2435223452345",\ "saml_provider_id": 1\ }\ ], "can_create_group": true, "can_create_project": true, "two_factor_enabled": false, "external": false, "private_profile": false, "commit_email": "user22@example.org", "shared_runners_minutes_limit": null, "extra_shared_runners_minutes_limit": null, "scim_identities": [\ {\ "extern_uid": "2435223452345",\ "group_id": 1,\ "active": true\ }\ ] } Update an enterprise user ------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/199248) in GitLab 18.6. Updates a specified enterprise user. PATCH /groups/:id/enterprise_users/:user_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a top-level group. | | `user_id` | integer | yes | ID of user account. | | `name` | string | no | Name of the user account. | | `email` | string | no | Email address of the user account. Must be from a verified [group domain](https://docs.gitlab.com/user/enterprise_user/#manage-group-domains)
. | Example request: curl --request PATCH --header "PRIVATE-TOKEN: " --data "email=new-email@example.com" --data "name=New name" "https://gitlab.example.com/api/v4/groups/:id/enterprise_users/:user_id" If successful, returns `200 OK`. Example of successful response: { "id": 66, "username": "user22", "name": "New name", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/xxx?s=80&d=identicon", "web_url": "http://my.gitlab.com/user22", "created_at": "2021-09-10T12:48:22.381Z", "bio": "", "location": null, "public_email": "", "linkedin": "", "twitter": "", "website_url": "", "organization": null, "job_title": "", "pronouns": null, "bot": false, "work_information": null, "followers": 0, "following": 0, "local_time": null, "last_sign_in_at": null, "confirmed_at": "2021-09-10T12:48:22.330Z", "last_activity_on": null, "email": "new-email@example.com", "theme_id": 1, "color_scheme_id": 1, "projects_limit": 100000, "current_sign_in_at": null, "identities": [\ {\ "provider": "group_saml",\ "extern_uid": "2435223452345",\ "saml_provider_id": 1\ }\ ], "can_create_group": true, "can_create_project": true, "two_factor_enabled": false, "external": false, "private_profile": false, "commit_email": "user22@example.org", "shared_runners_minutes_limit": null, "extra_shared_runners_minutes_limit": null, "scim_identities": [\ {\ "extern_uid": "2435223452345",\ "group_id": 1,\ "active": true\ }\ ] } Other possible responses: * `400 Bad Request`: Validation errors. * `403 Forbidden`: The authenticated user is not an Owner. * `404 Not found`: User can not be found. Delete an enterprise user ------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/199646) in GitLab 18.3. Deletes a specified enterprise user. DELETE /groups/:id/enterprise_users/:user_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a top-level group. | | `user_id` | integer | yes | ID of user account. | | `hard_delete` | boolean | no | If `false`, deletes the user and moves their contributions [to a ghost user](https://docs.gitlab.com/user/profile/account/delete_account/#associated-records)
. If `true`, deletes the user, their associated contributions, and any groups owned solely by the user. Default value: `false`. | Example request: curl --request DELETE --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/:id/enterprise_users/:user_id" If successful, returns `204 No content`. Other possible responses: * `403 Forbidden`: The authenticated user is not an Owner. * `404 Not found`: The user can not be found. * `409 Conflict`: Can not remove a user who is the sole Owner of a group. Disable two-factor authentication for an enterprise user -------------------------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177943) in GitLab 17.9. Disables two-factor authentication (2FA) for a specified enterprise user. PATCH /groups/:id/enterprise_users/:user_id/disable_two_factor Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of a top-level group. | | `user_id` | integer | yes | ID of user account. | Example request: curl --request PATCH --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/groups/:id/enterprise_users/:user_id/disable_two_factor" If successful, returns `204 No content`. Other possible responses: * `400 Bad request`: 2FA is not enabled for the specified user. * `403 Forbidden`: The authenticated user is not an Owner. * `404 Not found`: User can not be found. --- # Projects members API | GitLab Docs * * * Projects members API ==================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this endpoint to interact with project members. For information about group members, see the [Group members API](https://docs.gitlab.com/api/group_members/) . Known issues ------------ * The `group_saml_identity` and `group_scim_identity` attributes are only visible to group owners for [SSO-enabled groups](https://docs.gitlab.com/user/group/saml_sso/) . * The `email` attribute is only visible to group owners for [enterprise users](https://docs.gitlab.com/user/enterprise_user/) of the group when an API request is sent to the group itself, or that group’s subgroups or projects. List all direct members of a project ------------------------------------ Lists all direct members of a specified project viewable by the authenticated user. Use [List all members of a project](https://docs.gitlab.com/api/project_members/#list-all-members-of-a-project) to list inherited members. This function takes pagination parameters `page` and `per_page` to restrict the list of users. GET /projects/:id/members | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `query` | string | no | Filters results based on a given name, email, or username. Use partial values to widen the scope of the query. | | `user_ids` | array of integers | no | Filter the results on the given user IDs. | | `skip_users` | array of integers | no | Filter skipped users out of the results. | | `show_seat_info` | boolean | no | Show seat information for users. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/members" Example response: [\ {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "group_saml_identity": null,\ "is_using_seat": true\ },\ {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "email": "john@example.com",\ "group_saml_identity": {\ "extern_uid":"ABC-1234567890",\ "provider": "group_saml",\ "saml_provider_id": 10\ }\ }\ ] List all members of a project ----------------------------- History * [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to return members of the invited private group if the current user is a member of the shared group or project in GitLab 16.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `webui_members_inherited_users`. Disabled by default. * Feature flag `webui_members_inherited_users` was [enabled on GitLab.com and GitLab Self-Managed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) in GitLab 17.0. * Feature flag `webui_members_inherited_users` [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163627) in GitLab 17.4. Members of invited groups displayed by default. Lists all project members viewable by the authenticated user, including inherited members, invited users, and permissions through ancestor groups. If a user is a member of this project and also of one or more ancestor groups, only its membership with the highest `access_level` is returned. This represents the effective permission of the user. Members from an invited group are returned if either: * The invited group is public. * The requester is also a member of the invited group. * The requester is a member of the shared group or project. The invited group members have shared membership in the shared group or project. This means that if the requester is a member of a shared group or project, but not a member of an invited private group, then using this endpoint the requester can get all the shared group or project members, including the invited private group members. This function takes pagination parameters `page` and `per_page` to restrict the list of users. GET /projects/:id/members/all | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `query` | string | no | Filters results based on a given name, email, or username. Use partial values to widen the scope of the query. | | `user_ids` | array of integers | no | Filter the results on the given user IDs. | | `show_seat_info` | boolean | no | Show seat information for users. | | `state` | string | no | Filter results by member state, one of `awaiting` or `active`. Premium and Ultimate only. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/members/all" Example response: [\ {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "group_saml_identity": null\ },\ {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-09-22T14:13:35Z",\ "created_by": {\ "id": 1,\ "username": "raymond_smith",\ "name": "Raymond Smith",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-10-22",\ "access_level": 30,\ "email": "john@example.com",\ "group_saml_identity": {\ "extern_uid":"ABC-1234567890",\ "provider": "group_saml",\ "saml_provider_id": 10\ }\ },\ {\ "id": 3,\ "username": "foo_bar",\ "name": "Foo bar",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root",\ "created_at": "2012-10-22T14:13:35Z",\ "created_by": {\ "id": 2,\ "username": "john_doe",\ "name": "John Doe",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",\ "web_url": "http://192.168.1.8:3000/root"\ },\ "expires_at": "2012-11-22",\ "access_level": 30,\ "group_saml_identity": null\ }\ ] Retrieve a direct member of a project ------------------------------------- Retrieves a specified direct member of a project. Use [retrieve a member of a project](https://docs.gitlab.com/api/project_members/#retrieve-a-member-of-a-project) to retrieve inherited members. GET /projects/:id/members/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/members/:user_id" To update or remove a custom role from a group member, pass an empty `member_role_id` value: # Updates a project membership curl --request PUT --header "Content-Type: application/json" \ --header "Authorization: Bearer " \ --data '{"member_role_id": null, "access_level": 10}' \ --url "https://gitlab.example.com/api/v4/projects//members/" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "access_level": 30, "email": "john@example.com", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": null, "group_saml_identity": null } Retrieve a member of a project ------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17744) in GitLab 12.4. * [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) to return members of the invited private group if the current user is a member of the shared group or project in GitLab 16.10 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `webui_members_inherited_users`. Disabled by default. * [Enabled on GitLab.com and GitLab Self-Managed](https://gitlab.com/gitlab-org/gitlab/-/issues/219230) in GitLab 17.0. * Feature flag `webui_members_inherited_users` [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163627) in GitLab 17.4. Members of invited groups displayed by default. Retrieves a specified member of a project, including members inherited or invited through ancestor groups. For more information, see [list all members of a project](https://docs.gitlab.com/api/project_members/#list-all-members-of-a-project) . The invited group members have shared membership in the shared group or project. This means that if the requester is a member of a shared group or project, but not a member of an invited private group, then using this endpoint the requester can get all the shared group or project members, including the invited private group members. GET /projects/:id/members/all/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/members/all/:user_id" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "access_level": 30, "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "email": "john@example.com", "expires_at": null, "group_saml_identity": null } Add a member to a project ------------------------- Adds a direct member to a specified project. To give a group access to a project, see [share a project with group](https://docs.gitlab.com/api/projects/#share-a-project-with-a-group) . POST /projects/:id/members | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer or string | yes, if `username` is not provided | The user ID of the new member or multiple IDs separated by commas. | | `username` | string | yes, if `user_id` is not provided | The username of the new member or multiple usernames separated by commas. | | `access_level` | integer | yes | A valid [access level](https://docs.gitlab.com/user/permissions/#default-roles)
Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). Default: `30`. | | `expires_at` | string | no | A date string in the format `YEAR-MONTH-DAY`. | | `invite_source` | string | no | The source of the invitation that starts the member creation process. GitLab team members can view more information in this confidential issue: `https://gitlab.com/gitlab-org/gitlab/-/issues/327120`. | | `member_role_id` | integer | no | Ultimate only. The ID of a custom member role. | curl --request POST --header "PRIVATE-TOKEN: " \ --data "user_id=1&access_level=30" \ --url "https://gitlab.example.com/api/v4/projects/:id/members" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": "2012-10-22", "access_level": 30, "email": "john@example.com", "group_saml_identity": null } If [administrator approval for role promotions](https://docs.gitlab.com/administration/settings/sign_up_restrictions/#turn-on-administrator-approval-for-role-promotions) is turned on, membership requests that promote existing users into a billable role require administrator approval. To enable **Manage Non-Billable Promotions**, you must first enable the `enable_member_promotion_management` application setting. Example of queueing a single user: curl --request POST --header "PRIVATE-TOKEN: " \ --data "user_id=1&access_level=30" \ --url "https://gitlab.example.com/api/v4/projects/:id/members" { "message":{ "username_1":"Request queued for administrator approval." } } Example of queueing multiple users: curl --request POST --header "PRIVATE-TOKEN: " \ --data "user_id=1,2&access_level=30" \ --url "https://gitlab.example.com/api/v4/projects/:id/members" { "queued_users": { "username_1": "Request queued for administrator approval.", "username_2": "Request queued for administrator approval." }, "status": "success" } Update a member of a project ---------------------------- Updates the specified member of a project. PUT /projects/:id/members/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | | `access_level` | integer | yes | A valid [access level](https://docs.gitlab.com/user/permissions/#default-roles)
Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). Default: `30`. | | `expires_at` | string | no | A date string in the format `YEAR-MONTH-DAY`. | | `member_role_id` | integer | no | Ultimate only. The ID of a custom member role. If no value is specified, removes all roles. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/members/:user_id?access_level=40" Example response: { "id": 1, "username": "raymond_smith", "name": "Raymond Smith", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root", "created_at": "2012-10-22T14:13:35Z", "created_by": { "id": 2, "username": "john_doe", "name": "John Doe", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon", "web_url": "http://192.168.1.8:3000/root" }, "expires_at": "2012-10-22", "access_level": 40, "email": "john@example.com", "group_saml_identity": null } If [administrator approval for role promotions](https://docs.gitlab.com/administration/settings/sign_up_restrictions/#turn-on-administrator-approval-for-role-promotions) is turned on, membership requests that promote existing users into a billable role require administrator approval. To enable **Manage non-billable promotions**, you must first enable the `enable_member_promotion_management` application setting. Example response: { "message":{ "username_1":"Request queued for administrator approval." } } Remove a direct member of a project ----------------------------------- Removes the specified direct member of a project. For example, if the user was added directly to a project in the group but not this group explicitly, you cannot use this endpoint to remove them. For more information, see [Remove a billable member from a group](https://docs.gitlab.com/api/group_members/#remove-a-billable-group-member) . DELETE /projects/:id/members/:user_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `user_id` | integer | yes | The user ID of the member. | | `skip_subresources` | boolean | false | Whether the deletion of direct memberships of the removed member in subgroups and projects should be skipped. Default is `false`. | | `unassign_issuables` | boolean | false | Whether the removed member should be unassigned from any issues or merge requests inside a given project. Default is `false`. | Example request: curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/:id/members/:user_id" --- # Project repository storage moves API | GitLab Docs * * * Project repository storage moves API ==================================== * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Project repositories including wiki and design repositories can be moved between storages. This API can help you when [migrating to Gitaly Cluster (Praefect)](https://docs.gitlab.com/administration/gitaly/praefect/#migrate-to-gitaly-cluster-praefect) , for example. As project repository storage moves are processed, they transition through different states. Values of `state` are: * `initial`: The record has been created but the background job has not yet been scheduled. * `scheduled`: The background job has been scheduled. * `started`: The project repositories are being copied to the destination storage. * `replicated`: The project has been moved. * `failed`: The project repositories failed to copy or the checksums did not match. * `finished`: The project has been moved and the repositories on the source storage have been deleted. * `cleanup failed`: The project has been moved but the repositories on the source storage could not be deleted. To ensure data integrity, projects are put in a temporary read-only state for the duration of the move. During this time, users receive a `The repository is temporarily read-only. Please try again later.` message if they try to push new commits. This API requires you to [authenticate yourself](https://docs.gitlab.com/api/rest/authentication/) as an administrator. For other repository types see: * [Snippet repository storage moves API](https://docs.gitlab.com/api/snippet_repository_storage_moves/) . * [Group repository storage moves API](https://docs.gitlab.com/api/group_repository_storage_moves/) . List all project repository storage moves ----------------------------------------- GET /project_repository_storage_moves By default, `GET` requests return 20 results at a time because the API results are [paginated](https://docs.gitlab.com/api/rest/#pagination) . Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/project_repository_storage_moves" Example response: [\ {\ "id": 1,\ "created_at": "2020-05-07T04:27:17.234Z",\ "state": "scheduled",\ "source_storage_name": "default",\ "destination_storage_name": "storage2",\ "project": {\ "id": 1,\ "description": null,\ "name": "project1",\ "name_with_namespace": "John Doe2 / project1",\ "path": "project1",\ "path_with_namespace": "namespace1/project1",\ "created_at": "2020-05-07T04:27:17.016Z"\ }\ }\ ] List all repository storage moves for a project ----------------------------------------------- GET /projects/:project_id/repository_storage_moves By default, `GET` requests return 20 results at a time because the API results are [paginated](https://docs.gitlab.com/api/rest/#pagination) . Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `project_id` | integer | yes | ID of the project | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/repository_storage_moves" Example response: [\ {\ "id": 1,\ "created_at": "2020-05-07T04:27:17.234Z",\ "state": "scheduled",\ "source_storage_name": "default",\ "destination_storage_name": "storage2",\ "project": {\ "id": 1,\ "description": null,\ "name": "project1",\ "name_with_namespace": "John Doe2 / project1",\ "path": "project1",\ "path_with_namespace": "namespace1/project1",\ "created_at": "2020-05-07T04:27:17.016Z"\ }\ }\ ] Retrieve a project repository storage move ------------------------------------------ GET /project_repository_storage_moves/:repository_storage_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `repository_storage_id` | integer | yes | ID of the project repository storage move | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/project_repository_storage_moves/1" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "project": { "id": 1, "description": null, "name": "project1", "name_with_namespace": "John Doe2 / project1", "path": "project1", "path_with_namespace": "namespace1/project1", "created_at": "2020-05-07T04:27:17.016Z" } } Retrieve a repository storage move for a project ------------------------------------------------ GET /projects/:project_id/repository_storage_moves/:repository_storage_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `project_id` | integer | yes | ID of the project | | `repository_storage_id` | integer | yes | ID of the project repository storage move | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/repository_storage_moves/1" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "project": { "id": 1, "description": null, "name": "project1", "name_with_namespace": "John Doe2 / project1", "path": "project1", "path_with_namespace": "namespace1/project1", "created_at": "2020-05-07T04:27:17.016Z" } } Create a repository storage move for a project ---------------------------------------------- POST /projects/:project_id/repository_storage_moves Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `project_id` | integer | yes | ID of the project | | `destination_storage_name` | string | no | Name of the destination storage shard. The storage is selected [automatically based on storage weights](https://docs.gitlab.com/administration/repository_storage_paths/#configure-where-new-repositories-are-stored)
if not provided | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"destination_storage_name":"storage2"}' \ --url "https://gitlab.example.com/api/v4/projects/1/repository_storage_moves" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "project": { "id": 1, "description": null, "name": "project1", "name_with_namespace": "John Doe2 / project1", "path": "project1", "path_with_namespace": "namespace1/project1", "created_at": "2020-05-07T04:27:17.016Z" } } Create repository storage moves for all projects on a storage shard ------------------------------------------------------------------- Creates repository storage moves for each project repository stored on the source storage shard. This endpoint migrates all projects at once. POST /project_repository_storage_moves Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `source_storage_name` | string | yes | Name of the source storage shard. | | `destination_storage_name` | string | no | Name of the destination storage shard. The storage is selected [automatically based on storage weights](https://docs.gitlab.com/administration/repository_storage_paths/#configure-where-new-repositories-are-stored)
if not provided. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"default"}' \ --url "https://gitlab.example.com/api/v4/project_repository_storage_moves" Example response: { "message": "202 Accepted" } Related topics -------------- * [Moving repositories managed by GitLab](https://docs.gitlab.com/administration/operations/moving_repositories/) --- # Group import and export API | GitLab Docs * * * Group import and export API =========================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to [migrate a group structure](https://docs.gitlab.com/user/group/import/) . When you use this API with the [project import and export API](https://docs.gitlab.com/api/project_import_export/) , you can preserve group-level relationships, such as connections between project issues and group epics. Group exports include the following: * Group milestones * Group boards * Group labels * Group badges * Group members * Group events * Group wikis (Premium and Ultimate only) * Subgroups. Each subgroup includes all previous data in the list. To preserve group-level relationships from imported projects, you should run group export and import first. This way, you can import project exports into the desired group structure. Because of [issue 405168](https://gitlab.com/gitlab-org/gitlab/-/issues/405168) , imported groups have a `private` visibility level unless you import them into a parent group. By default, if you import groups into a parent group, the subgroups inherit the same level of visibility as the parent. To preserve the member list and their respective permissions on imported groups, review the users in these groups. Make sure these users exist before importing the desired groups. Create a group export --------------------- Creates a group export for a specified group. POST /groups/:id/export | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | Integer or string | Yes | ID of the group. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/export" { "message": "202 Accepted" } Retrieve a group export download -------------------------------- Retrieves the exported archive for a specified group. GET /groups/:id/export/download | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | Integer or string | Yes | ID of the group. | group=1 token=secret curl --request GET \ --header "PRIVATE-TOKEN: ${token}" \ --output download_group_${group}.tar.gz \ --url "https://gitlab.example.com/api/v4/groups/${group}/export/download" ls *export.tar.gz 2020-12-05_22-11-148_namespace_export.tar.gz Time spent on exporting a group might vary depending on a size of the group. This endpoint returns either: * The exported archive (when available) * A 404 message Create a group import --------------------- Creates a group import by uploading a file. The maximum import file size can be set by the Administrator on GitLab Self-Managed (default is `0` (unlimited)). As an administrator, you can modify the maximum import file size either: * In the [**Admin** area](https://docs.gitlab.com/administration/settings/import_and_export_settings/) . * By using the `max_import_size` option in the [application settings API](https://docs.gitlab.com/api/settings/#update-application-settings) . For information on the maximum import file size on GitLab.com, see [account and limit settings](https://docs.gitlab.com/user/gitlab_com/#account-and-limit-settings) . POST /groups/import | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `file` | String | Yes | The file to be uploaded. | | `name` | String | Yes | The name of the group to be imported. | | `path` | String | Yes | Name and path for new group. | | `parent_id` | Integer | No | ID of a parent group to import the group into. Defaults to the current user’s namespace if not provided. | To upload a file from your file system, use the `--form` argument. This causes cURL to post data using the header `Content-Type: multipart/form-data`. The `file=` parameter must point to a file on your file system and be preceded by `@`. For example: curl --request POST \ --header "PRIVATE-TOKEN: " \ --form "name=imported-group" \ --form "path=imported-group" \ --form "file=@/path/to/file" \ --url "https://gitlab.example.com/api/v4/groups/import" Related topics -------------- * [Project import and export API](https://docs.gitlab.com/api/project_import_export/) --- # SAML API | GitLab Docs * * * SAML API ======== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227841) in GitLab 15.5. Use this API to interact with SAML features. GitLab.com endpoints -------------------- ### List all SAML identities for a group GET /groups/:id/saml/identities Lists all the SAML identities for a group. Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `extern_uid` | string | External UID for the user | | `user_id` | string | ID for the user | Example request: curl --location --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.com/api/v4/groups/33/saml/identities" Example response: [\ {\ "extern_uid": "yrnZW46BrtBFqM7xDzE7dddd",\ "user_id": 48\ }\ ] ### Retrieve a single SAML identity History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123591) in GitLab 16.1. Retrieves a single SAML identity. GET /groups/:id/saml/:uid Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `uid` | string | yes | External UID of the user. | Example request: curl --location --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.com/api/v4/groups/33/saml/yrnZW46BrtBFqM7xDzE7dddd" Example response: { "extern_uid": "yrnZW46BrtBFqM7xDzE7dddd", "user_id": 48 } ### Update `extern_uid` field for a SAML identity Updates `extern_uid` field for a SAML identity: | SAML IdP attribute | GitLab field | | --- | --- | | `id/externalId` | `extern_uid` | PATCH /groups/:id/saml/:uid Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `uid` | string | yes | External UID of the user. | Example request: curl --request PATCH \ --location \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.com/api/v4/groups/33/saml/yrnZW46BrtBFqM7xDzE7dddd" \ --form "extern_uid=be20d8dcc028677c931e04f387" ### Delete a single SAML identity History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/423592) in GitLab 16.5. DELETE /groups/:id/saml/:uid Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `uid` | string | yes | External UID of the user. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.com/api/v4/groups/33/saml/be20d8dcc028677c931e04f387" Example response: { "message" : "204 No Content" } GitLab Self-Managed endpoints ----------------------------- ### Retrieve a single SAML identity Uses the Users API to [get a single SAML identity](https://docs.gitlab.com/api/users/#as-an-administrator) . ### Update `extern_uid` field for a SAML identity Uses the Users API to [update the `extern_uid` field of a user](https://docs.gitlab.com/api/users/#modify-a-user) . ### Delete a single SAML identity Uses the Users API to [delete a single identity of a user](https://docs.gitlab.com/api/users/#delete-authentication-identity-from-a-user) . SAML group links ---------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/290367) in GitLab 15.3.0. * `access_level` type [changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95607) from `string` to `integer` in GitLab 15.3.3. * `member_role_id` type [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/417201) in GitLab 16.7 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `custom_roles_for_saml_group_links`. Disabled by default. * `member_role_id` type [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/417201) in GitLab 16.8. Feature flag `custom_roles_for_saml_group_links` removed. * `provider` parameter [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/548725) in GitLab 18.2. List, get, add, and delete [SAML group links](https://docs.gitlab.com/user/group/saml_sso/group_sync/#configure-saml-group-links) by using the REST API. ### List all SAML group links Lists all SAML group links for a group. GET /groups/:id/saml_group_links Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `[].name` | string | Name of the SAML group. | | `[].access_level` | integer | The default access level for members of the SAML group. Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). | | `[].member_role_id` | integer | [Member Role ID (`member_role_id`)](https://docs.gitlab.com/api/member_roles/)
for members of the SAML group. | | `[].provider` | string | Unique [provider name](https://docs.gitlab.com/integration/saml/#configure-saml-support-in-gitlab)
that must match for this group link to be applied. | Example request: curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/saml_group_links" Example response: [\ {\ "name": "saml-group-1",\ "access_level": 10,\ "member_role_id": 12,\ "provider": null\ },\ {\ "name": "saml-group-2",\ "access_level": 40,\ "member_role_id": 99,\ "provider": "saml_provider_1"\ }\ ] ### Retrieve a SAML group link Retrieves a SAML group link for a group. GET /groups/:id/saml_group_links/:saml_group_name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `saml_group_name` | string | yes | Name of the SAML group. | | `provider` | string | no | Unique [provider name](https://docs.gitlab.com/integration/saml/#configure-saml-support-in-gitlab)
to disambiguate when multiple links exist with the same name. Required when multiple links exist with the same `saml_group_name`. | If successful, returns [`200`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `name` | string | Name of the SAML group. | | `access_level` | integer | The default access level for members of the SAML group. Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). | | `member_role_id` | integer | [Member Role ID (`member_role_id`)](https://docs.gitlab.com/api/member_roles/)
for members of the SAML group. | | `provider` | string | Unique [provider name](https://docs.gitlab.com/integration/saml/#configure-saml-support-in-gitlab)
that must match for this group link to be applied. | If multiple SAML group links exist with the same name but different providers, and no `provider` parameter is specified, returns [`422`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) with an error message indicating that the `provider` parameter is required to disambiguate. Example request: curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/saml_group_links/saml-group-1" Example request with provider parameter: curl \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/saml_group_links/saml-group-1?provider=saml_provider_1" Example response: { "name": "saml-group-1", "access_level": 10, "member_role_id": 12, "provider": "saml_provider_1" } ### Add a SAML group link Adds a SAML group link for a group. POST /groups/:id/saml_group_links Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `saml_group_name` | string | yes | Name of the SAML group. | | `access_level` | integer | yes | The default access level for members of the SAML group. Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). | | `member_role_id` | integer | no | [Member Role ID (`member_role_id`)](https://docs.gitlab.com/api/member_roles/)
for members of the SAML group. | | `provider` | string | no | Unique [provider name](https://docs.gitlab.com/integration/saml/#configure-saml-support-in-gitlab)
that must match for this group link to be applied. | If successful, returns [`201`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `name` | string | Name of the SAML group. | | `access_level` | integer | The default access level for members of the SAML group. Possible values: `0` (No access), `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). | | `member_role_id` | integer | [Member Role ID (`member_role_id`)](https://docs.gitlab.com/api/member_roles/)
for members of the SAML group. | | `provider` | string | Unique [provider name](https://docs.gitlab.com/integration/saml/#configure-saml-support-in-gitlab)
that must match for this group link to be applied. | Example request: curl --request POST --header "PRIVATE-TOKEN: " --header "Content-Type: application/json" --data '{ "saml_group_name": "", "access_level": , "member_role_id": , "provider": "" }' --url "https://gitlab.example.com/api/v4/groups/1/saml_group_links" Example response: { "name": "saml-group-1", "access_level": 10, "member_role_id": 12, "provider": "saml_provider_1" } ### Delete a SAML group link Delete a SAML group link for a group. DELETE /groups/:id/saml_group_links/:saml_group_name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `saml_group_name` | string | yes | Name of the SAML group. | | `provider` | string | no | Unique [provider name](https://docs.gitlab.com/integration/saml/#configure-saml-support-in-gitlab)
to disambiguate when multiple links exist with the same name. Required when multiple links exist with the same `saml_group_name`. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/saml_group_links/saml-group-1" Example request with provider parameter: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/1/saml_group_links/saml-group-1?provider=saml_provider_1" If successful, returns [`204`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) status code without any response body. If multiple SAML group links exist with the same name but different providers, and no `provider` parameter is specified, returns [`422`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) with an error message indicating that the `provider` parameter is required to disambiguate. --- # Group webhooks API | GitLab Docs * * * Group webhooks API ================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [group webhooks](https://docs.gitlab.com/user/project/integrations/webhooks/#group-webhooks) . Group webhooks are different from [system hooks](https://docs.gitlab.com/api/system_hooks/) that impact the entire instance, and [project webhooks](https://docs.gitlab.com/api/project_webhooks/) that are limited to a single project. Prerequisites: * You must be an Administrator or have the Owner role for the group. List all group hooks -------------------- Lists all group hooks for a specified group. GET /groups/:id/hooks Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks" Example response: [\ {\ "id": 1,\ "url": "http://example.com/hook",\ "name": "Test group hook",\ "description": "This is a test group hook.",\ "created_at": "2024-09-01T09:10:54.854Z",\ "push_events": true,\ "tag_push_events": false,\ "merge_requests_events": false,\ "repository_update_events": false,\ "enable_ssl_verification": true,\ "alert_status": "executable",\ "disabled_until": null,\ "url_variables": [],\ "push_events_branch_filter": null,\ "branch_filter_strategy": "all_branches",\ "group_id": 99,\ "issues_events": false,\ "confidential_issues_events": false,\ "note_events": false,\ "confidential_note_events": false,\ "pipeline_events": false,\ "wiki_page_events": false,\ "job_events": false,\ "deployment_events": false,\ "feature_flag_events": false,\ "releases_events": false,\ "milestone_events": false,\ "subgroup_events": false,\ "emoji_events": false,\ "resource_access_token_events": false,\ "member_events": false,\ "project_events": false,\ "custom_webhook_template": "{\"event\":\"{{object_kind}}\"}",\ "custom_headers": [\ {\ "key": "Authorization"\ }\ ]\ }\ ] Retrieve a group hook --------------------- Retrieves a specified group hook. GET /groups/:id/hooks/:hook_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `hook_id` | integer | yes | The ID of a group hook. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1" Example response: { "id": 1, "url": "http://example.com/hook", "name": "Hook name", "description": "Hook description", "group_id": 3, "push_events": true, "push_events_branch_filter": "", "branch_filter_strategy": "wildcard", "issues_events": true, "confidential_issues_events": true, "merge_requests_events": true, "tag_push_events": true, "note_events": true, "confidential_note_events": true, "job_events": true, "pipeline_events": true, "wiki_page_events": true, "deployment_events": true, "feature_flag_events": false, "releases_events": true, "milestone_events": false, "subgroup_events": true, "member_events": true, "project_events": true, "enable_ssl_verification": true, "repository_update_events": false, "alert_status": "executable", "disabled_until": null, "url_variables": [ ], "created_at": "2012-10-12T17:04:47Z", "resource_access_token_events": true, "custom_webhook_template": "{\"event\":\"{{object_kind}}\"}", "custom_headers": [\ {\ "key": "Authorization"\ }\ ] } List all group hook events -------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151048) in GitLab 17.3. Lists all events for a specified group hook in the past seven days from the start date. GET /groups/:id/hooks/:hook_id/events Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of a project hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `page` | Integer | No | Page to retrieve. Defaults to `1`. | | `per_page` | Integer | No | Number of records to return per page. Defaults to `20`. | | `status` | Integer or string | No | The response status code of the events, for example: `200` or `500`. You can search by status category: `successful` (200-299), `client_failure` (400-499), and `server_failure` (500-599). | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1/events" Example response: [\ {\ "id": 1,\ "url": "https://example.net/",\ "trigger": "push_hooks",\ "request_headers": {\ "Content-Type": "application/json",\ "User-Agent": "GitLab/17.1.0-pre",\ "Idempotency-Key": "a5461c4d-9c7f-4af9-add6-cddebe3c426f",\ "X-Gitlab-Event": "Push Hook",\ "X-Gitlab-Webhook-UUID": "3c5c0404-c866-44bc-a5f6-452bb1bfc76e",\ "X-Gitlab-Instance": "https://gitlab.example.com",\ "X-Gitlab-Event-UUID": "9cebe914-4827-408f-b014-cfa23a47a35f",\ "X-Gitlab-Token": "[REDACTED]"\ },\ "request_data": {\ "object_kind": "push",\ "event_name": "push",\ "after": "f15b32277d2c55c6c595845a87109b09c913c556",\ "ref": "refs/heads/master",\ "ref_protected": true,\ "checkout_sha": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": null,\ "user_id": 1,\ "user_name": "Administrator",\ "user_username": "root",\ "user_email": null,\ "user_avatar": "https://www.gravatar.com/avatar/13efe0d4559475ba84ecc802061febbdea6e224fcbffd7ec7da9cd431845299c?s=80&d=identicon",\ "project_id": 7,\ "project": {\ "id": 7,\ "name": "Flight",\ "description": "Incidunt ea ab officia a veniam.",\ "web_url": "https://gitlab.example.com/flightjs/Flight",\ "avatar_url": null,\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "namespace": "Flightjs",\ "visibility_level": 10,\ "path_with_namespace": "flightjs/Flight",\ "default_branch": "master",\ "ci_config_path": null,\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "http_url": "https://gitlab.example.com/flightjs/Flight.git"\ },\ "commits": [\ {\ "id": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": "v1.5.2\n",\ "title": "v1.5.2",\ "timestamp": "2017-06-19T14:39:53-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/f15b32277d2c55c6c595845a87109b09c913c556",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "message": "Merge pull request #378 from flightjs/alunny/publish_lib\n\npublish lib and index to npm",\ "title": "Merge pull request #378 from flightjs/alunny/publish_lib",\ "timestamp": "2017-06-16T10:26:39-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "author": {\ "name": "angus croll",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "468abc807a2b2572f43e72c743b76cee6db24025",\ "message": "publish lib and index to npm\n",\ "title": "publish lib and index to npm",\ "timestamp": "2017-06-16T10:23:04-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/468abc807a2b2572f43e72c743b76cee6db24025",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ }\ ],\ "total_commits_count": 3,\ "push_options": {},\ "repository": {\ "name": "Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "description": "Incidunt ea ab officia a veniam.",\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "visibility_level": 10\ }\ },\ "response_headers": {\ "Date": "Sun, 26 May 2024 03:03:17 GMT",\ "Content-Type": "application/json; charset=utf-8",\ "Content-Length": "16",\ "Connection": "close",\ "X-Powered-By": "Express",\ "Access-Control-Allow-Origin": "*",\ "X-Pd-Status": "sent to primary"\ },\ "response_body": "{\"success\":true}",\ "execution_duration": 1.0906479999999874,\ "response_status": "200"\ },\ {\ "id": 2,\ "url": "https://example.net/",\ "trigger": "push_hooks",\ "request_headers": {\ "Content-Type": "application/json",\ "User-Agent": "GitLab/17.1.0-pre",\ "Idempotency-Key": "1f0a54f0-0529-408d-a5b8-a2a98ff5f94a",\ "X-Gitlab-Event": "Push Hook",\ "X-Gitlab-Webhook-UUID": "a753eedb-1d72-4549-9ca7-eac8ea8e50dd",\ "X-Gitlab-Instance": "https://gitlab.example.com:3000",\ "X-Gitlab-Event-UUID": "842d7c3e-3114-4396-8a95-66c084d53cb1",\ "X-Gitlab-Token": "[REDACTED]"\ },\ "request_data": {\ "object_kind": "push",\ "event_name": "push",\ "before": "468abc807a2b2572f43e72c743b76cee6db24025",\ "after": "f15b32277d2c55c6c595845a87109b09c913c556",\ "ref": "refs/heads/master",\ "ref_protected": true,\ "checkout_sha": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": null,\ "user_id": 1,\ "user_name": "Administrator",\ "user_username": "root",\ "user_email": null,\ "user_avatar": "https://www.gravatar.com/avatar/13efe0d4559475ba84ecc802061febbdea6e224fcbffd7ec7da9cd431845299c?s=80&d=identicon",\ "project_id": 7,\ "project": {\ "id": 7,\ "name": "Flight",\ "description": "Incidunt ea ab officia a veniam.",\ "web_url": "https://gitlab.example.com/flightjs/Flight",\ "avatar_url": null,\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "namespace": "Flightjs",\ "visibility_level": 10,\ "path_with_namespace": "flightjs/Flight",\ "default_branch": "master",\ "ci_config_path": null,\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "http_url": "https://gitlab.example.com/flightjs/Flight.git"\ },\ "commits": [\ {\ "id": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": "v1.5.2\n",\ "title": "v1.5.2",\ "timestamp": "2017-06-19T14:39:53-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/f15b32277d2c55c6c595845a87109b09c913c556",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "message": "Merge pull request #378 from flightjs/alunny/publish_lib\n\npublish lib and index to npm",\ "title": "Merge pull request #378 from flightjs/alunny/publish_lib",\ "timestamp": "2017-06-16T10:26:39-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "author": {\ "name": "angus croll",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "468abc807a2b2572f43e72c743b76cee6db24025",\ "message": "publish lib and index to npm\n",\ "title": "publish lib and index to npm",\ "timestamp": "2017-06-16T10:23:04-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/468abc807a2b2572f43e72c743b76cee6db24025",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ }\ ],\ "total_commits_count": 3,\ "push_options": {},\ "repository": {\ "name": "Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "description": "Incidunt ea ab officia a veniam.",\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "visibility_level": 10\ }\ },\ "response_headers": {\ "Date": "Sun, 26 May 2024 03:03:19 GMT",\ "Content-Type": "application/json; charset=utf-8",\ "Content-Length": "16",\ "Connection": "close",\ "X-Powered-By": "Express",\ "Access-Control-Allow-Origin": "*",\ "X-Pd-Status": "sent to primary"\ },\ "response_body": "{\"success\":true}",\ "execution_duration": 1.0716120000000728,\ "response_status": "200"\ }\ ] ### Resend group hook event History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151130) in GitLab 17.4. Resends a specific hook event. This endpoint has a rate limit of five requests per minute for each hook and authenticated user. To disable this limit on GitLab Self-Managed and GitLab Dedicated, an administrator can [disable the feature flag](https://docs.gitlab.com/administration/feature_flags/) named `web_hook_event_resend_api_endpoint_rate_limit`. POST /groups/:id/hooks/:hook_id/events/:hook_event_id/resend Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_event_id` | Integer | Yes | The ID of a hook event. | | `hook_id` | Integer | Yes | The ID of a group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1/events/1/resend" Example response: { "response_status": 200 } Create a group hook ------------------- Creates a group hook for a specified group. POST /groups/:id/hooks Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `url` | String | Yes | The hook URL. | | `branch_filter_strategy` | String | No | Filter push events by branch. Possible values are `wildcard` (default), `regex`, and `all_branches`. | | `confidential_issues_events` | Boolean | No | Trigger hook on confidential issue events. | | `confidential_note_events` | Boolean | No | Trigger hook on confidential note events. | | `custom_headers` | Array | No | Custom headers for the hook. | | `custom_webhook_template` | String | No | Custom webhook template for the hook. | | `deployment_events` | Boolean | No | Trigger hook on deployment events. | | `description` | String | No | Description of the hook ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887)
in GitLab 17.1). | | `enable_ssl_verification` | Boolean | No | Do SSL verification when triggering the hook. | | `feature_flag_events` | Boolean | No | Trigger hook on feature flag events. | | `issues_events` | Boolean | No | Trigger hook on issue events. | | `job_events` | Boolean | No | Trigger hook on job events. | | `member_events` | Boolean | No | Trigger hook on member events. | | `merge_requests_events` | Boolean | No | Trigger hook on merge request events. | | `milestone_events` | Boolean | No | Trigger hook on milestone events. | | `name` | String | No | Name of the hook ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887)
in GitLab 17.1). | | `note_events` | Boolean | No | Trigger hook on note events. | | `pipeline_events` | Boolean | No | Trigger hook on pipeline events. | | `project_events` | Boolean | No | Trigger hook on project events. | | `push_events` | Boolean | No | Trigger hook on push events. | | `push_events_branch_filter` | String | No | Trigger hook on push events for matching branches only. | | `releases_events` | Boolean | No | Trigger hook on release events. | | `resource_access_token_events` | Boolean | No | Trigger hook on project access token expiry events. | | `subgroup_events` | Boolean | No | Trigger hook on subgroup events. | | `tag_push_events` | Boolean | No | Trigger hook on tag push events. | | `token` | String | No | Secret token to validate received payloads; not returned in the response. | | `wiki_page_events` | Boolean | No | Trigger hook on wiki page events. | Example request: curl --request POST \ --header "content-type: application/json" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks" \ --data '{"url": "https://example.com/hook", "name": "My Hook", "description": "Hook description"}' Example response: { "id": 42, "url": "https://example.com/hook", "name": "My Hook", "description": "Hook description", "group_id": 3, "push_events": true, "push_events_branch_filter": "", "branch_filter_strategy": "wildcard", "issues_events": true, "confidential_issues_events": true, "merge_requests_events": true, "tag_push_events": true, "note_events": true, "confidential_note_events": true, "job_events": true, "pipeline_events": true, "wiki_page_events": true, "deployment_events": true, "feature_flag_events": true, "releases_events": true, "milestone_events": true, "subgroup_events": true, "member_events": true, "project_events": true, "enable_ssl_verification": true, "repository_update_events": false, "alert_status": "executable", "disabled_until": null, "url_variables": [ ], "created_at": "2012-10-12T17:04:47Z", "resource_access_token_events": true, "custom_webhook_template": "{\"event\":\"{{object_kind}}\"}", } Update a group hook ------------------- Updates a group hook for a specified group. PUT /groups/:id/hooks/:hook_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of the group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `url` | String | Yes | The hook URL. | | `branch_filter_strategy` | String | No | Filter push events by branch. Possible values are `wildcard` (default), `regex`, and `all_branches`. | | `confidential_issues_events` | Boolean | No | Trigger hook on confidential issue events. | | `confidential_note_events` | Boolean | No | Trigger hook on confidential note events. | | `custom_headers` | Array | No | Custom headers for the hook. | | `custom_webhook_template` | String | No | Custom webhook template for the hook. | | `deployment_events` | Boolean | No | Trigger hook on deployment events. | | `description` | String | No | Description of the hook ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887)
in GitLab 17.1). | | `enable_ssl_verification` | Boolean | No | Do SSL verification when triggering the hook. | | `feature_flag_events` | Boolean | No | Trigger hook on feature flag events. | | `issues_events` | Boolean | No | Trigger hook on issue events. | | `job_events` | Boolean | No | Trigger hook on job events. | | `member_events` | Boolean | No | Trigger hook on member events. | | `merge_requests_events` | Boolean | No | Trigger hook on merge request events. | | `milestone_events` | Boolean | No | Trigger hook on milestone events. | | `name` | String | No | Name of the hook ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887)
in GitLab 17.1). | | `note_events` | Boolean | No | Trigger hook on note events. | | `pipeline_events` | Boolean | No | Trigger hook on pipeline events. | | `project_events` | Boolean | No | Trigger hook on project events. | | `push_events` | Boolean | No | Trigger hook on push events. | | `push_events_branch_filter` | String | No | Trigger hook on push events for matching branches only. | | `releases_events` | Boolean | No | Trigger hook on release events. | | `resource_access_token_events` | Boolean | No | Trigger hook on project access token expiry events. | | `service_access_tokens_expiration_enforced` | Boolean | No | Require service account access tokens to have an expiration date. | | `subgroup_events` | Boolean | No | Trigger hook on subgroup events. | | `tag_push_events` | Boolean | No | Trigger hook on tag push events. | | `token` | String | No | Secret token to validate received payloads. Not returned in the response. When you change the webhook URL, the secret token is reset and not retained. | | `wiki_page_events` | Boolean | No | Trigger hook on wiki page events. | Example request: curl --request POST \ --header "content-type: application/json" \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1" \ --data '{"url": "https://example.com/hook", "name": "New hook name", "description": "Changed hook description"}' Example response: { "id": 1, "url": "https://example.com/hook", "name": "New hook name", "description": "Changed hook description", "group_id": 3, "push_events": true, "push_events_branch_filter": "", "branch_filter_strategy": "wildcard", "issues_events": true, "confidential_issues_events": true, "merge_requests_events": true, "tag_push_events": true, "note_events": true, "confidential_note_events": true, "job_events": true, "pipeline_events": true, "wiki_page_events": true, "deployment_events": true, "feature_flag_events": true, "releases_events": true, "milestone_events": true, "subgroup_events": true, "member_events": true, "project_events": true, "enable_ssl_verification": true, "repository_update_events": false, "alert_status": "executable", "disabled_until": null, "url_variables": [ ], "created_at": "2012-10-12T17:04:47Z", "resource_access_token_events": true, "custom_webhook_template": "{\"event\":\"{{object_kind}}\"}", "custom_headers": [\ {\ "key": "Authorization"\ }\ ] } Delete a group hook ------------------- Deletes a specified group hook. This is an idempotent method and can be called multiple times. Either the hook is available or not. DELETE /groups/:id/hooks/:hook_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of the group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1" On success, no message is returned. Trigger a test group hook ------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/455589) in GitLab 17.1. * Special rate limit [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150486) in GitLab 17.1 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `web_hook_test_api_endpoint_rate_limit`. Enabled by default. Trigger a test hook for a specified group. This endpoint has a rate limit of five requests per minute for each group and authenticated user. To disable this limit on GitLab Self-Managed and GitLab Dedicated, an administrator can [disable the feature flag](https://docs.gitlab.com/administration/feature_flags/) named `web_hook_test_api_endpoint_rate_limit`. POST /groups/:id/hooks/:hook_id/test/:trigger | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of the group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `trigger` | String | Yes | One of `push_events`, `tag_push_events`, `issues_events`, `confidential_issues_events`, `note_events`, `merge_requests_events`, `job_events`, `pipeline_events`, `wiki_page_events`, `releases_events`, `milestone_events`, `emoji_events`, or `resource_access_token_events`. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1/test/push_events" Example response: {"message":"201 Created"} Update a custom header ---------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153768) in GitLab 17.1. Updates a custom header for a specified group hook. PUT /groups/:id/hooks/:hook_id/custom_headers/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of the group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | String | Yes | The key of the custom header. | | `value` | String | Yes | The value of the custom header. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1/custom_headers/header_key?value='header_value'" On success, no message is returned. Delete a custom header ---------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153768) in GitLab 17.1. Deletes a custom header. DELETE /groups/:id/hooks/:hook_id/custom_headers/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of the group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | String | Yes | The key of the custom header. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1/custom_headers/header_key" On success, no message is returned. Update a URL variable --------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90310) in GitLab 15.2. Updates a URL variable for a specified group hook. PUT /groups/:id/hooks/:hook_id/url_variables/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of the group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | String | Yes | The key of the URL variable. | | `value` | String | Yes | The value of the URL variable. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1/url_variables/my_key?value='my_key_value'" On success, no message is returned. Delete a URL variable --------------------- Deletes a URL variable for a specified group hook. DELETE /groups/:id/hooks/:hook_id/url_variables/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | Integer | Yes | The ID of the group hook. | | `id` | Integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `key` | String | Yes | The key of the URL variable. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/3/hooks/1/url_variables/my_key" On success, no message is returned. --- # Group and project migration by direct transfer API | GitLab Docs * * * Group and project migration by direct transfer API ================================================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to migrate groups and projects by using [direct transfer](https://docs.gitlab.com/user/group/import/direct_transfer_migrations/) . Prerequisites: * See [prerequisites for migrating groups by direct transfer](https://docs.gitlab.com/user/group/import/direct_transfer_migrations/#prerequisites) . Start a group or project migration ---------------------------------- Starts a new group or project migration. To migrate a project, specify `entities[project_entity]`. POST /bulk_imports | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `configuration` | Hash | Yes | The source GitLab instance configuration. | | `configuration[url]` | String | Yes | Source GitLab instance URL. | | `configuration[access_token]` | String | Yes | Access token to the source GitLab instance. | | `entities` | Array | Yes | List of entities to import. | | `entities[source_type]` | String | Yes | Source entity type. Valid values are `group_entity` and `project_entity`. | | `entities[source_full_path]` | String | Yes | Source full path of the entity to import. For example, `gitlab-org/gitlab`. | | `entities[destination_slug]` | String | Yes | Destination slug for the entity. GitLab uses the slug as the URL path to the entity. The name of the imported entity is copied from the name of the source entity and not the slug. | | `entities[destination_namespace]` | String | Yes | Full path of the destination group [namespace](https://docs.gitlab.com/user/namespace/)
for the entity. For `project_entity`, this value must be an existing group on the destination instance. For `group_entity`, this value can be an existing group on the destination instance or an empty string `""` to create a top-level group on the destination instance (on GitLab Self-Managed and GitLab Dedicated). Personal namespaces are not supported. | | `entities[destination_name]` | String | No | Deprecated: Use `destination_slug` instead. Destination slug for the entity. | | `entities[migrate_memberships]` | Boolean | No | Import user memberships. Defaults to `true`. | | `entities[migrate_projects]` | Boolean | No | Also import all nested projects of the group (if `source_type` is `group_entity`). Defaults to `true`. | curl --request POST \ --url "https://destination-gitlab-instance.example.com/api/v4/bulk_imports" \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "configuration": { "url": "https://source-gitlab-instance.example.com", "access_token": "" }, "entities": [\ {\ "source_full_path": "source/full/path",\ "source_type": "group_entity",\ "destination_slug": "destination_slug",\ "destination_namespace": "destination/namespace/path"\ }\ ] }' { "id": 1, "status": "created", "source_type": "gitlab", "source_url": "https://gitlab.example.com", "created_at": "2021-06-18T09:45:55.358Z", "updated_at": "2021-06-18T09:46:27.003Z", "has_failures": false } List all group or project migrations ------------------------------------ Lists all group or project migrations. GET /bulk_imports | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `per_page` | integer | no | Number of records to return per page. | | `page` | integer | no | Page to retrieve. | | `sort` | string | no | Return records sorted in `asc` or `desc` order by creation date. Default is `desc` | | `status` | string | no | Import status. | The status can be one of the following: * `created` * `started` * `finished` * `failed` curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/bulk_imports?per_page=2&page=1" [\ {\ "id": 1,\ "status": "finished",\ "source_type": "gitlab",\ "source_url": "https://gitlab.example.com",\ "created_at": "2021-06-18T09:45:55.358Z",\ "updated_at": "2021-06-18T09:46:27.003Z",\ "has_failures": false\ },\ {\ "id": 2,\ "status": "started",\ "source_type": "gitlab",\ "source_url": "https://gitlab.example.com",\ "created_at": "2021-06-18T09:47:36.581Z",\ "updated_at": "2021-06-18T09:47:58.286Z",\ "has_failures": false\ }\ ] List all group or project migration entities -------------------------------------------- Lists all group or project migration entities. GET /bulk_imports/entities | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `per_page` | integer | no | Number of records to return per page. | | `page` | integer | no | Page to retrieve. | | `sort` | string | no | Return records sorted in `asc` or `desc` order by creation date. Default is `desc` | | `status` | string | no | Import status. | The status can be one of the following: * `created` * `started` * `finished` * `failed` curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/bulk_imports/entities?per_page=2&page=1&status=started" [\ {\ "id": 1,\ "bulk_import_id": 1,\ "status": "finished",\ "entity_type": "group",\ "source_full_path": "source_group",\ "destination_full_path": "destination/full_path",\ "destination_name": "destination_slug",\ "destination_slug": "destination_slug",\ "destination_namespace": "destination_path",\ "parent_id": null,\ "namespace_id": 1,\ "project_id": null,\ "created_at": "2021-06-18T09:47:37.390Z",\ "updated_at": "2021-06-18T09:47:51.867Z",\ "failures": [],\ "migrate_projects": true,\ "migrate_memberships": true,\ "has_failures": false,\ "stats": {\ "labels": {\ "source": 10,\ "fetched": 10,\ "imported": 10\ },\ "milestones": {\ "source": 10,\ "fetched": 10,\ "imported": 10\ }\ }\ },\ {\ "id": 2,\ "bulk_import_id": 2,\ "status": "failed",\ "entity_type": "group",\ "source_full_path": "another_group",\ "destination_full_path": "destination/full_path",\ "destination_name": "destination_slug",\ "destination_slug": "another_slug",\ "destination_namespace": "another_namespace",\ "parent_id": null,\ "namespace_id": null,\ "project_id": null,\ "created_at": "2021-06-24T10:40:20.110Z",\ "updated_at": "2021-06-24T10:40:46.590Z",\ "failures": [\ {\ "relation": "group",\ "step": "extractor",\ "exception_message": "Error!",\ "exception_class": "Exception",\ "correlation_id_value": "dfcf583058ed4508e4c7c617bd7f0edd",\ "created_at": "2021-06-24T10:40:46.495Z",\ "pipeline_class": "BulkImports::Groups::Pipelines::GroupPipeline",\ "pipeline_step": "extractor"\ }\ ],\ "migrate_projects": true,\ "migrate_memberships": true,\ "has_failures": false,\ "stats": { }\ }\ ] Retrieve a group or project migration ------------------------------------- Retrieves details of a group or project migration. GET /bulk_imports/:id curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/bulk_imports/1" { "id": 1, "status": "finished", "source_type": "gitlab", "source_url": "https://gitlab.example.com", "created_at": "2021-06-18T09:45:55.358Z", "updated_at": "2021-06-18T09:46:27.003Z" } List group or project migration entities ---------------------------------------- Lists group or project migration entities for a specific migration. GET /bulk_imports/:id/entities | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `per_page` | integer | no | Number of records to return per page. | | `page` | integer | no | Page to retrieve. | | `sort` | string | no | Return records sorted in `asc` or `desc` order by creation date. Default is `desc` | | `status` | string | no | Import status. | The status can be one of the following: * `created` * `started` * `finished` * `failed` curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/bulk_imports/1/entities?per_page=2&page=1&status=finished" [\ {\ "id": 1,\ "bulk_import_id": 1,\ "status": "finished",\ "entity_type": "group",\ "source_full_path": "source_group",\ "destination_full_path": "destination/full_path",\ "destination_name": "destination_slug",\ "destination_slug": "destination_slug",\ "destination_namespace": "destination_path",\ "parent_id": null,\ "namespace_id": 1,\ "project_id": null,\ "created_at": "2021-06-18T09:47:37.390Z",\ "updated_at": "2021-06-18T09:47:51.867Z",\ "failures": [\ {\ "relation": "group",\ "step": "extractor",\ "exception_message": "Error!",\ "exception_class": "Exception",\ "correlation_id_value": "dfcf583058ed4508e4c7c617bd7f0edd",\ "created_at": "2021-06-24T10:40:46.495Z",\ "pipeline_class": "BulkImports::Groups::Pipelines::GroupPipeline",\ "pipeline_step": "extractor"\ }\ ],\ "migrate_projects": true,\ "migrate_memberships": true,\ "has_failures": true,\ "stats": {\ "labels": {\ "source": 10,\ "fetched": 10,\ "imported": 10\ },\ "milestones": {\ "source": 10,\ "fetched": 10,\ "imported": 10\ }\ }\ }\ ] Retrieve a group or project migration entity -------------------------------------------- Retrieves details of a group or project migration entity. GET /bulk_imports/:id/entities/:entity_id curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/bulk_imports/1/entities/2" { "id": 1, "bulk_import_id": 1, "status": "finished", "entity_type": "group", "source_full_path": "source_group", "destination_full_path": "destination/full_path", "destination_name": "destination_slug", "destination_slug": "destination_slug", "destination_namespace": "destination_path", "parent_id": null, "namespace_id": 1, "project_id": null, "created_at": "2021-06-18T09:47:37.390Z", "updated_at": "2021-06-18T09:47:51.867Z", "failures": [\ {\ "relation": "group",\ "step": "extractor",\ "exception_message": "Error!",\ "exception_class": "Exception",\ "correlation_id_value": "dfcf583058ed4508e4c7c617bd7f0edd",\ "created_at": "2021-06-24T10:40:46.495Z",\ "pipeline_class": "BulkImports::Groups::Pipelines::GroupPipeline",\ "pipeline_step": "extractor"\ }\ ], "migrate_projects": true, "migrate_memberships": true, "has_failures": true, "stats": { "labels": { "source": 10, "fetched": 10, "imported": 10 }, "milestones": { "source": 10, "fetched": 10, "imported": 10 } } } List failed import records for a migration entity ------------------------------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/428016) in GitLab 16.6. Lists failed import records for a group or project migration entity. GET /bulk_imports/:id/entities/:entity_id/failures curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/bulk_imports/1/entities/2/failures" { "relation": "issues", "exception_message": "Error!", "exception_class": "StandardError", "correlation_id_value": "06289e4b064329a69de7bb2d7a1b5a97", "source_url": "https://gitlab.example/project/full/path/-/issues/1", "source_title": "Issue title" } Cancel a migration ------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/438281) in GitLab 17.1. Cancels a direct transfer migration. POST /bulk_imports/:id/cancel curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/bulk_imports/1/cancel" { "id": 1, "status": "canceled", "source_type": "gitlab", "created_at": "2021-06-18T09:45:55.358Z", "updated_at": "2021-06-18T09:46:27.003Z", "has_failures": false } Possible response status codes: | Status | Description | | --- | --- | | 200 | Migration successfully canceled | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Migration not found | | 503 | Service unavailable | --- # Retrieve GitLab Duo and SDLC trend data | GitLab Docs * * * Retrieve GitLab Duo and SDLC trend data ======================================= * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use the GraphQL API to retrieve and export GitLab Duo data. Retrieve AI usage data ---------------------- * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/474469) in GitLab 17.5 with a flag named `code_suggestions_usage_events_in_pg`. Disabled by default. * Feature flag `move_ai_tracking_to_instrumentation_layer` [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/167415) in GitLab 17.7. Disabled by default. * Dependency on `move_ai_tracking_to_instrumentation_layer` [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179527) in GitLab 17.8. * Feature flag `code_suggestions_usage_events_in_pg` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/486469) in GitLab 17.8. * GitLab Duo Enterprise add-on requirement for `AiUsageData` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/580174) in GitLab 18.7. The `AiUsageData` endpoint provides raw event data. It exposes Code Suggestions-specific events through `codeSuggestionEvents` and all raw event data through `all`. On earlier versions with GitLab Duo Pro, the `AiUsageData` endpoint returns `null` without an error message. You can use this endpoint to import events into a BI tool or write scripts that aggregate the data, acceptance rates, and per-user metrics for all GitLab Duo events. Data is retained for three months for customers without ClickHouse installed. For customers with ClickHouse configured, there is currently no data retention policy. The `all` and `codeSuggestionEvents` attributes have a maximum date range of one month. If you need data spanning multiple months, run separate queries for each month. The `all` attribute is filterable by `startDate`, `endDate`, `events`, `userIds`, and standard pagination values. To see which events are being tracked, you can examine the events declared in the [`ai_tracking.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/tracking/ai_tracking.rb) file. GitLab Duo Chat events (`request_duo_chat_response`) do not populate the `extras` field. Unlike Code Suggestions events, Chat interactions do not carry language or suggestion metadata. An empty `extras` object on Chat events is expected behavior. ### For projects and groups For example, to retrieve usage data for all Code Suggestions events for the `gitlab-org` group: query { group(fullPath: "gitlab-org") { aiUsageData { codeSuggestionEvents(startDate: "2025-09-26") { nodes { event timestamp language suggestionSize user { username } } } } } } The query returns the following output: { "data": { "group": { "aiUsageData": { "codeSuggestionEvents": { "nodes": [\ {\ "event": "CODE_SUGGESTION_SHOWN_IN_IDE",\ "timestamp": "2025-09-26T18:17:25Z",\ "language": "python",\ "suggestionSize": 2,\ "user": {\ "username": "jasbourne"\ }\ },\ {\ "event": "CODE_SUGGESTION_REJECTED_IN_IDE",\ "timestamp": "2025-09-26T18:13:45Z",\ "language": "python",\ "suggestionSize": 2,\ "user": {\ "username": "jasbourne"\ }\ },\ {\ "event": "CODE_SUGGESTION_ACCEPTED_IN_IDE",\ "timestamp": "2025-09-26T18:13:44Z",\ "language": "python",\ "suggestionSize": 2,\ "user": {\ "username": "jasbourne"\ }\ }\ ] } } } } } Alternatively, to retrieve usage data for all GitLab Duo events for the `gitlab-org` group: query { group(fullPath: "gitlab-org") { aiUsageData { all(startDate: "2025-09-26") { nodes { event timestamp user { username } } } } } } The query returns the following output: { "data": { "group": { "aiUsageData": { "all": { "nodes": [\ {\ "event": "FIND_NO_ISSUES_DUO_CODE_REVIEW_AFTER_REVIEW",\ "timestamp": "2025-09-26T18:17:25Z",\ "user": {\ "username": "jasbourne"\ }\ },\ {\ "event": "REQUEST_REVIEW_DUO_CODE_REVIEW_ON_MR_BY_AUTHOR",\ "timestamp": "2025-09-26T18:13:45Z",\ "user": {\ "username": "jasbourne"\ }\ },\ {\ "event": "AGENT_PLATFORM_SESSION_STARTED",\ "timestamp": "2025-09-26T18:13:44Z",\ "user": {\ "username": "jasbourne"\ }\ }\ ] } } } } } ### For instances * Offering: GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/582153) in GitLab 18.7. This feature is an [experiment](https://docs.gitlab.com/policy/development_stages_support/) . Prerequisites: * You must be an administrator for the instance. For example, to retrieve all GitLab Duo usage events for the entire instance: query { aiUsageData { all(startDate: "2025-09-26", endDate: "2025-09-30") { nodes { event timestamp user { username } extras } } } } The query returns the following output: { "data": { "aiUsageData": { "all": { "nodes": [\ {\ "event": "CODE_SUGGESTION_SHOWN_IN_IDE",\ "timestamp": "2025-09-26T18:17:25Z",\ "user": {\ "username": "jasbourne"\ },\ "extras": {}\ },\ {\ "event": "AGENT_PLATFORM_SESSION_STARTED",\ "timestamp": "2025-09-26T18:13:44Z",\ "user": {\ "username": "johndoe"\ },\ "extras": {\ "session_id": "abc123"\ }\ }\ ] } } } } Retrieve AI user metrics ------------------------ * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/483049) in GitLab 17.6. * Feature-specific metric types [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/483049) in GitLab 18.7 The `AiUserMetrics` endpoint provides pre-aggregated per-user metrics for all registered GitLab Duo features, including Code Suggestions, GitLab Duo Chat, Code Review, Agent Platform, Job Troubleshooting, and Model Context Protocol (MCP) tool calls. You can use this endpoint to analyze GitLab Duo user engagement and measure usage frequency across different GitLab Duo features. Prerequisites: * You must have ClickHouse configured. ### Total event counts The `AiUserMetrics` endpoint provides the following levels of event count aggregation: * Top-level `totalEventCount`: Returns the sum of all event counts across all GitLab Duo features for a user. * Feature-level `totalEventCount`: Available in each feature metric type, returns the sum of all event counts for that specific feature. You can use these fields to get aggregate counts at different levels of granularity. For example, to retrieve both top-level and feature-level totals: query { group(fullPath:"gitlab-org") { aiUserMetrics { nodes { user { username } totalEventCount codeSuggestions { totalEventCount codeSuggestionAcceptedInIdeEventCount codeSuggestionShownInIdeEventCount } chat { totalEventCount requestDuoChatResponseEventCount } } } } } The query returns the following output: { "data": { "group": { "aiUserMetrics": { "nodes": [\ {\ "user": {\ "username": "USER_1"\ },\ "totalEventCount": 82,\ "codeSuggestions": {\ "totalEventCount": 60,\ "codeSuggestionAcceptedInIdeEventCount": 10,\ "codeSuggestionShownInIdeEventCount": 50\ },\ "chat": {\ "totalEventCount": 22,\ "requestDuoChatResponseEventCount": 22\ }\ },\ {\ "user": {\ "username": "USER_2"\ },\ "totalEventCount": 102,\ "codeSuggestions": {\ "totalEventCount": 72,\ "codeSuggestionAcceptedInIdeEventCount": 12,\ "codeSuggestionShownInIdeEventCount": 60\ },\ "chat": {\ "totalEventCount": 30,\ "requestDuoChatResponseEventCount": 30\ }\ }\ ] } } } } In this example: * The top-level `totalEventCount` (82 for USER\_1) is the sum of all events across all features. * Each feature’s `totalEventCount` represents the sum of events within that feature only. * Code Suggestions: 60 events (10 accepted + 50 shown) * Chat: 22 events ### Feature-specific metric types The `AiUserMetrics` endpoint provides detailed metrics through feature-specific nested types. Each GitLab Duo feature has its own dedicated metric type that exposes event count fields for all tracked events related to that feature. Available feature metric types include: * `codeSuggestions`: Code Suggestions-specific metrics * `chat`: GitLab Duo Chat-specific metrics * `codeReview`: Code Review-specific metrics * `agentPlatform`: Agent Platform-specific metrics (includes agentic Chat sessions) * `troubleshootJob`: Job troubleshooting-specific metrics * `mcp`: Model Context Protocol (MCP) tool call metrics Each feature metric type includes: * Individual event count fields for all tracked events in that feature * A `totalEventCount` field that sums all events for that specific feature The available event count fields are dynamically generated based on the events registered in the system. To see which events are tracked for each feature, examine the events declared in the [`ai_tracking.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/tracking/ai_tracking.rb) file. For example, to retrieve detailed metrics across multiple GitLab Duo features: query { group(fullPath:"gitlab-org") { aiUserMetrics { nodes { user { username } codeSuggestions { totalEventCount codeSuggestionAcceptedInIdeEventCount codeSuggestionShownInIdeEventCount } chat { totalEventCount requestDuoChatResponseEventCount } codeReview { totalEventCount requestReviewDuoCodeReviewOnMrByAuthorEventCount findNoIssuesDuoCodeReviewAfterReviewEventCount } agentPlatform { totalEventCount agentPlatformSessionStartedEventCount agentPlatformSessionFinishedEventCount } } } } } The query returns the following output: { "data": { "group": { "aiUserMetrics": { "nodes": [\ {\ "user": {\ "username": "USER_1"\ },\ "codeSuggestions": {\ "totalEventCount": 60,\ "codeSuggestionAcceptedInIdeEventCount": 10,\ "codeSuggestionShownInIdeEventCount": 50\ },\ "chat": {\ "totalEventCount": 22,\ "requestDuoChatResponseEventCount": 22\ },\ "codeReview": {\ "totalEventCount": 8,\ "requestReviewDuoCodeReviewOnMrByAuthorEventCount": 5,\ "findNoIssuesDuoCodeReviewAfterReviewEventCount": 3\ },\ "agentPlatform": {\ "totalEventCount": 15,\ "agentPlatformSessionStartedEventCount": 8,\ "agentPlatformSessionFinishedEventCount": 7\ }\ },\ {\ "user": {\ "username": "USER_2"\ },\ "codeSuggestions": {\ "totalEventCount": 72,\ "codeSuggestionAcceptedInIdeEventCount": 12,\ "codeSuggestionShownInIdeEventCount": 60\ },\ "chat": {\ "totalEventCount": 30,\ "requestDuoChatResponseEventCount": 30\ },\ "codeReview": {\ "totalEventCount": 5,\ "requestReviewDuoCodeReviewOnMrByAuthorEventCount": 3,\ "findNoIssuesDuoCodeReviewAfterReviewEventCount": 2\ },\ "agentPlatform": {\ "totalEventCount": 20,\ "agentPlatformSessionStartedEventCount": 12,\ "agentPlatformSessionFinishedEventCount": 8\ }\ }\ ] } } } } Retrieve GitLab Duo and SDLC trend metrics ------------------------------------------ * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/443696) in GitLab 16.11. * Add-on requirement [changed](https://gitlab.com/gitlab-org/gitlab/-/issues/498497) from GitLab Duo Enterprise to GitLab Duo Pro in GitLab 17.6. * Add-on requirement [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/580174) in GitLab 18.7. The `AiMetrics` endpoint powers the GitLab Duo and SDLC trends dashboard and provides the following pre-aggregated metrics for Code Suggestions and GitLab Duo Chat: * `codeSuggestionsShown` * `codeSuggestionsAccepted` * `codeSuggestionAcceptanceRate` * `codeSuggestionUsers` * `duoChatUsers` Prerequisites: * You must have ClickHouse configured. For example, to retrieve Code Suggestions and GitLab Duo Chat usage data for a specified time period for the `gitlab-org` group: query { group(fullPath: "gitlab-org") { aiMetrics(startDate: "2024-12-01", endDate: "2024-12-31") { codeSuggestions{ shownCount acceptedCount acceptedLinesOfCode shownLinesOfCode } codeContributorsCount duoChatContributorsCount duoUsedCount } } } The query returns the following output: { "data": { "group": { "aiMetrics": { "codeSuggestions": { "shownCount": 88728, "acceptedCount": 7016, "acceptedLinesOfCode": 9334, "shownLinesOfCode": 124118 }, "codeContributorsCount": 719, "duoChatContributorsCount": 681, "duoUsedCount": 714 } } }, } Export AI metrics data to CSV ----------------------------- You can export AI metrics data to a CSV file with the [GitLab AI Metrics Exporter tool](https://gitlab.com/smathur/custom-duo-metrics) . --- # Migrate epic APIs to work items | GitLab Docs * * * Migrate epic APIs to work items =============================== * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated * Status: Beta History * [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/9290) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `work_item_epics`. Disabled by default. [The new look for epics](https://docs.gitlab.com/user/group/epics/#epics-as-work-items) must be enabled. Introduced in [beta](https://docs.gitlab.com/policy/development_stages_support/#beta) . * Listing epics using the [GraphQL API](https://docs.gitlab.com/api/graphql/reference/) [introduced](https://gitlab.com/groups/gitlab-org/-/epics/12852) in GitLab 17.4. * [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/470685) in GitLab 17.6. * [Enabled by default on GitLab Self-Managed and GitLab Dedicated](https://gitlab.com/gitlab-org/gitlab/-/issues/468310) in GitLab 17.7. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/468310) in GitLab 18.1. Feature flag `work_item_epics` removed. GitLab 17.2 introduced [epics as work items](https://docs.gitlab.com/user/group/epics/#epics-as-work-items) . To ensure that your integrations continue working: * If you use the [epic GraphQL API](https://docs.gitlab.com/api/graphql/reference/#epic) , migrate to the work item API before the epic GraphQL API is removed. * If you use the [epic REST API](https://docs.gitlab.com/api/epics/) , you can continue using it, but you should migrate to future-proof your integrations. * For new features (such as assignees, health status, linked items with other types), you must use the `WorkItem` GraphQL API. API status ---------- ### REST API (`/api/v4/`) The REST API for epics: * Is still supported but deprecated. * Continues to work with existing endpoints. * Does not receive new features. * Has no set removal date, but it will happen in a major release. ### GraphQL API The `WorkItem` GraphQL API: * Is marked as experimental. * Is used in production environments. * Will be [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/500620) before GitLab 19.0 * Is planned to exit [experimental status](https://gitlab.com/gitlab-org/gitlab/-/issues/500620) before GitLab 19.0 The [epic GraphQL API](https://docs.gitlab.com/api/graphql/reference/#epic) is planned for removal in GitLab 19.0. Migrate to the Work Item API ---------------------------- The Work Item API uses widgets to represent epic attributes like health status, assignees, and hierarchy. ### Set up the GraphiQL explorer To run these examples, you can use GraphiQL, an interactive GraphQL API explorer where you can play around with existing queries: 1. Open the GraphiQL explorer tool: * For GitLab.com, go to [https://gitlab.com/-/graphql-explorer](https://gitlab.com/-/graphql-explorer) . * For GitLab Self-Managed, go to `https://gitlab.example.com/-/graphql-explorer`. Change `gitlab.example.com` to your instance URL. 2. Paste a query listed in an example into the left window of your GraphiQL explorer tool. 3. Select **Play**. ### Query epics Epic IDs are different from work item IDs, but the IID (ID incremented for each group) remains the same. For example, an epic at `/gitlab-org/-/epics/123` has the same IID `123` as a work item. **Before (Epic API)**: query Epics { group(fullPath: "gitlab-org") { epics { nodes { id iid title } } } } Example response: { "data": { "group": { "epics": { "nodes": [\ {\ "id": "gid://gitlab/Epic/2335843",\ "iid": "15596",\ "title": "First epic"\ },\ {\ "id": "gid://gitlab/Epic/2335762",\ "iid": "15595",\ "title": "Second epic"\ }\ ] } } } } **After (Work Item API)**: query EpicsAsWorkItem { group(fullPath: "gitlab-org") { workItems(types: [EPIC]) { nodes { id iid title } } } } Example response: { "data": { "group": { "workItems": { "nodes": [\ {\ "id": "gid://gitlab/WorkItem/154888575",\ "iid": "15596",\ "title": "First epic"\ },\ {\ "id": "gid://gitlab/WorkItem/154877868",\ "iid": "15595",\ "title": "Second epic"\ }\ ] } } } } ### Create an epic **Before (Epic API)**: mutation CreateEpic { createEpic(input: { title: "New epic", groupPath: "gitlab-org" }) { epic { id title } } } Example response: { "data": { "createEpic": { "epic": { "id": "gid://gitlab/Epic/806", "title": "New epic" } } } } **After (Work Item API)**: To create an epic: 1. Get the work item type ID (`workItemTypeId`) for epics in your namespace. The `workItemTypeId` for an epic is not guaranteed to be the same between GitLab instances or namespaces. Work to ensure the same IDs for default work item types is tracked in [epic 15272](https://gitlab.com/groups/gitlab-org/-/epics/15272) . query WorkItemTypes { namespace(fullPath: "gitlab-org") { workItemTypes(name: EPIC) { nodes { id name } } } } Example response: { "data": { "namespace": { "workItemTypes": { "nodes": [\ {\ // the will be different based on your namespace and instance\ "id": "gid://gitlab/WorkItems::Type/",\ "name": "Epic"\ }\ ] } } } } 2. Create the epic (work item with the type `epic`) by using that ID: mutation CreateWorkItemEpic { workItemCreate( input: { title: "New work item epic" namespacePath: "gitlab-org" workItemTypeId: "gid://gitlab/WorkItems::Type/" } ) { workItem { id title } } } Example response: { "data": { "workItemCreate": { "workItem": { "id": "gid://gitlab/WorkItem/2243", "title": "New work item epic" } } } } ### Widgets The Work Item API introduces the concept of widgets. Widgets represent specific features or attributes of a work item type. They can range from attributes like health status or assignees to dates or hierarchy. Each work item type has a unique set of available widgets. #### Query epics with widgets To retrieve detailed information about an epic, you can use various widgets in your GraphQL query. The following example demonstrates how to query an epic’s: * Hierarchy (parent/child relationships) * Assignees * Emoji reactions * Color * Health status * Start and due dates For all available widgets, see the [work item widget reference](https://docs.gitlab.com/api/graphql/reference/#workitemwidget) . To query epics with widgets: **Before (Epic API)**: query DetailedEpicQuery { group(fullPath: "gitlab-org") { epic(iid: 1000) { id iid title confidential author { id name } state color parent { id title } startDate dueDate ancestors { nodes { id title } } children { nodes { id title } } notes { nodes { body createdAt author { name } } } } } } Example response: { "data": { "group": { "epic": { "id": "gid://gitlab/Epic/5579", "iid": "1000", "title": "Pajamas component: Pagination - Style", "confidential": false, "author": { "id": "gid://gitlab/User/3079878", "name": "Sidney Jones" }, "state": "opened", "color": "#1068bf", "parent": { "id": "gid://gitlab/Epic/5576", "title": "Pajamas component: Pagination" }, "startDate": null, "dueDate": null, "ancestors": { "nodes": [\ {\ "id": "gid://gitlab/Epic/5523",\ "title": "Components of Pajamas Design System"\ },\ {\ "id": "gid://gitlab/Epic/5576",\ "title": "Pajamas component: Pagination"\ }\ ] }, "children": { "nodes": [] }, "notes": { "nodes": [\ {\ "body": "changed the description",\ "createdAt": "2019-04-02T17:03:05Z",\ "author": {\ "name": "Sidney Jones"\ }\ },\ {\ "body": "mentioned in epic &997",\ "createdAt": "2019-04-26T15:45:49Z",\ "author": {\ "name": "Zhang Wei"\ }\ },\ {\ "body": "added issue gitlab-ui#302",\ "createdAt": "2019-06-27T09:20:43Z",\ "author": {\ "name": "Alex Garcia"\ }\ },\ {\ "body": "added issue gitlab-ui#304",\ "createdAt": "2019-06-27T09:20:43Z",\ "author": {\ "name": "Alex Garcia"\ }\ },\ {\ "body": "added issue gitlab-ui#316",\ "createdAt": "2019-07-11T08:26:25Z",\ "author": {\ "name": "Alex Garcia"\ }\ },\ {\ "body": "mentioned in issue gitlab-design#528",\ "createdAt": "2019-08-05T14:12:51Z",\ "author": {\ "name": "Jan Kowalski"\ }\ }\ ] } } } } } **After (Work Item API)**: query DetailedEpicWorkItem { namespace(fullPath: "gitlab-org") { workItem(iid: "10") { id title confidential author { id name } state widgets { ... on WorkItemWidgetColor { color textColor __typename } ... on WorkItemWidgetHierarchy { children { nodes { id title } } parent { title } __typename } ... on WorkItemWidgetHealthStatus { type healthStatus } ... on WorkItemWidgetAssignees { assignees { nodes { name } } __typename } ... on WorkItemWidgetAwardEmoji { downvotes upvotes awardEmoji { nodes { unicode } } __typename } ... on WorkItemWidgetStartAndDueDate { dueDate isFixed startDate __typename } ... on WorkItemWidgetNotes { discussions { nodes { notes { edges { node { body id author { name } } } } } } } __typename } } } } Example response: { "data": { "namespace": { "workItem": { "id": "gid://gitlab/WorkItem/146171815", "title": "Pajamas component: Pagination - Style", "confidential": false, "author": { "id": "gid://gitlab/User/3079878", "name": "Sidney Jones" }, "state": "OPEN", "widgets": [\ {\ "assignees": {\ "nodes": []\ },\ "__typename": "WorkItemWidgetAssignees"\ },\ {\ "__typename": "WorkItemWidgetDescription"\ },\ {\ "children": {\ "nodes": [\ {\ "id": "gid://gitlab/WorkItem/24697619",\ "title": "Pagination does not conform with button styling and interaction styling"\ },\ {\ "id": "gid://gitlab/WorkItem/22693964",\ "title": "Remove next and previous labels on mobile and smaller viewports for pagination component"\ },\ {\ "id": "gid://gitlab/WorkItem/22308883",\ "title": "Update pagination border and background colors according to the specs"\ },\ {\ "id": "gid://gitlab/WorkItem/22294339",\ "title": "Pagination \"active\" page contains gray border on right side"\ }\ ]\ },\ "parent": {\ "title": "Pajamas component: Pagination"\ },\ "__typename": "WorkItemWidgetHierarchy"\ },\ {\ "__typename": "WorkItemWidgetLabels"\ },\ {\ "discussions": {\ "nodes": [\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "changed the description",\ "id": "gid://gitlab/Note/156548315",\ "author": {\ "name": "Sidney Jones"\ }\ }\ }\ ]\ }\ },\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "added ~10161862 label",\ "id": "gid://gitlab/LabelNote/853dc8176d8eff789269d69c31c019ecd9918996",\ "author": {\ "name": "Jan Kowalski"\ }\ }\ }\ ]\ }\ },\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "mentioned in epic &997",\ "id": "gid://gitlab/Note/164703873",\ "author": {\ "name": "Zhang Wei"\ }\ }\ }\ ]\ }\ },\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "added issue gitlab-ui#302",\ "id": "gid://gitlab/Note/185977331",\ "author": {\ "name": "Alex Garcia"\ }\ }\ }\ ]\ }\ },\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "added issue gitlab-ui#304",\ "id": "gid://gitlab/Note/185977335",\ "author": {\ "name": "Alex Garcia"\ }\ }\ }\ ]\ }\ },\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "added issue gitlab-ui#316",\ "id": "gid://gitlab/Note/190661279",\ "author": {\ "name": "Alex Garcia"\ }\ }\ }\ ]\ }\ },\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "mentioned in issue gitlab-design#528",\ "id": "gid://gitlab/Note/200228415",\ "author": {\ "name": "Jan Kowalski"\ }\ }\ }\ ]\ }\ },\ {\ "notes": {\ "edges": [\ {\ "node": {\ "body": "added ~8547186 ~10161725 labels and removed ~10161862 label",\ "id": "gid://gitlab/LabelNote/dfa79f5c4e6650850cc9e767f0dc0d3896bfd0f9",\ "author": {\ "name": "Sidney Jones"\ }\ }\ }\ ]\ }\ }\ ]\ },\ "__typename": "WorkItemWidgetNotes"\ },\ {\ "dueDate": null,\ "isFixed": false,\ "startDate": null,\ "__typename": "WorkItemWidgetStartAndDueDate"\ },\ {\ "type": "HEALTH_STATUS",\ "healthStatus": null,\ "__typename": "WorkItemWidgetHealthStatus"\ },\ {\ "__typename": "WorkItemWidgetVerificationStatus"\ },\ {\ "__typename": "WorkItemWidgetNotifications"\ },\ {\ "downvotes": 0,\ "upvotes": 0,\ "awardEmoji": {\ "nodes": []\ },\ "__typename": "WorkItemWidgetAwardEmoji"\ },\ {\ "__typename": "WorkItemWidgetLinkedItems"\ },\ {\ "__typename": "WorkItemWidgetCurrentUserTodos"\ },\ {\ "__typename": "WorkItemWidgetRolledupDates"\ },\ {\ "__typename": "WorkItemWidgetParticipants"\ },\ {\ "__typename": "WorkItemWidgetWeight"\ },\ {\ "__typename": "WorkItemWidgetTimeTracking"\ },\ {\ "color": "#1068bf",\ "textColor": "#FFFFFF",\ "__typename": "WorkItemWidgetColor"\ }\ ] } } } } #### Create a work item epic with widgets Use widgets as part of the `input` parameter to create or update work items. For example, run the query below to create an epic with: * Title * Description * Color * Health status * Start date * Due date * Assignee mutation createEpicWithWidgets { workItemCreate( input: { title: "New work item epic" namespacePath: "gitlab-org" workItemTypeId: "gid://gitlab/WorkItems::Type/" colorWidget: { color: "#e24329" } descriptionWidget: { description: "My new plans ..." } healthStatusWidget: { healthStatus: onTrack } startAndDueDateWidget: { startDate: "2024-10-12", dueDate: "2024-12-12", isFixed: true } assigneesWidget: { assigneeIds: "gid://gitlab/User/" } } ) { workItem { id title description widgets { ... on WorkItemWidgetColor { color textColor __typename } ... on WorkItemWidgetAssignees { assignees { nodes { id name } } __typename } ... on WorkItemWidgetHealthStatus { healthStatus __typename } ... on WorkItemWidgetStartAndDueDate { startDate dueDate isFixed __typename } } } } } Example response: { "data": { "workItemCreate": { "workItem": { "id": "gid://gitlab/WorkItem/2252", "title": "New epic", "description": "My new plans ...", "widgets": [\ {\ "assignees": {\ "nodes": [\ {\ "id": "gid://gitlab/User/46",\ "name": "Jane Smith"\ }\ ]\ },\ "__typename": "WorkItemWidgetAssignees"\ },\ {\ "color": "#e24329",\ "textColor": "#FFFFFF",\ "__typename": "WorkItemWidgetColor"\ },\ {\ "healthStatus": "onTrack",\ "__typename": "WorkItemWidgetHealthStatus"\ },\ {\ "startDate": "2024-10-12",\ "dueDate": "2024-12-12",\ "isFixed": true,\ "__typename": "WorkItemWidgetStartAndDueDate"\ }\ ] } } } } #### Update a work item epic using widgets To edit a work item, re-use the widget inputs from [create a work item epic with widgets](https://docs.gitlab.com/api/graphql/epic_work_items_api_migration_guide/#create-a-work-item-epic-with-widgets) , but use the `workItemUpdate` mutation instead. Get the global ID of the work item (format `gid://gitlab/WorkItem/`) and use it as `id` for the `input`: mutation updateEpicWorkItemWithWidgets { workItemUpdate( input: { id: "gid://gitlab/WorkItem/" title: "Updated work item epic title" colorWidget: { color: "#fc6d26" } descriptionWidget: { description: "My other new plans ..." } healthStatusWidget: { healthStatus: onTrack } startAndDueDateWidget: { startDate: "2025-10-12", dueDate: "2025-12-12", isFixed: true } assigneesWidget: { assigneeIds: "gid://gitlab/User/45" } } ) { workItem { id title description widgets { ... on WorkItemWidgetColor { color textColor __typename } ... on WorkItemWidgetAssignees { assignees { nodes { id name } } __typename } ... on WorkItemWidgetHealthStatus { healthStatus __typename } ... on WorkItemWidgetStartAndDueDate { startDate dueDate isFixed __typename } } } } } Example response: { "data": { "workItemUpdate": { "workItem": { "id": "gid://gitlab/WorkItem/2252", "title": "Updated work item epic title", "description": "My other new plans ...", "widgets": [\ {\ "assignees": {\ "nodes": [\ {\ "id": "gid://gitlab/User/45",\ "name": "Ardella Williamson"\ }\ ]\ },\ "__typename": "WorkItemWidgetAssignees"\ },\ {\ "color": "#fc6d26",\ "textColor": "#FFFFFF",\ "__typename": "WorkItemWidgetColor"\ },\ {\ "healthStatus": "onTrack",\ "__typename": "WorkItemWidgetHealthStatus"\ },\ {\ "startDate": "2025-10-12",\ "dueDate": "2025-12-12",\ "isFixed": true,\ "__typename": "WorkItemWidgetStartAndDueDate"\ }\ ] } } } } ### Delete an epic work item To delete an epic work item, use the `workItemDelete` mutation: mutation deleteEpicWorkItem { workItemDelete(input: { id: "gid://gitlab/WorkItem/" }) { clientMutationId errors namespace { id } } } Example response: { "data": { "workItemDelete": { "clientMutationId": null, "errors": [], "namespace": { "id": "gid://gitlab/Group/24" } } } } --- # Project starring API | GitLab Docs * * * Project starring API ==================== Use this API to interact with starred projects. For more information, see [projects and stars](https://docs.gitlab.com/user/project/working_with_projects/) . List projects starred by a user ------------------------------- Lists all visible projects starred by a specified user. When accessed without authentication, only public projects are returned. GET /users/:user_id/starred_projects Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `user_id` | string | Yes | The ID or username of the user. | | `archived` | boolean | No | Limit by archived status. | | `membership` | boolean | No | Limit by projects that the current user is a member of. | | `min_access_level` | integer | No | Limit to projects where the current user has at least the specified access level. Possible values: `5` (Minimal access), `10` (Guest), `15` (Planner), `20` (Reporter), `25` (Security Manager), `30` (Developer), `40` (Maintainer), or `50` (Owner). | | `order_by` | string | No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `star_count`, or `last_activity_at` fields. Default is `created_at`. | | `owned` | boolean | No | Limit by projects explicitly owned by the current user. | | `search` | string | No | Return list of projects matching the search criteria. | | `simple` | boolean | No | Return only limited fields for each project. Without authentication, this operation is a no-op; only simple fields are returned. | | `sort` | string | No | Return projects sorted in `asc` or `desc` order. Default is `desc`. | | `starred` | boolean | No | Limit by projects starred by the current user. | | `statistics` | boolean | No | Include project statistics. Available only to users with the Reporter, Developer, Maintainer, or Owner role. | | `updated_after` | datetime | No | Limit results to projects last updated after the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979)
in GitLab 15.10. | | `updated_before` | datetime | No | Limit results to projects last updated before the specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393979)
in GitLab 15.10. | | `visibility` | string | No | Limit by visibility `public`, `internal`, or `private`. | | `with_custom_attributes` | boolean | No | Include [custom attributes](https://docs.gitlab.com/api/custom_attributes/)
in response. _(administrator only)_ | | `with_issues_enabled` | boolean | No | Limit by enabled issues feature. | | `with_merge_requests_enabled` | boolean | No | Limit by enabled merge requests feature. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/users/5/starred_projects" Example response: [\ {\ "id": 4,\ "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",\ "description_html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

",\ "default_branch": "main",\ "visibility": "private",\ "ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",\ "http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",\ "web_url": "http://example.com/diaspora/diaspora-client",\ "readme_url": "http://example.com/diaspora/diaspora-client/blob/main/README.md",\ "tag_list": [ //deprecated, use `topics` instead\ "example",\ "disapora client"\ ],\ "topics": [\ "example",\ "disapora client"\ ],\ "owner": {\ "id": 3,\ "name": "Diaspora",\ "created_at": "2013-09-30T13:46:02Z"\ },\ "name": "Diaspora Client",\ "name_with_namespace": "Diaspora / Diaspora Client",\ "path": "diaspora-client",\ "path_with_namespace": "diaspora/diaspora-client",\ "issues_enabled": true,\ "open_issues_count": 1,\ "merge_requests_enabled": true,\ "jobs_enabled": true,\ "wiki_enabled": true,\ "snippets_enabled": false,\ "can_create_merge_request_in": true,\ "resolve_outdated_diff_discussions": false,\ "container_registry_enabled": false, // deprecated, use container_registry_access_level instead\ "container_registry_access_level": "disabled",\ "security_and_compliance_access_level": "disabled",\ "created_at": "2013-09-30T13:46:02Z",\ "updated_at": "2013-09-30T13:46:02Z",\ "last_activity_at": "2013-09-30T13:46:02Z",\ "creator_id": 3,\ "namespace": {\ "id": 3,\ "name": "Diaspora",\ "path": "diaspora",\ "kind": "group",\ "full_path": "diaspora"\ },\ "import_status": "none",\ "archived": false,\ "avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",\ "shared_runners_enabled": true,\ "group_runners_enabled": true,\ "forks_count": 0,\ "star_count": 0,\ "runners_token": "",\ "public_jobs": true,\ "shared_with_groups": [],\ "only_allow_merge_if_pipeline_succeeds": false,\ "allow_merge_on_skipped_pipeline": false,\ "restrict_user_defined_variables": false,\ "only_allow_merge_if_all_discussions_are_resolved": false,\ "remove_source_branch_after_merge": false,\ "request_access_enabled": false,\ "merge_method": "merge",\ "squash_option": "default_on",\ "autoclose_referenced_issues": true,\ "enforce_auth_checks_on_uploads": true,\ "suggestion_commit_message": null,\ "merge_commit_template": null,\ "squash_commit_template": null,\ "issue_branch_template": "gitlab/%{id}-%{title}",\ "statistics": {\ "commit_count": 37,\ "storage_size": 1038090,\ "repository_size": 1038090,\ "lfs_objects_size": 0,\ "job_artifacts_size": 0,\ "pipeline_artifacts_size": 0,\ "packages_size": 0,\ "snippets_size": 0,\ "uploads_size": 0,\ "container_registry_size": 0\ },\ "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-client",\ "_links": {\ "self": "http://example.com/api/v4/projects",\ "issues": "http://example.com/api/v4/projects/1/issues",\ "merge_requests": "http://example.com/api/v4/projects/1/merge_requests",\ "repo_branches": "http://example.com/api/v4/projects/1/repository_branches",\ "labels": "http://example.com/api/v4/projects/1/labels",\ "events": "http://example.com/api/v4/projects/1/events",\ "members": "http://example.com/api/v4/projects/1/members",\ "cluster_agents": "http://example.com/api/v4/projects/1/cluster_agents"\ }\ },\ {\ "id": 6,\ "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",\ "description_html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

",\ "default_branch": "main",\ "visibility": "private",\ "ssh_url_to_repo": "git@example.com:brightbox/puppet.git",\ "http_url_to_repo": "http://example.com/brightbox/puppet.git",\ "web_url": "http://example.com/brightbox/puppet",\ "readme_url": "http://example.com/brightbox/puppet/blob/main/README.md",\ "tag_list": [ //deprecated, use `topics` instead\ "example",\ "puppet"\ ],\ "topics": [\ "example",\ "puppet"\ ],\ "owner": {\ "id": 4,\ "name": "Brightbox",\ "created_at": "2013-09-30T13:46:02Z"\ },\ "name": "Puppet",\ "name_with_namespace": "Brightbox / Puppet",\ "path": "puppet",\ "path_with_namespace": "brightbox/puppet",\ "issues_enabled": true,\ "open_issues_count": 1,\ "merge_requests_enabled": true,\ "jobs_enabled": true,\ "wiki_enabled": true,\ "snippets_enabled": false,\ "can_create_merge_request_in": true,\ "resolve_outdated_diff_discussions": false,\ "container_registry_enabled": false, // deprecated, use container_registry_access_level instead\ "container_registry_access_level": "disabled",\ "security_and_compliance_access_level": "disabled",\ "created_at": "2013-09-30T13:46:02Z",\ "updated_at": "2013-09-30T13:46:02Z",\ "last_activity_at": "2013-09-30T13:46:02Z",\ "creator_id": 3,\ "namespace": {\ "id": 4,\ "name": "Brightbox",\ "path": "brightbox",\ "kind": "group",\ "full_path": "brightbox"\ },\ "import_status": "none",\ "import_error": null,\ "permissions": {\ "project_access": {\ "access_level": 10,\ "notification_level": 3\ },\ "group_access": {\ "access_level": 50,\ "notification_level": 3\ }\ },\ "archived": false,\ "avatar_url": null,\ "shared_runners_enabled": true,\ "group_runners_enabled": true,\ "forks_count": 0,\ "star_count": 0,\ "runners_token": "",\ "public_jobs": true,\ "shared_with_groups": [],\ "only_allow_merge_if_pipeline_succeeds": false,\ "allow_merge_on_skipped_pipeline": false,\ "restrict_user_defined_variables": false,\ "only_allow_merge_if_all_discussions_are_resolved": false,\ "remove_source_branch_after_merge": false,\ "request_access_enabled": false,\ "merge_method": "merge",\ "squash_option": "default_on",\ "auto_devops_enabled": true,\ "auto_devops_deploy_strategy": "continuous",\ "repository_storage": "default",\ "approvals_before_merge": 0, // Deprecated. Use merge request approvals API instead.\ "mirror": false,\ "mirror_user_id": 45,\ "mirror_trigger_builds": false,\ "only_mirror_protected_branches": false,\ "mirror_overwrites_diverged_branches": false,\ "external_authorization_classification_label": null,\ "packages_enabled": true,\ "service_desk_enabled": false,\ "service_desk_address": null,\ "autoclose_referenced_issues": true,\ "enforce_auth_checks_on_uploads": true,\ "suggestion_commit_message": null,\ "merge_commit_template": null,\ "squash_commit_template": null,\ "issue_branch_template": "gitlab/%{id}-%{title}",\ "statistics": {\ "commit_count": 12,\ "storage_size": 2066080,\ "repository_size": 2066080,\ "lfs_objects_size": 0,\ "job_artifacts_size": 0,\ "pipeline_artifacts_size": 0,\ "packages_size": 0,\ "snippets_size": 0,\ "uploads_size": 0,\ "container_registry_size": 0\ },\ "container_registry_image_prefix": "registry.example.com/brightbox/puppet",\ "_links": {\ "self": "http://example.com/api/v4/projects",\ "issues": "http://example.com/api/v4/projects/1/issues",\ "merge_requests": "http://example.com/api/v4/projects/1/merge_requests",\ "repo_branches": "http://example.com/api/v4/projects/1/repository_branches",\ "labels": "http://example.com/api/v4/projects/1/labels",\ "events": "http://example.com/api/v4/projects/1/events",\ "members": "http://example.com/api/v4/projects/1/members",\ "cluster_agents": "http://example.com/api/v4/projects/1/cluster_agents"\ }\ }\ ] List users who starred a project -------------------------------- Lists all users who starred a specified project. GET /projects/:id/starrers Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `search` | string | No | Search for specific users. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/starrers" Example responses: [\ {\ "starred_since": "2019-01-28T14:47:30.642Z",\ "user": {\ "id": 1,\ "username": "jane_smith",\ "name": "Jane Smith",\ "state": "active",\ "avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",\ "web_url": "http://localhost:3000/jane_smith"\ }\ },\ {\ "starred_since": "2018-01-02T11:40:26.570Z",\ "user": {\ "id": 2,\ "username": "janine_smith",\ "name": "Janine Smith",\ "state": "blocked",\ "avatar_url": "http://gravatar.com/../e32131cd8.jpeg",\ "web_url": "http://localhost:3000/janine_smith"\ }\ }\ ] Star a project -------------- Star a project. POST /projects/:id/star Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/star" Example response: { "id": 3, "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", "description_html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", "default_branch": "main", "visibility": "internal", "ssh_url_to_repo": "git@example.com:diaspora/diaspora-project-site.git", "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git", "web_url": "http://example.com/diaspora/diaspora-project-site", "readme_url": "http://example.com/diaspora/diaspora-project-site/blob/main/README.md", "tag_list": [ //deprecated, use `topics` instead\ "example",\ "disapora project"\ ], "topics": [\ "example",\ "disapora project"\ ], "name": "Diaspora Project Site", "name_with_namespace": "Diaspora / Diaspora Project Site", "path": "diaspora-project-site", "path_with_namespace": "diaspora/diaspora-project-site", "repository_object_format": "sha1", "issues_enabled": true, "open_issues_count": 1, "merge_requests_enabled": true, "jobs_enabled": true, "wiki_enabled": true, "snippets_enabled": false, "can_create_merge_request_in": true, "resolve_outdated_diff_discussions": false, "container_registry_enabled": false, // deprecated, use container_registry_access_level instead "container_registry_access_level": "disabled", "security_and_compliance_access_level": "disabled", "created_at": "2013-09-30T13:46:02Z", "updated_at": "2013-09-30T13:46:02Z", "last_activity_at": "2013-09-30T13:46:02Z", "creator_id": 3, "namespace": { "id": 3, "name": "Diaspora", "path": "diaspora", "kind": "group", "full_path": "diaspora" }, "import_status": "none", "archived": true, "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png", "license_url": "http://example.com/diaspora/diaspora-client/blob/main/LICENSE", "license": { "key": "lgpl-3.0", "name": "GNU Lesser General Public License v3.0", "nickname": "GNU LGPLv3", "html_url": "http://choosealicense.com/licenses/lgpl-3.0/", "source_url": "http://www.gnu.org/licenses/lgpl-3.0.txt" }, "shared_runners_enabled": true, "group_runners_enabled": true, "forks_count": 0, "star_count": 1, "public_jobs": true, "shared_with_groups": [], "only_allow_merge_if_pipeline_succeeds": false, "allow_merge_on_skipped_pipeline": false, "restrict_user_defined_variables": false, "only_allow_merge_if_all_discussions_are_resolved": false, "remove_source_branch_after_merge": false, "request_access_enabled": false, "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site", "_links": { "self": "http://example.com/api/v4/projects", "issues": "http://example.com/api/v4/projects/1/issues", "merge_requests": "http://example.com/api/v4/projects/1/merge_requests", "repo_branches": "http://example.com/api/v4/projects/1/repository_branches", "labels": "http://example.com/api/v4/projects/1/labels", "events": "http://example.com/api/v4/projects/1/events", "members": "http://example.com/api/v4/projects/1/members", "cluster_agents": "http://example.com/api/v4/projects/1/cluster_agents" } } Unstar a project ---------------- Unstar a project. POST /projects/:id/unstar Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/unstar" Example response: { "id": 3, "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", "description_html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", "default_branch": "main", "visibility": "internal", "ssh_url_to_repo": "git@example.com:diaspora/diaspora-project-site.git", "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git", "web_url": "http://example.com/diaspora/diaspora-project-site", "readme_url": "http://example.com/diaspora/diaspora-project-site/blob/main/README.md", "tag_list": [ //deprecated, use `topics` instead\ "example",\ "disapora project"\ ], "topics": [\ "example",\ "disapora project"\ ], "name": "Diaspora Project Site", "name_with_namespace": "Diaspora / Diaspora Project Site", "path": "diaspora-project-site", "path_with_namespace": "diaspora/diaspora-project-site", "repository_object_format": "sha1", "issues_enabled": true, "open_issues_count": 1, "merge_requests_enabled": true, "jobs_enabled": true, "wiki_enabled": true, "snippets_enabled": false, "can_create_merge_request_in": true, "resolve_outdated_diff_discussions": false, "container_registry_enabled": false, // deprecated, use container_registry_access_level instead "container_registry_access_level": "disabled", "security_and_compliance_access_level": "disabled", "created_at": "2013-09-30T13:46:02Z", "updated_at": "2013-09-30T13:46:02Z", "last_activity_at": "2013-09-30T13:46:02Z", "creator_id": 3, "namespace": { "id": 3, "name": "Diaspora", "path": "diaspora", "kind": "group", "full_path": "diaspora" }, "import_status": "none", "archived": true, "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png", "license_url": "http://example.com/diaspora/diaspora-client/blob/main/LICENSE", "license": { "key": "lgpl-3.0", "name": "GNU Lesser General Public License v3.0", "nickname": "GNU LGPLv3", "html_url": "http://choosealicense.com/licenses/lgpl-3.0/", "source_url": "http://www.gnu.org/licenses/lgpl-3.0.txt" }, "shared_runners_enabled": true, "group_runners_enabled": true, "forks_count": 0, "star_count": 0, "public_jobs": true, "shared_with_groups": [], "only_allow_merge_if_pipeline_succeeds": false, "allow_merge_on_skipped_pipeline": false, "restrict_user_defined_variables": false, "only_allow_merge_if_all_discussions_are_resolved": false, "remove_source_branch_after_merge": false, "request_access_enabled": false, "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site", "_links": { "self": "http://example.com/api/v4/projects", "issues": "http://example.com/api/v4/projects/1/issues", "merge_requests": "http://example.com/api/v4/projects/1/merge_requests", "repo_branches": "http://example.com/api/v4/projects/1/repository_branches", "labels": "http://example.com/api/v4/projects/1/labels", "events": "http://example.com/api/v4/projects/1/events", "members": "http://example.com/api/v4/projects/1/members", "cluster_agents": "http://example.com/api/v4/projects/1/cluster_agents" } } Returns status code `304` if the project is not starred. --- # Project webhooks API | GitLab Docs * * * Project webhooks API ==================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [project webhooks](https://docs.gitlab.com/user/project/integrations/webhooks/) . Project webhooks are different from [system hooks](https://docs.gitlab.com/api/system_hooks/) that impact the entire instance, and [group webhooks](https://docs.gitlab.com/api/group_webhooks/) that impact all projects and subgroups in a group. Prerequisites: * You must be an administrator or have the Maintainer or Owner role for the project. List webhooks for a project --------------------------- Get a list of project webhooks. GET /projects/:id/hooks Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Retrieve a project webhook -------------------------- Retrieves a specified webhook for a project. GET /projects/:id/hooks/:hook_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of a project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example response: { "id": 1, "url": "http://example.com/hook", "name": "Hook name", "description": "Hook description", "project_id": 3, "push_events": true, "push_events_branch_filter": "", "issues_events": true, "confidential_issues_events": true, "merge_requests_events": true, "tag_push_events": true, "note_events": true, "confidential_note_events": true, "job_events": true, "pipeline_events": true, "wiki_page_events": true, "deployment_events": true, "releases_events": true, "milestone_events": true, "feature_flag_events": true, "enable_ssl_verification": true, "repository_update_events": false, "alert_status": "executable", "disabled_until": null, "url_variables": [ ], "created_at": "2012-10-12T17:04:47Z", "resource_access_token_events": true, "custom_webhook_template": "{\"event\":\"{{object_kind}}\"}", "custom_headers": [\ {\ "key": "Authorization"\ }\ ] } List project webhook events --------------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151048) in GitLab 17.3. Lists all events for a specified project webhook in the past 7 days from start date. GET /projects/:id/hooks/:hook_id/events Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of a project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `status` | integer or string | No | Response status code of the events, for example: `200` or `500`. You can search by status category: `successful` (200-299), `client_failure` (400-499), and `server_failure` (500-599). | | `page` | integer | No | Page to retrieve. Defaults to `1`. | | `per_page` | integer | No | Number of records to return per page. Defaults to `20`. | Example response: [\ {\ "id": 1,\ "url": "https://example.net/",\ "trigger": "push_hooks",\ "request_headers": {\ "Content-Type": "application/json",\ "User-Agent": "GitLab/17.1.0-pre",\ "Idempotency-Key": "3a427872-00df-429c-9bc9-a9475de2efe4",\ "X-Gitlab-Event": "Push Hook",\ "X-Gitlab-Webhook-UUID": "3c5c0404-c866-44bc-a5f6-452bb1bfc76e",\ "X-Gitlab-Instance": "https://gitlab.example.com",\ "X-Gitlab-Event-UUID": "9cebe914-4827-408f-b014-cfa23a47a35f",\ "X-Gitlab-Token": "[REDACTED]"\ },\ "request_data": {\ "object_kind": "push",\ "event_name": "push",\ "before": "468abc807a2b2572f43e72c743b76cee6db24025",\ "after": "f15b32277d2c55c6c595845a87109b09c913c556",\ "ref": "refs/heads/master",\ "ref_protected": true,\ "checkout_sha": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": null,\ "user_id": 1,\ "user_name": "Administrator",\ "user_username": "root",\ "user_email": null,\ "user_avatar": "https://www.gravatar.com/avatar/13efe0d4559475ba84ecc802061febbdea6e224fcbffd7ec7da9cd431845299c?s=80&d=identicon",\ "project_id": 7,\ "project": {\ "id": 7,\ "name": "Flight",\ "description": "Incidunt ea ab officia a veniam.",\ "web_url": "https://gitlab.example.com/flightjs/Flight",\ "avatar_url": null,\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "namespace": "Flightjs",\ "visibility_level": 10,\ "path_with_namespace": "flightjs/Flight",\ "default_branch": "master",\ "ci_config_path": null,\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "http_url": "https://gitlab.example.com/flightjs/Flight.git"\ },\ "commits": [\ {\ "id": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": "v1.5.2\n",\ "title": "v1.5.2",\ "timestamp": "2017-06-19T14:39:53-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/f15b32277d2c55c6c595845a87109b09c913c556",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "message": "Merge pull request #378 from flightjs/alunny/publish_lib\n\npublish lib and index to npm",\ "title": "Merge pull request #378 from flightjs/alunny/publish_lib",\ "timestamp": "2017-06-16T10:26:39-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "author": {\ "name": "angus croll",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "468abc807a2b2572f43e72c743b76cee6db24025",\ "message": "publish lib and index to npm\n",\ "title": "publish lib and index to npm",\ "timestamp": "2017-06-16T10:23:04-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/468abc807a2b2572f43e72c743b76cee6db24025",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ }\ ],\ "total_commits_count": 3,\ "push_options": {},\ "repository": {\ "name": "Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "description": "Incidunt ea ab officia a veniam.",\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "visibility_level": 10\ }\ },\ "response_headers": {\ "Date": "Sun, 26 May 2024 03:03:17 GMT",\ "Content-Type": "application/json; charset=utf-8",\ "Content-Length": "16",\ "Connection": "close",\ "X-Powered-By": "Express",\ "Access-Control-Allow-Origin": "*",\ "X-Pd-Status": "sent to primary"\ },\ "response_body": "{\"success\":true}",\ "execution_duration": 1.0906479999999874,\ "response_status": "200"\ },\ {\ "id": 2,\ "url": "https://example.net/",\ "trigger": "push_hooks",\ "request_headers": {\ "Content-Type": "application/json",\ "User-Agent": "GitLab/17.1.0-pre",\ "Idempotency-Key": "7c6e0583-49f2-4dc5-a50b-4c0bcf3c1b27",\ "X-Gitlab-Event": "Push Hook",\ "X-Gitlab-Webhook-UUID": "a753eedb-1d72-4549-9ca7-eac8ea8e50dd",\ "X-Gitlab-Instance": "https://gitlab.example.com",\ "X-Gitlab-Event-UUID": "842d7c3e-3114-4396-8a95-66c084d53cb1",\ "X-Gitlab-Token": "[REDACTED]"\ },\ "request_data": {\ "object_kind": "push",\ "event_name": "push",\ "before": "468abc807a2b2572f43e72c743b76cee6db24025",\ "after": "f15b32277d2c55c6c595845a87109b09c913c556",\ "ref": "refs/heads/master",\ "ref_protected": true,\ "checkout_sha": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": null,\ "user_id": 1,\ "user_name": "Administrator",\ "user_username": "root",\ "user_email": null,\ "user_avatar": "https://www.gravatar.com/avatar/13efe0d4559475ba84ecc802061febbdea6e224fcbffd7ec7da9cd431845299c?s=80&d=identicon",\ "project_id": 7,\ "project": {\ "id": 7,\ "name": "Flight",\ "description": "Incidunt ea ab officia a veniam.",\ "web_url": "https://gitlab.example.com/flightjs/Flight",\ "avatar_url": null,\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "namespace": "Flightjs",\ "visibility_level": 10,\ "path_with_namespace": "flightjs/Flight",\ "default_branch": "master",\ "ci_config_path": null,\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "http_url": "https://gitlab.example.com/flightjs/Flight.git"\ },\ "commits": [\ {\ "id": "f15b32277d2c55c6c595845a87109b09c913c556",\ "message": "v1.5.2\n",\ "title": "v1.5.2",\ "timestamp": "2017-06-19T14:39:53-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/f15b32277d2c55c6c595845a87109b09c913c556",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "message": "Merge pull request #378 from flightjs/alunny/publish_lib\n\npublish lib and index to npm",\ "title": "Merge pull request #378 from flightjs/alunny/publish_lib",\ "timestamp": "2017-06-16T10:26:39-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/8749d49930866a4871fa086adbd7d2057fcc3ebb",\ "author": {\ "name": "angus croll",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ },\ {\ "id": "468abc807a2b2572f43e72c743b76cee6db24025",\ "message": "publish lib and index to npm\n",\ "title": "publish lib and index to npm",\ "timestamp": "2017-06-16T10:23:04-07:00",\ "url": "https://gitlab.example.com/flightjs/Flight/-/commit/468abc807a2b2572f43e72c743b76cee6db24025",\ "author": {\ "name": "Andrew Lunny",\ "email": "[REDACTED]"\ },\ "added": [],\ "modified": [\ "package.json"\ ],\ "removed": []\ }\ ],\ "total_commits_count": 3,\ "push_options": {},\ "repository": {\ "name": "Flight",\ "url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "description": "Incidunt ea ab officia a veniam.",\ "homepage": "https://gitlab.example.com/flightjs/Flight",\ "git_http_url": "https://gitlab.example.com/flightjs/Flight.git",\ "git_ssh_url": "ssh://git@gitlab.example.com:2222/flightjs/Flight.git",\ "visibility_level": 10\ }\ },\ "response_headers": {\ "Date": "Sun, 26 May 2024 03:03:19 GMT",\ "Content-Type": "application/json; charset=utf-8",\ "Content-Length": "16",\ "Connection": "close",\ "X-Powered-By": "Express",\ "Access-Control-Allow-Origin": "*",\ "X-Pd-Status": "sent to primary"\ },\ "response_body": "{\"success\":true}",\ "execution_duration": 1.0716120000000728,\ "response_status": "200"\ }\ ] Resend a project webhook event ------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151130) in GitLab 17.4. Resend a specific project webhook event. This endpoint has a rate limit of five requests per minute for each project webhook and authenticated user. To disable this limit on GitLab Self-Managed and GitLab Dedicated, an administrator can [disable the feature flag](https://docs.gitlab.com/administration/feature_flags/) named `web_hook_event_resend_api_endpoint_rate_limit`. POST /projects/:id/hooks/:hook_id/events/:hook_event_id/resend Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_event_id` | integer | Yes | ID of a project webhook event. | | `hook_id` | integer | Yes | ID of a project webhook. | Example response: { "response_status": 200 } Add a webhook to a project -------------------------- History * `name` and `description` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887) in GitLab 17.1. Add a webhook to a specified project. POST /projects/:id/hooks Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `url` | string | Yes | Project webhook URL. | | `branch_filter_strategy` | string | No | Filter push events by branch. Possible values are `wildcard` (default), `regex`, and `all_branches`. | | `confidential_issues_events` | boolean | No | Trigger project webhook on confidential issue events. | | `confidential_note_events` | boolean | No | Trigger project webhook on confidential note events. | | `custom_headers` | array | No | Custom headers for the project webhook. | | `custom_webhook_template` | string | No | Custom webhook template for the project webhook. | | `deployment_events` | boolean | No | Trigger project webhook on deployment events. | | `description` | string | No | Description of the webhook. | | `enable_ssl_verification` | boolean | No | Do SSL verification when triggering the webhook. | | `feature_flag_events` | boolean | No | Trigger project webhook on feature flag events. | | `issues_events` | boolean | No | Trigger project webhook on issue events. | | `job_events` | boolean | No | Trigger project webhook on job events. | | `merge_requests_events` | boolean | No | Trigger project webhook on merge request events. | | `milestone_events` | boolean | No | Trigger project webhook on milestone events. | | `name` | string | No | Name of the project webhook. | | `note_events` | boolean | No | Trigger project webhook on note events. | | `pipeline_events` | boolean | No | Trigger project webhook on pipeline events. | | `push_events` | boolean | No | Trigger project webhook on push events. | | `push_events_branch_filter` | string | No | Trigger project webhook on push events for matching branches only. | | `releases_events` | boolean | No | Trigger project webhook on release events. | | `resource_access_token_events` | boolean | No | Trigger project webhook on project access token expiry events. | | `tag_push_events` | boolean | No | Trigger project webhook on tag push events. | | `token` | string | No | Secret token to validate received payloads; the token isn’t returned in the response. | | `wiki_page_events` | boolean | No | Trigger project webhook on wiki events. | | `resource_deploy_token_events` | boolean | No | Trigger project webhook on project deploy token expiry events. | Update a project webhook ------------------------ History * `name` and `description` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887) in GitLab 17.1. Updates a project webhook for a specified project. PUT /projects/:id/hooks/:hook_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `url` | string | Yes | Project webhook URL. | | `branch_filter_strategy` | string | No | Filter push events by branch. Possible values are `wildcard` (default), `regex`, and `all_branches`. | | `custom_headers` | array | No | Custom headers for the project webhook. | | `custom_webhook_template` | string | No | Custom webhook template for the project webhook. | | `description` | string | No | Description of the project webhook. | | `confidential_issues_events` | boolean | No | Trigger project webhook on confidential issue events. | | `confidential_note_events` | boolean | No | Trigger project webhook on confidential note events. | | `deployment_events` | boolean | No | Trigger project webhook on deployment events. | | `enable_ssl_verification` | boolean | No | Do SSL verification when triggering the hook. | | `feature_flag_events` | boolean | No | Trigger project webhook on feature flag events. | | `issues_events` | boolean | No | Trigger project webhook on issue events. | | `job_events` | boolean | No | Trigger project webhook on job events. | | `merge_requests_events` | boolean | No | Trigger project webhook on merge request events. | | `milestone_events` | boolean | No | Trigger project webhook on milestone events. | | `name` | string | No | Name of the project webhook. | | `note_events` | boolean | No | Trigger project webhook on note events. | | `pipeline_events` | boolean | No | Trigger project webhook on pipeline events. | | `push_events` | boolean | No | Trigger project webhook on push events. | | `push_events_branch_filter` | string | No | Trigger project webhook on push events for matching branches only. | | `releases_events` | boolean | No | Trigger project webhook on release events. | | `resource_access_token_events` | boolean | No | Trigger project webhook on project access token expiry events. | | `tag_push_events` | boolean | No | Trigger project webhook on tag push events. | | `token` | string | No | Secret token to validate received payloads. Not returned in the response. When you change the webhook URL, the secret token is reset and not retained. | | `wiki_page_events` | boolean | No | Trigger project webhook on wiki page events. | | `resource_deploy_token_events` | boolean | No | Trigger project webhook on project deploy token expiry events. | Delete project webhook ---------------------- Remove a webhook from a project. This method is idempotent and can be called multiple times. The project webhook is either available or not. DELETE /projects/:id/hooks/:hook_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Note the JSON response differs if the project webhook is available or not. If the project hook is available before it’s returned in the JSON response or an empty response is returned. Trigger a test project webhook ------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147656) in GitLab 16.11. * Special rate limit [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150066) in GitLab 17.0 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `web_hook_test_api_endpoint_rate_limit`. Enabled by default. Trigger a test project webhook for a specified project. In GitLab 17.0 and later, this endpoint has a special rate limit: * In GitLab 17.0, the rate was three requests per minute for each project webhook. * In GitLab 17.1, this was changed to five requests per minute for each project and authenticated user. To disable this limit on GitLab Self-Managed and GitLab Dedicated, an administrator can [disable the feature flag](https://docs.gitlab.com/administration/feature_flags/) named `web_hook_test_api_endpoint_rate_limit`. POST /projects/:id/hooks/:hook_id/test/:trigger Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `trigger` | string | Yes | One of `push_events`, `tag_push_events`, `issues_events`, `confidential_issues_events`, `note_events`, `merge_requests_events`, `job_events`, `pipeline_events`, `wiki_page_events`, `releases_events`, `milestone_events`, `emoji_events`,`resource_access_token_events` or `resource_deploy_token_events`. | Example response: {"message":"201 Created"} Set a custom header ------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153768) in GitLab 17.1. PUT /projects/:id/hooks/:hook_id/custom_headers/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `key` | string | Yes | Key of the custom header. | | `value` | string | Yes | Value of the custom header. | On success, this endpoint returns the response code `204 No Content`. Delete a custom header ---------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153768) in GitLab 17.1. DELETE /projects/:id/hooks/:hook_id/custom_headers/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `key` | string | Yes | Key of the custom header. | On success, this endpoint returns the response code `204 No Content`. Set a URL variable ------------------ PUT /projects/:id/hooks/:hook_id/url_variables/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `key` | string | Yes | Key of the URL variable. | | `value` | string | Yes | Value of the URL variable. | On success, this endpoint returns the response code `204 No Content`. Delete a URL variable --------------------- DELETE /projects/:id/hooks/:hook_id/url_variables/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the project webhook. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `key` | string | Yes | Key of the URL variable. | On success, this endpoint returns the response code `204 No Content`. --- # Protected branches API | GitLab Docs * * * Protected branches API ====================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [protected branches](https://docs.gitlab.com/user/project/repository/branches/protected/) . GitLab Premium and GitLab Ultimate support more granular protections for pushing to branches. Administrators can grant permission to modify and push to protected branches only to deploy keys, instead of specific users. Valid access levels ------------------- The `ProtectedRefAccess.allowed_access_levels` method defines the following access levels used across push, merge, and unprotect configurations. * `0`: No access - Valid for push and merge access levels only. Not valid for unprotect access levels. * `30`: Developer * `40`: Maintainer * `60`: Administrator - Valid for GitLab Self-Managed only. In addition to role-based access levels, you can assign access by: * User (`user_id`): Valid for push, merge, and unprotect access levels. * Group (`group_id`): Valid for push, merge, and unprotect access levels. The group must have the Developer, Maintainer, or Owner role for the project. * Deploy key (`deploy_key_id`): Valid for push access levels only. For more information, see the [protect repository branches examples](https://docs.gitlab.com/api/protected_branches/#protect-repository-branches) . To avoid permanently locking protection settings for a branch, ensure at least one user or group retains unprotect permissions for the branch at all times. For more information, see [control who can unprotect branches](https://docs.gitlab.com/user/project/repository/branches/protected/#control-who-can-unprotect-branches) . List protected branches ----------------------- History * Deploy key information [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116846) in GitLab 16.0. Get a list of [protected branches](https://docs.gitlab.com/user/project/repository/branches/protected/) from a project as they are defined in the UI. If a wildcard is set, it is returned instead of the exact name of the branches that match that wildcard. GET /projects/:id/protected_branches Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `search` | string | No | Name or part of the name of protected branches to search for. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `allow_force_push` | boolean | If `true`, force push is allowed on this branch. | | `code_owner_approval_required` | boolean | If `true`, code owner approval is required for pushes to this branch. | | `id` | integer | ID of the protected branch. | | `inherited` | boolean | If `true`, protection settings are inherited from parent group. Premium and Ultimate only. | | `merge_access_levels` | array | Array of merge access level configurations. | | `merge_access_levels[].access_level` | integer | Access level for merging. | | `merge_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `merge_access_levels[].group_id` | integer | ID of the group with merge access. Premium and Ultimate only. | | `merge_access_levels[].id` | integer | ID of the merge access level configuration. | | `merge_access_levels[].user_id` | integer | ID of the user with merge access. Premium and Ultimate only. | | `name` | string | Name of the protected branch. | | `push_access_levels` | array | Array of push access level configurations. | | `push_access_levels[].access_level` | integer | Access level for pushing. | | `push_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `push_access_levels[].deploy_key_id` | integer | ID of the deploy key with push access. | | `push_access_levels[].group_id` | integer | ID of the group with push access. Premium and Ultimate only. | | `push_access_levels[].id` | integer | ID of the push access level configuration. | | `push_access_levels[].user_id` | integer | ID of the user with push access. Premium and Ultimate only. | In the following example request, the project ID is `5`. curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches" The following example response includes: * Two protected branches with IDs `100` and `101`. * `push_access_levels` with IDs `1001`, `1002`, and `1003`. * `merge_access_levels` with IDs `2001` and `2002`. [\ {\ "id": 100,\ "name": "main",\ "push_access_levels": [\ {\ "id": 1001,\ "access_level": 40,\ "access_level_description": "Maintainers"\ },\ {\ "id": 1002,\ "access_level": 40,\ "access_level_description": "Deploy key",\ "deploy_key_id": 1\ }\ ],\ "merge_access_levels": [\ {\ "id": 2001,\ "access_level": 40,\ "access_level_description": "Maintainers"\ }\ ],\ "allow_force_push":false,\ "code_owner_approval_required": false\ },\ {\ "id": 101,\ "name": "release/*",\ "push_access_levels": [\ {\ "id": 1003,\ "access_level": 40,\ "access_level_description": "Maintainers"\ }\ ],\ "merge_access_levels": [\ {\ "id": 2002,\ "access_level": 40,\ "access_level_description": "Maintainers"\ }\ ],\ "allow_force_push":false,\ "code_owner_approval_required": false\ }\ ] Users on GitLab Premium or Ultimate also see the `user_id`, `group_id`, and `inherited` parameters. If the `inherited` parameter exists, the setting was inherited from the project’s group. The following example response includes: * One protected branch with ID `100`. * `push_access_levels` with IDs `1001` and `1002`. * `merge_access_levels` with ID `2001`. [\ {\ "id": 101,\ "name": "main",\ "push_access_levels": [\ {\ "id": 1001,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ },\ {\ "id": 1002,\ "access_level": 40,\ "access_level_description": "Deploy key",\ "deploy_key_id": 1,\ "user_id": null,\ "group_id": null\ }\ ],\ "merge_access_levels": [\ {\ "id": 2001,\ "access_level": null,\ "user_id": null,\ "group_id": 1234,\ "access_level_description": "Example Merge Group"\ }\ ],\ "allow_force_push":false,\ "code_owner_approval_required": false,\ "inherited": true\ }\ ] Retrieve a protected branch or wildcard protected branch -------------------------------------------------------- Retrieves a specified protected branch or wildcard protected branch. GET /projects/:id/protected_branches/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the branch or wildcard. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `allow_force_push` | boolean | If `true`, force push is allowed on this branch. | | `code_owner_approval_required` | boolean | If `true`, code owner approval is required for pushes to this branch. | | `id` | integer | ID of the protected branch. | | `merge_access_levels` | array | Array of merge access level configurations. | | `merge_access_levels[].access_level` | integer | Access level for merging. | | `merge_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `merge_access_levels[].group_id` | integer | ID of the group with merge access. Premium and Ultimate only. | | `merge_access_levels[].id` | integer | ID of the merge access level configuration. | | `merge_access_levels[].user_id` | integer | ID of the user with merge access. Premium and Ultimate only. | | `name` | string | Name of the protected branch. | | `push_access_levels` | array | Array of push access level configurations. | | `push_access_levels[].access_level` | integer | Access level for pushing. | | `push_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `push_access_levels[].group_id` | integer | ID of the group with push access. Premium and Ultimate only. | | `push_access_levels[].id` | integer | ID of the push access level configuration. | | `push_access_levels[].user_id` | integer | ID of the user with push access. Premium and Ultimate only. | In the following example request, the project ID is `5` and branch name is `main`: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches/main" Example response: { "id": 101, "name": "main", "push_access_levels": [\ {\ "id": 1001,\ "access_level": 40,\ "access_level_description": "Maintainers"\ }\ ], "merge_access_levels": [\ {\ "id": 2001,\ "access_level": 40,\ "access_level_description": "Maintainers"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } Users on GitLab Premium or Ultimate also see the `user_id` and `group_id` parameters. Example response: { "id": 101, "name": "main", "push_access_levels": [\ {\ "id": 1001,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "merge_access_levels": [\ {\ "id": 2001,\ "access_level": null,\ "user_id": null,\ "group_id": 1234,\ "access_level_description": "Example Merge Group"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } Protect repository branches --------------------------- History * `deploy_key_id` configuration [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166598) in GitLab 17.5. * `deploy_key_id` configuration [moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/224542) from GitLab Premium to GitLab Free in GitLab 18.10. Protect a single repository branch or several project repository branches using a wildcard protected branch. POST /projects/:id/protected_branches Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the branch or wildcard. | | `allow_force_push` | boolean | No | If `true`, members who can push to this branch can also force push. Default is `false`. | | `allowed_to_merge` | array | No | Array of merge access levels, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. Premium and Ultimate only. | | `allowed_to_push` | array | No | Array of push access levels, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, `{deploy_key_id: integer}`, or `{access_level: integer}`. `user_id`, `group_id`, and `access_level` are Premium and Ultimate only. | | `allowed_to_unprotect` | array | No | Array of unprotect access levels, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. Access level `No access` is not available for this field. Premium and Ultimate only. | | `code_owner_approval_required` | boolean | No | If `true`, prevents pushes to this branch if it matches an item in the [`CODEOWNERS` file](https://docs.gitlab.com/user/project/codeowners/)
. Default is `false`. Premium and Ultimate only. | | `merge_access_level` | integer | No | Access levels allowed to merge. Default is `40` (Maintainer role). | | `push_access_level` | integer | No | Access levels allowed to push. Default is `40` (Maintainer role). | | `unprotect_access_level` | integer | No | Access levels allowed to unprotect. Default is `40` (Maintainer role). `0` (No access) is not valid. | When you configure access levels: * You can set multiple access levels simultaneously for `allowed_to_push` and `allowed_to_merge`. * The most permissive access level determines who can perform the action. * Do not include `id` in the `allowed_to_push`, `allowed_to_merge`, or `allowed_to_unprotect` arrays. The `id` field identifies an existing access level record and is only valid when you [update a protected branch](https://docs.gitlab.com/api/protected_branches/#update-a-protected-branch) . If you include an `id` that does not match an existing record, the API returns `404 Not Found`. This behavior differs from the UI, which automatically clears other role selections when you select **No one** (`access_level: 0`). If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `allow_force_push` | boolean | If `true`, force push is allowed on this branch. | | `code_owner_approval_required` | boolean | If `true`, code owner approval is required for pushes to this branch. | | `id` | integer | ID of the protected branch. | | `merge_access_levels` | array | Array of merge access level configurations. | | `merge_access_levels[].access_level` | integer | Access level for merging. | | `merge_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `merge_access_levels[].group_id` | integer | ID of the group with merge access. Premium and Ultimate only. | | `merge_access_levels[].id` | integer | ID of the merge access level configuration. | | `merge_access_levels[].user_id` | integer | ID of the user with merge access. Premium and Ultimate only. | | `name` | string | Name of the protected branch. | | `push_access_levels` | array | Array of push access level configurations. | | `push_access_levels[].access_level` | integer | Access level for pushing. | | `push_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `push_access_levels[].deploy_key_id` | integer | ID of the deploy key with push access. | | `push_access_levels[].group_id` | integer | ID of the group with push access. Premium and Ultimate only. | | `push_access_levels[].id` | integer | ID of the push access level configuration. | | `push_access_levels[].user_id` | integer | ID of the user with push access. Premium and Ultimate only. | | `unprotect_access_levels` | array | Array of unprotect access level configurations. | | `unprotect_access_levels[].access_level` | integer | Access level for unprotecting. | | `unprotect_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `unprotect_access_levels[].group_id` | integer | ID of the group with unprotect access. Premium and Ultimate only. | | `unprotect_access_levels[].id` | integer | ID of the unprotect access level configuration. | | `unprotect_access_levels[].user_id` | integer | ID of the user with unprotect access. Premium and Ultimate only. | In the following example request, the project ID is `5` and branch name is `*-stable`. curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches?name=*-stable&push_access_level=30&merge_access_level=30&unprotect_access_level=40" The example response includes: * A protected branch with ID `101`. * `push_access_levels` with ID `1001`. * `merge_access_levels` with ID `2001`. * `unprotect_access_levels` with ID `3001`. { "id": 101, "name": "*-stable", "push_access_levels": [\ {\ "id": 1001,\ "access_level": 30,\ "access_level_description": "Developers + Maintainers"\ }\ ], "merge_access_levels": [\ {\ "id": 2001,\ "access_level": 30,\ "access_level_description": "Developers + Maintainers"\ }\ ], "unprotect_access_levels": [\ {\ "id": 3001,\ "access_level": 40,\ "access_level_description": "Maintainers"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } Users on GitLab Premium or Ultimate also see the `user_id` and `group_id` parameters: The following example response includes: * A protected branch with ID `101`. * `push_access_levels` with ID `1001`. * `merge_access_levels` with ID `2001`. * `unprotect_access_levels` with ID `3001`. { "id": 1, "name": "*-stable", "push_access_levels": [\ {\ "id": 1001,\ "access_level": 30,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Developers + Maintainers"\ }\ ], "merge_access_levels": [\ {\ "id": 2001,\ "access_level": 30,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Developers + Maintainers"\ }\ ], "unprotect_access_levels": [\ {\ "id": 3001,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } ### Example with user push access and group merge access * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Elements in the `allowed_to_push` / `allowed_to_merge` / `allowed_to_unprotect` array should take the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. Each user must have access to the project and each group must [have this project shared](https://docs.gitlab.com/user/project/members/sharing_projects_groups/) . These access levels allow more granular control over protected branch access. For more information, see [configure group permissions](https://docs.gitlab.com/user/project/repository/branches/protected/#with-group-permissions) . The following example request creates a protected branch with user push access and group merge access. The `user_id` is `2` and the `group_id` is `3`. curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches?name=*-stable&allowed_to_push%5B%5D%5Buser_id%5D=2&allowed_to_merge%5B%5D%5Bgroup_id%5D=3" The following example response includes: * A protected branch with ID `101`. * `push_access_levels` with ID `1001`. * `merge_access_levels` with ID `2001`. * `unprotect_access_levels` with ID `3001`. { "id": 101, "name": "*-stable", "push_access_levels": [\ {\ "id": 1001,\ "access_level": null,\ "user_id": 2,\ "group_id": null,\ "access_level_description": "Administrator"\ }\ ], "merge_access_levels": [\ {\ "id": 2001,\ "access_level": null,\ "user_id": null,\ "group_id": 3,\ "access_level_description": "Example Merge Group"\ }\ ], "unprotect_access_levels": [\ {\ "id": 3001,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } ### Example with deploy key access History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166598) in GitLab 17.5. * [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/224542) from GitLab Premium to GitLab Free in GitLab 18.10. Elements in the `allowed_to_push` array should take the form `{user_id: integer}`, `{group_id: integer}`, `{deploy_key_id: integer}`, or `{access_level: integer}`. The deploy key must be enabled for your project and it must have write access to your project repository. For other requirements, see [allow deploy keys to push to a protected branch](https://docs.gitlab.com/user/project/repository/branches/protected/#enable-deploy-key-access) . Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches?name=*-stable&allowed_to_push[][deploy_key_id]=1" The following example response includes: * A protected branch with ID `101`. * `push_access_levels` with ID `1001`. * `merge_access_levels` with ID `2001`. * `unprotect_access_levels` with ID `3001`. { "id": 101, "name": "*-stable", "push_access_levels": [\ {\ "id": 1001,\ "access_level": null,\ "user_id": null,\ "group_id": null,\ "deploy_key_id": 1,\ "access_level_description": "Deploy"\ }\ ], "merge_access_levels": [\ {\ "id": 2001,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "unprotect_access_levels": [\ {\ "id": 3001,\ "access_level": 40,\ "user_id": null,\ "group_id": null,\ "access_level_description": "Maintainers"\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } ### Example with allow to push and allow to merge access * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * Moved to GitLab Premium in 13.9. Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "name": "main", "allowed_to_push": [\ {"access_level": 30}\ ], "allowed_to_merge": [\ {"access_level": 30},\ {"access_level": 40}\ ] }' \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches" The following example response includes: * A protected branch with ID `105`. * `push_access_levels` with ID `1001`. * `merge_access_levels` with IDs `2001` and `2002`. * `unprotect_access_levels` with ID `3001`. { "id": 105, "name": "main", "push_access_levels": [\ {\ "id": 1001,\ "access_level": 30,\ "access_level_description": "Developers + Maintainers",\ "user_id": null,\ "group_id": null\ }\ ], "merge_access_levels": [\ {\ "id": 2001,\ "access_level": 30,\ "access_level_description": "Developers + Maintainers",\ "user_id": null,\ "group_id": null\ },\ {\ "id": 2002,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ], "unprotect_access_levels": [\ {\ "id": 3001,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ], "allow_force_push":false, "code_owner_approval_required": false } ### Examples with unprotect access levels * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated To create a protected branch where only a specific group can unprotect the branch: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "name": "production", "allowed_to_unprotect": [\ {"group_id": 789}\ ] }' \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches" To allow multiple types of users to unprotect a branch: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "name": "main", "allowed_to_unprotect": [\ {"user_id": 123},\ {"group_id": 456},\ {"access_level": 40}\ ] }' \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches" This configuration allows these users to unprotect the branch: * The user with ID `123`. * Members of the group with ID `456`. * Users with the Maintainer or Owner role (access level 40). Unprotect repository branches ----------------------------- Unprotect the given protected branch or wildcard protected branch. DELETE /projects/:id/protected_branches/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the branch. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . In the following example request, the project ID is `5` and branch name is `*-stable`: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches/*-stable" Update a protected branch ------------------------- History * `deploy_key_id` configuration [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166598) in GitLab 17.5. Update a protected branch. PATCH /projects/:id/protected_branches/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the branch or wildcard. | | `allow_force_push` | boolean | No | If `true`, members who can push to this branch can also force push. | | `allowed_to_merge` | array | No | Array of merge access levels, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, or `{access_level: integer}`. Premium and Ultimate only. | | `allowed_to_push` | array | No | Array of push access levels, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, `{deploy_key_id: integer}`, or `{access_level: integer}`. `user_id`, `group_id`, and `access_level` are Premium and Ultimate only. | | `allowed_to_unprotect` | array | No | Array of unprotect access levels, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, `{access_level: integer}`, or `{id: integer, _destroy: true}` to destroy an existing access level. Access level `No access` is not available for this field. Premium and Ultimate only. | | `code_owner_approval_required` | boolean | No | If `true`, prevents pushes to this branch if it matches an item in the [`CODEOWNERS` file](https://docs.gitlab.com/user/project/codeowners/)
. Premium and Ultimate only. | For information about how access levels interact when you set multiple values, see [protect repository branches](https://docs.gitlab.com/api/protected_branches/#protect-repository-branches) . If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `allow_force_push` | boolean | If `true`, force push is allowed on this branch. | | `code_owner_approval_required` | boolean | If `true`, code owner approval is required for pushes to this branch. | | `id` | integer | ID of the protected branch. | | `merge_access_levels` | array | Array of merge access level configurations. | | `merge_access_levels[].access_level` | integer | Access level for merging. | | `merge_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `merge_access_levels[].group_id` | integer | ID of the group with merge access. Premium and Ultimate only. | | `merge_access_levels[].id` | integer | ID of the merge access level configuration. | | `merge_access_levels[].user_id` | integer | ID of the user with merge access. Premium and Ultimate only. | | `name` | string | Name of the protected branch. | | `push_access_levels` | array | Array of push access level configurations. | | `push_access_levels[].access_level` | integer | Access level for pushing. | | `push_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `push_access_levels[].deploy_key_id` | integer | ID of the deploy key with push access. | | `push_access_levels[].group_id` | integer | ID of the group with push access. Premium and Ultimate only. | | `push_access_levels[].id` | integer | ID of the push access level configuration. | | `push_access_levels[].user_id` | integer | ID of the user with push access. Premium and Ultimate only. | | `unprotect_access_levels` | array | Array of unprotect access level configurations. | | `unprotect_access_levels[].access_level` | integer | Access level for unprotecting. | | `unprotect_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `unprotect_access_levels[].group_id` | integer | ID of the group with unprotect access. Premium and Ultimate only. | | `unprotect_access_levels[].id` | integer | ID of the unprotect access level configuration. | | `unprotect_access_levels[].user_id` | integer | ID of the user with unprotect access. Premium and Ultimate only. | Example request: curl --request PATCH \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches/feature-branch?allow_force_push=true&code_owner_approval_required=true" Elements in the `allowed_to_push`, `allowed_to_merge`, and `allowed_to_unprotect` arrays should be one of `user_id`, `group_id`, or `access_level`, and take the form `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}`. `allowed_to_push` includes an extra element, `deploy_key_id`, that takes the form `{deploy_key_id: integer}`. To update: * `user_id`: Ensure the updated user has access to the project. Include the access level record’s `id` in the hash. * `group_id`: Ensure the updated group [has this project shared](https://docs.gitlab.com/user/project/members/sharing_projects_groups/) . Include the access level record’s `id` in the hash. * `deploy_key_id`: Ensure the deploy key is enabled for your project and has write access to your project repository. To update any other field on an existing access level record, include the record’s `id` in the hash. To delete, you must pass `_destroy` set to `true`. See the following examples. ### Example: create a `push_access_level` record curl --header 'Content-Type: application/json' --request PATCH \ --data '{"allowed_to_push": [{"access_level": 40}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_branches/main" Example response: { "name": "main", "push_access_levels": [\ {\ "id": 12,\ "access_level": 40,\ "access_level_description": "Maintainers",\ "user_id": null,\ "group_id": null\ }\ ] } ### Example: update a `push_access_level` record curl --header 'Content-Type: application/json' --request PATCH \ --data '{"allowed_to_push": [{"id": 12, "access_level": 0}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_branches/main" Example response: { "name": "main", "push_access_levels": [\ {\ "id": 12,\ "access_level": 0,\ "access_level_description": "No One",\ "user_id": null,\ "group_id": null\ }\ ] } ### Example: delete a `push_access_level` record curl --header 'Content-Type: application/json' --request PATCH \ --data '{"allowed_to_push": [{"id": 12, "_destroy": true}]}' \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/22034114/protected_branches/main" Example response: { "name": "main", "push_access_levels": [] } ### Example: update an `unprotect_access_level` record Prerequisites: * Users calling this API must be included in the `allowed_to_unprotect` configuration. * The user specified by `user_id` must be a project member. * Groups specified by `group_id` must have access to the project. To modify who can unprotect an existing protected branch, include the `id` of the existing access level record. For example: curl --request PATCH \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{ "allowed_to_unprotect": [\ {"id": 17486, "user_id": 3791}\ ] }' \ --url "https://gitlab.example.com/api/v4/projects/5/protected_branches/main" To remove specific access levels, use `_destroy: true`. Related topics -------------- * [Protected branches](https://docs.gitlab.com/user/project/repository/branches/protected/) * [Branches](https://docs.gitlab.com/user/project/repository/branches/) * [Branches API](https://docs.gitlab.com/api/branches/) --- # Project import and export API | GitLab Docs * * * Project import and export API ============================= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to [migrate a project](https://docs.gitlab.com/user/project/settings/import_export/) . If you first migrate the parent group structure with the [group import and export API](https://docs.gitlab.com/api/group_import_export/) , you can preserve group-level relationships, such as connections between project issues and group epics. After using this API, you might want to use the [project-level CI/CD variables API](https://docs.gitlab.com/api/project_level_variables/) to preserve the CI/CD variables for the project. You must still migrate your [container registry](https://docs.gitlab.com/user/packages/container_registry/) over a series of Docker pulls and pushes. Re-run any CI/CD pipelines to retrieve any build artifacts. Prerequisites: * For project exports, see [export a project and its data](https://docs.gitlab.com/user/project/settings/import_export/#export-a-project-and-its-data) . * For project imports, see [import a project and its data](https://docs.gitlab.com/user/project/settings/import_export/#import-a-project-and-its-data) . Export a project ---------------- Exports the specified project. Use the `upload` hash parameter to upload the exported project to a web server or any S3-compatible platform. For exports, GitLab: * Only supports binary data file uploads to the final server. * Sends the `Content-Type: application/gzip` header with upload requests. Ensure that your pre-signed URL includes this as part of the signature. * Can take some time to complete the project export process. Make sure the upload URL doesn’t have a short expiration time and is available throughout the export process. * Administrators can modify the maximum export file size. By default, the maximum is unlimited (`0`). To change this, edit `max_export_size` using either: * [GitLab UI](https://docs.gitlab.com/administration/settings/import_and_export_settings/) . * [Application settings API](https://docs.gitlab.com/api/settings/#update-application-settings) * Has a fixed limit for the maximum import file size on GitLab.com. For more information, see [account and limit settings](https://docs.gitlab.com/user/gitlab_com/#account-and-limit-settings) . The `upload[url]` parameter is required if the `upload` parameter is present. For uploads to Amazon S3, refer to [generating a pre-signed URL for uploading objects](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html) documentation scripts to generate the `upload[url]`. Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/430277) , you can only upload files with a maximum file size of 5 GB to Amazon S3. POST /projects/:id/export | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `upload[url]` | string | Yes | The URL to upload the project. | | `description` | string | No | Overrides the project description. | | `upload` | hash | No | Hash that contains the information to upload the exported project to a web server. | | `upload[http_method]` | string | No | The HTTP method to upload the exported project. Only `PUT` and `POST` methods allowed. Default is `PUT`. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/export" \ --data "upload[http_method]=PUT" \ --data-urlencode "upload[url]=https://example-bucket.s3.eu-west-3.amazonaws.com/backup?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=%2F20180312%2Feu-west-3%2Fs3%2Faws4_request&X-Amz-Date=20180312T110328Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=8413facb20ff33a49a147a0b4abcff4c8487cc33ee1f7e450c46e8f695569dbd" { "message": "202 Accepted" } Retrieve the status of a project export --------------------------------------- Retrieves the status of the most recent export for a specified project. GET /projects/:id/export | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/export" Status can be one of: * `none`: No exports queued, started, finished, or being regenerated. * `queued`: The request for export is received, and is in the queue to be processed. * `started`: The export process has started and is in progress. It includes: * The process of exporting. * Actions performed on the resulting file, such as sending an email notifying the user to download the file, or uploading the exported file to a web server. * `finished`: After the export process has completed and the user has been notified. * `regeneration_in_progress`: An export file is available to download, and a request to generate a new export is in process. `_links` are only present when export has finished. `created_at` is the project create timestamp, not the export start time. { "id": 1, "description": "Itaque perspiciatis minima aspernatur corporis consequatur.", "name": "Gitlab Test", "name_with_namespace": "Gitlab Org / Gitlab Test", "path": "gitlab-test", "path_with_namespace": "gitlab-org/gitlab-test", "created_at": "2017-08-29T04:36:44.383Z", "export_status": "finished", "_links": { "api_url": "https://gitlab.example.com/api/v4/projects/1/export/download", "web_url": "https://gitlab.example.com/gitlab-org/gitlab-test/download_export" } } Download a project export ------------------------- Downloads the most recent export of a specified project. GET /projects/:id/export/download | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --remote-header-name \ --remote-name \ --url "https://gitlab.example.com/api/v4/projects/5/export/download" ls *export.tar.gz 2017-12-05_22-11-148_namespace_project_export.tar.gz Import a project from a local archive ------------------------------------- History * Requirement for Maintainer role instead of Developer role introduced in GitLab 16.0. * `namespace_id` and `namespace_path` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/511053) in GitLab 18.7. Imports a project from a local archive. POST /projects/import | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `file` | string | Yes | The file to be uploaded. | | `path` | string | Yes | Name and path for new project. | | `name` | string | No | The name of the project to be imported. Defaults to the path of the project if not provided. | | `namespace` | integer or string | No | (Deprecated) The ID or path of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. Use `namespace_id` or `namespace_path` instead. | | `namespace_id` | integer | No | The ID of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. | | `namespace_path` | string | No | The path of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. | | `override_params` | hash | No | Supports all fields defined in the [project API](https://docs.gitlab.com/api/projects/)
. | | `overwrite` | boolean | No | If there is a project with the same path the import overwrites it. Defaults to `false`. | The override parameters passed take precedence over all values defined inside the export file. To upload a file from your file system, use the `--form` argument. This causes cURL to post data using the header `Content-Type: multipart/form-data`. The `file=` parameter must point to a file on your file system and be preceded by `@`. For example: curl --request POST \ --header "PRIVATE-TOKEN: " \ --form "path=api-project" \ --form "file=@/path/to/file" \ --url "https://gitlab.example.com/api/v4/projects/import" cURL doesn’t support posting a file from a remote server. This example imports a project using Python’s `open` method: import requests url = 'https://gitlab.example.com/api/v4/projects/import' files = { "file": open("project_export.tar.gz", "rb") } data = { "path": "example-project", "namespace_path": "example-group" } headers = { 'Private-Token': "" } requests.post(url, headers=headers, data=data, files=files) { "id": 1, "description": null, "name": "api-project", "name_with_namespace": "Administrator / api-project", "path": "api-project", "path_with_namespace": "root/api-project", "created_at": "2018-02-13T09:05:58.023Z", "import_status": "scheduled", "correlation_id": "mezklWso3Za", "failed_relations": [] } The maximum import file size can be set by the Administrator. It defaults to `0` (unlimited). As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [application settings API](https://docs.gitlab.com/api/settings/#update-application-settings) or the [**Admin** area](https://docs.gitlab.com/administration/settings/account_and_limit_settings/) . Import a project from a remote archive -------------------------------------- * Status: Beta History * `namespace_id` and `namespace_path` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/511053) in GitLab 18.7. On GitLab Self-Managed, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](https://docs.gitlab.com/administration/feature_flags/) named `import_project_from_remote_file`. On GitLab.com and GitLab Dedicated, this feature is available. Imports a project from a remote archive. POST /projects/remote-import | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `path` | string | Yes | Name and path for the new project. | | `url` | string | Yes | URL for the file to import. | | `name` | string | No | The name of the project to import. If not provided, defaults to the path of the project. | | `namespace` | integer or string | No | (Deprecated) The ID or path of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. Use `namespace_id` or `namespace_path` instead. | | `namespace_id` | integer | No | The ID of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. | | `namespace_path` | string | No | The path of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. | | `overwrite` | boolean | No | Whether to overwrite a project with the same path when importing. Defaults to `false`. | | `override_params` | hash | No | Supports all fields defined in the [project API](https://docs.gitlab.com/api/projects/)
. | The passed override parameters take precedence over all values defined in the export file. curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/projects/remote-import" \ --data '{"url":"https://remoteobject/file?token=123123","path":"remote-project"}' { "id": 1, "description": null, "name": "remote-project", "name_with_namespace": "Administrator / remote-project", "path": "remote-project", "path_with_namespace": "root/remote-project", "created_at": "2018-02-13T09:05:58.023Z", "import_status": "scheduled", "correlation_id": "mezklWso3Za", "failed_relations": [], "import_error": null } The `Content-Length` header must return a valid number. The maximum file size is 10 GB. The `Content-Type` header must be `application/gzip`. Import a project from an AWS S3 bucket -------------------------------------- History * `namespace_id` and `namespace_path` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/511053) in GitLab 18.7. Imports a project from an archive stored in a specified AWS S3 bucket. POST /projects/remote-import-s3 | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `access_key_id` | string | Yes | [AWS S3 access key ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)
. | | `bucket_name` | string | Yes | [AWS S3 bucket name](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html)
where the file is stored. | | `file_key` | string | Yes | [AWS S3 file key](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingObjects.html)
to identify the file. | | `path` | string | Yes | The full path of the new project. | | `region` | string | Yes | [AWS S3 region name](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html#Regions)
where the file is stored. | | `secret_access_key` | string | Yes | [AWS S3 secret access key](https://docs.aws.amazon.com/IAM/latest/UserGuide/security-creds.html#access-keys-and-secret-access-keys)
. | | `name` | string | No | The name of the project to import. If not provided, defaults to the path of the project. | | `namespace` | integer or string | No | (Deprecated) The ID or path of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. Use `namespace_id` or `namespace_path` instead. | | `namespace_id` | integer | No | The ID of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. | | `namespace_path` | string | No | The path of the namespace to import the project to. Defaults to the current user’s namespace.

Requires the Maintainer or Owner role on the destination group. | The passed override parameters take precedence over all values defined in the export file. curl --request POST \ --url "https://gitlab.example.com/api/v4/projects/remote-import-s3" \ --header "PRIVATE-TOKEN: " \ --header 'Content-Type: application/json' \ --data '{ "name": "Sample Project", "path": "sample-project", "region": "", "bucket_name": "", "file_key": "", "access_key_id": "", "secret_access_key": "" }' This example imports from an Amazon S3 bucket, using a module that connects to Amazon S3: import requests from io import BytesIO s3_file = requests.get(presigned_url) url = 'https://gitlab.example.com/api/v4/projects/import' files = {'file': ('file.tar.gz', BytesIO(s3_file.content))} data = { "path": "example-project", "namespace_path": "example-group" } headers = { 'Private-Token': "" } requests.post(url, headers=headers, data=data, files=files) { "id": 1, "description": null, "name": "Sample project", "name_with_namespace": "Administrator / sample-project", "path": "sample-project", "path_with_namespace": "root/sample-project", "created_at": "2018-02-13T09:05:58.023Z", "import_status": "scheduled", "correlation_id": "mezklWso3Za", "failed_relations": [], "import_error": null } Retrieve the status of a project import --------------------------------------- Retrieves the status of the most recent import for a specified project. GET /projects/:id/import | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/import" Status can be one of: * `none` * `scheduled` * `failed` * `started` * `finished` If the status is `failed`, it includes the import error message under `import_error`. If the status is `failed`, `started` or `finished`, the `failed_relations` array might be populated with any occurrences of relations that failed to import due to either: * Unrecoverable errors. * Retries were exhausted. A typical example: query timeouts. An element’s `id` field in `failed_relations` references the failure record, not the relation. Also, the `failed_relations` array is capped to 100 items. { "id": 1, "description": "Itaque perspiciatis minima aspernatur corporis consequatur.", "name": "Gitlab Test", "name_with_namespace": "Gitlab Org / Gitlab Test", "path": "gitlab-test", "path_with_namespace": "gitlab-org/gitlab-test", "created_at": "2017-08-29T04:36:44.383Z", "import_status": "started", "import_type": "github", "correlation_id": "mezklWso3Za", "failed_relations": [\ {\ "id": 42,\ "created_at": "2020-04-02T14:48:59.526Z",\ "exception_class": "RuntimeError",\ "exception_message": "A failure occurred",\ "source": "custom error context",\ "relation_name": "merge_requests",\ "line_number": 0\ }\ ] } When importing from GitHub, the a `stats` field lists how many objects were already fetched from GitHub and how many were already imported: { "id": 1, "description": "Itaque perspiciatis minima aspernatur corporis consequatur.", "name": "Gitlab Test", "name_with_namespace": "Gitlab Org / Gitlab Test", "path": "gitlab-test", "path_with_namespace": "gitlab-org/gitlab-test", "created_at": "2017-08-29T04:36:44.383Z", "import_status": "started", "import_type": "github", "correlation_id": "mezklWso3Za", "failed_relations": [\ {\ "id": 42,\ "created_at": "2020-04-02T14:48:59.526Z",\ "exception_class": "RuntimeError",\ "exception_message": "A failure occurred",\ "source": "custom error context",\ "relation_name": "merge_requests",\ "line_number": 0\ }\ ], "stats": { "fetched": { "diff_note": 19, "issue": 3, "label": 1, "note": 3, "pull_request": 2, "pull_request_merged_by": 1, "pull_request_review": 16 }, "imported": { "diff_note": 19, "issue": 3, "label": 1, "note": 3, "pull_request": 2, "pull_request_merged_by": 1, "pull_request_review": 16 } } } Import project resources ------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/425798) as a [beta](https://docs.gitlab.com/policy/development_stages_support/#beta) in GitLab 16.11 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `single_relation_import`. Disabled by default. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/455889) in GitLab 17.1. Feature flag `single_relation_import` removed. Imports [project resources](https://docs.gitlab.com/user/project/settings/import_export/#project-items-that-are-exported) included with a project archive. The type of item to import is controlled by the `relation` attribute. Skips items that were previously imported. The required project export file adheres to the same structure and size requirements described in [import a project from a local archive](https://docs.gitlab.com/api/project_import_export/#import-a-project-from-a-local-archive) . * The extracted files must adhere to the structure of a GitLab project export. * The archive must not exceed the maximum import file size configured by the Administrator. POST /projects/import-relation | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `file` | string | Yes | The file to be uploaded. | | `path` | string | Yes | Name and path for new project. | | `relation` | string | Yes | The name of the relation to import. Must be one of `issues`, `milestones`, `ci_pipelines` or `merge_requests`. | To upload a file from your file system, use the `--form` option, which causes cURL to post data using the header `Content-Type: multipart/form-data`. The `file=` parameter must point to a file on your file system and be preceded by `@`. For example: curl --request POST \ --header "PRIVATE-TOKEN: " \ --form "path=api-project" \ --form "file=@/path/to/file" \ --form "relation=issues" \ --url "https://gitlab.example.com/api/v4/projects/import-relation" { "id": 9, "project_path": "namespace1/project1", "relation": "issues", "status": "finished" } Retrieve the status of a project resource import ------------------------------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/425798) in GitLab 16.11. Retrieves the status of the most recent relation import for a specified project. Because only one relation import can be scheduled at a time, you can use this endpoint to check whether the previous import completed successfully. GET /projects/:id/relation-imports | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/18/relation-imports" [\ {\ "id": 1,\ "project_path": "namespace1/project1",\ "relation": "issues",\ "status": "created",\ "created_at": "2024-03-25T11:03:48.074Z",\ "updated_at": "2024-03-25T11:03:48.074Z"\ }\ ] Status can be one of: * `created`: The import has been scheduled, but has not started. * `started`: The import is being processed. * `finished`: The import has completed. * `failed`: The import was not able to be completed. --- # Run GraphQL API queries and mutations | GitLab Docs * * * Run GraphQL API queries and mutations ===================================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated This guide demonstrates basic usage of the GitLab GraphQL API. Running examples ---------------- The examples documented here can be run using: * [GraphiQL](https://docs.gitlab.com/api/graphql/getting_started/#graphiql) . * [Command line](https://docs.gitlab.com/api/graphql/getting_started/#command-line) . * [Rails console](https://docs.gitlab.com/api/graphql/getting_started/#rails-console) . ### GraphiQL GraphiQL (pronounced “graphical”) allows you to run real GraphQL queries against the API interactively. It makes exploring the schema easier by providing a UI with syntax highlighting and autocompletion. For most people, using GraphiQL will be the easiest way to explore the GitLab GraphQL API. You can either use GraphiQL: * [On GitLab.com](https://gitlab.com/-/graphql-explorer) . * On GitLab Self-Managed on `https:///-/graphql-explorer`. Sign in to GitLab first to authenticate the requests with your GitLab account. To get started, refer to the [example queries and mutations](https://docs.gitlab.com/api/graphql/getting_started/#queries-and-mutations) . ### Command line You can run GraphQL queries in a `curl` request on the command line on your local computer. The requests `POST` to `/api/graphql` with the query as the payload. You can authorize your request by generating a [personal access token](https://docs.gitlab.com/user/profile/personal_access_tokens/) to use as a bearer token. Read more about [GraphQL Authentication](https://docs.gitlab.com/api/graphql/#authentication) . Example: GRAPHQL_TOKEN= curl --request POST \ --url "https://gitlab.com/api/graphql" \ --header "Authorization: Bearer $GRAPHQL_TOKEN" \ --header "Content-Type: application/json" \ --data "{\"query\": \"query {currentUser {name}}\"}" To nest strings in the query string, wrap the data in single quotes or escape the strings with `\\`: curl --request POST \ --url "https://gitlab.com/api/graphql" \ --header "Authorization: Bearer $GRAPHQL_TOKEN" \ --header "Content-Type: application/json" \ --data '{"query": "query {project(fullPath: \"//\") {jobs {nodes {id duration}}}}"}' # or "{\"query\": \"query {project(fullPath: \\\"//\\\") {jobs {nodes {id duration}}}}\"}" ### Rails console * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated GraphQL queries can be run in a [Rails console session](https://docs.gitlab.com/administration/operations/rails_console/#starting-a-rails-console-session) . For example, to search projects: current_user = User.find_by_id(1) query = <<~EOQ query securityGetProjects($search: String!) { projects(search: $search) { nodes { path } } } EOQ variables = { "search": "gitlab" } result = GitlabSchema.execute(query, variables: variables, context: { current_user: current_user }) result.to_h Queries and mutations --------------------- The GitLab GraphQL API can be used to perform: * Queries for data retrieval. * [Mutations](https://docs.gitlab.com/api/graphql/getting_started/#mutations) for creating, updating, and deleting data. In the GitLab GraphQL API, `id` refers to a [Global ID](https://graphql.org/learn/global-object-identification/) , which is an object identifier in the format of `"gid://gitlab/Issue/123"`. For more information, see [Global IDs](https://docs.gitlab.com/api/graphql/#global-ids) . [GitLab GraphQL Schema](https://docs.gitlab.com/api/graphql/reference/) outlines which objects and fields are available for clients to query and their corresponding data types. Example: Get only the names of all the projects the currently authenticated user can access (up to a limit) in the group `gitlab-org`. query { group(fullPath: "gitlab-org") { id name projects { nodes { name } } } } Example: Get a specific project and the title of Issue #2. query { project(fullPath: "gitlab-org/graphql-sandbox") { name issue(iid: "2") { title } } } ### Graph traversal When retrieving child nodes use: * The `edges { node { } }` syntax. * The short form `nodes { }` syntax. Underneath it all is a graph you are traversing, hence the name GraphQL. Example: Get the name of a project, and the titles of all its issues. query { project(fullPath: "gitlab-org/graphql-sandbox") { name issues { nodes { title description } } } } More about queries: [GraphQL documentation](https://graphql.org/learn/queries/) ### Authorization If you’ve signed in to GitLab and use [GraphiQL](https://docs.gitlab.com/api/graphql/getting_started/#graphiql) , all queries are performed as you, the authenticated user. For more information, read about [GraphQL Authentication](https://docs.gitlab.com/api/graphql/#authentication) . ### Mutations Mutations make changes to data. We can update, delete, or create new records. Mutations generally use InputTypes and variables, neither of which appear here. Mutations have: * Inputs. For example, arguments, such as which emoji reaction you’d like to add, and to which object. * Return statements. That is, what you’d like to get back when it’s successful. * Errors. Always ask for what went wrong, just in case. #### Creation mutations Example: Let’s have some tea - add a `:tea:` reaction emoji to an issue. mutation { awardEmojiAdd(input: { awardableId: "gid://gitlab/Issue/27039960", name: "tea" }) { awardEmoji { name description unicode emoji unicodeVersion user { name } } errors } } Example: Add a comment to the issue. This example uses the ID of the `GitLab.com` issue. If you’re using a local instance, you must get the ID of an issue you can write to. mutation { createNote(input: { noteableId: "gid://gitlab/Issue/27039960", body: "*sips tea*" }) { note { id body discussion { id } } errors } } #### Update mutations When you see the result `id` of the note you created, take a note of it. Let’s edit it to sip faster. mutation { updateNote(input: { id: "gid://gitlab/Note/", body: "*SIPS TEA*" }) { note { id body } errors } } #### Deletion mutations Let’s delete the comment, because our tea is all gone. mutation { destroyNote(input: { id: "gid://gitlab/Note/" }) { note { id body } errors } } You should get something like the following output: { "data": { "destroyNote": { "errors": [], "note": null } } } The requested note doesn’t exist anymore, so the returned value for that field is `null`. More about mutations: [GraphQL Documentation](https://graphql.org/learn/queries/#mutations) . ### Update project settings You can update multiple project settings in a single GraphQL mutation. This example is a workaround for [the major change](https://docs.gitlab.com/update/deprecations/#cicd-job-token---authorized-groups-and-projects-allowlist-enforcement) in `CI_JOB_TOKEN` scoping behavior. mutation DisableCI_JOB_TOKENscope { projectCiCdSettingsUpdate(input:{fullPath: "/", inboundJobTokenScopeEnabled: false}) { ciCdSettings { inboundJobTokenScopeEnabled } errors } } ### Introspection queries Clients can query the GraphQL endpoint for information about its schema by making an [introspection query](https://graphql.org/learn/introspection/) . These queries are intended for use as a discovery and diagnostic tool. * In development and test environments, introspection queries execute against the live schema. * In production environments, introspection queries return a static schema. * Introspection queries should not be used to fetch data in production environments. For more information, see: * [GraphQL Introspection in Production](https://graphql.org/learn/introspection/#introspection-in-production) * [Apollo Introspection in Production](https://www.apollographql.com/blog/why-you-should-disable-graphql-introspection-in-production#what-do-we-need-introspection-for) * All introspection queries return the same static response, regardless of the request method or parameters. * The static schema is updated automatically to match the current schema. * Introspection queries return one of two static schema files: * `public/-/graphql/introspection_result.json`: Full schema, including deprecated fields. * `public/-/graphql/introspection_result_no_deprecated.json`: Schema without deprecated fields. To request the schema, send the following in the request body: { "query": "{ __schema { types { name } } }" } To request the schema without deprecated fields, include `remove_deprecated: true` in the request body: { "query": "{ __schema { types { name } } }", "remove_deprecated": true } #### GraphiQL introspection queries The [GraphiQL Query Explorer](https://docs.gitlab.com/api/graphql/getting_started/#graphiql) uses an introspection query to: * Gain knowledge about the GitLab GraphQL schema. * Do autocompletion. * Provide its interactive `Docs` tab. More about introspection: [GraphQL documentation](https://graphql.org/learn/introspection/) ### Query complexity The calculated [complexity score and limit](https://docs.gitlab.com/api/graphql/#maximum-query-complexity) for a query can be revealed to clients by querying for `queryComplexity`. query { queryComplexity { score limit } project(fullPath: "gitlab-org/graphql-sandbox") { name } } Sorting ------- Some of the GitLab GraphQL endpoints allow you to specify how to sort a collection of objects. You can only sort by what the schema allows you to. Example: Issues can be sorted by creation date: query { project(fullPath: "gitlab-org/graphql-sandbox") { name issues(sort: created_asc) { nodes { title createdAt } } } } Pagination ---------- Pagination is a way of only asking for a subset of the records, such as the first ten. If you want more of them, you can make another request for the next ten from the server in the form of something like `give me the next ten records`. By default, the GitLab GraphQL API returns 100 records per page. To change this behavior, use `first` or `last` arguments. Both arguments take a value, so `first: 10` returns the first ten records, and `last: 10` the last ten records. There is a limit on how many records are returned per page, which is generally `100`. Example: Retrieve only the first two issues (slicing). The `cursor` field gives you a position from which you can retrieve further records relative to that one. query { project(fullPath: "gitlab-org/graphql-sandbox") { name issues(first: 2) { edges { node { title } } pageInfo { endCursor hasNextPage } } } } Example: Retrieve the next three. (The cursor value `eyJpZCI6IjI3MDM4OTMzIiwiY3JlYXRlZF9hdCI6IjIwMTktMTEtMTQgMDU6NTY6NDQgVVRDIn0` could be different, but it’s the `cursor` value returned for the second issue returned above.) query { project(fullPath: "gitlab-org/graphql-sandbox") { name issues(first: 3, after: "eyJpZCI6IjI3MDM4OTMzIiwiY3JlYXRlZF9hdCI6IjIwMTktMTEtMTQgMDU6NTY6NDQgVVRDIn0") { edges { node { title } cursor } pageInfo { endCursor hasNextPage } } } } More about pagination and cursors: [GraphQL documentation](https://graphql.org/learn/pagination/) File uploads ------------ Some mutations accept file uploads as arguments. These mutations use the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec) , which allows you to send files alongside your GraphQL operations using `multipart/form-data` requests. Mutations that support file uploads have arguments of type `Upload`. You can identify these mutations in the [GraphQL API reference](https://docs.gitlab.com/api/graphql/reference/) by looking for arguments with the `Upload` scalar type. File upload mutations cannot be run through [GraphiQL](https://docs.gitlab.com/api/graphql/getting_started/#graphiql) . You must use a [command-line](https://docs.gitlab.com/api/graphql/getting_started/#command-line) tool like `curl` or a compatible GraphQL client library. A multipart upload request has three key parts: * `operations`: A JSON string containing the GraphQL query and variables, with file values set to `null`. * `map`: A JSON object that maps file keys to the variable paths in the operations. * The file fields themselves, referenced by the keys used in `map`. To upload a design to an issue using the `designManagementUpload` mutation: GRAPHQL_TOKEN= curl --request POST \ --url "https://gitlab.com/api/graphql" \ --header "Authorization: Bearer $GRAPHQL_TOKEN" \ --form 'operations={"query": "mutation ($files: [Upload!]!, $projectPath: ID!, $iid: ID!) { designManagementUpload(input: { projectPath: $projectPath, iid: $iid, files: $files }) { designs { filename } errors } }", "variables": {"files": [null], "projectPath": "/", "iid": ""}}' \ --form 'map={"0": ["variables.files.0"]}' \ --form '0=@/path/to/your/design.png' To import work items from a CSV file using the `workItemsCsvImport` mutation: GRAPHQL_TOKEN= curl --request POST \ --url "https://gitlab.com/api/graphql" \ --header "Authorization: Bearer $GRAPHQL_TOKEN" \ --form 'operations={"query": "mutation ($projectPath: ID!, $file: Upload!) { workItemsCsvImport(input: { projectPath: $projectPath, file: $file }) { message errors } }", "variables": {"projectPath": "/", "file": null}}' \ --form 'map={"0": ["variables.file"]}' \ --form '0=@/path/to/your/work-items.csv' To upload multiple files in a single request, add additional entries to both the `map` and the form fields: GRAPHQL_TOKEN= curl --request POST \ --url "https://gitlab.com/api/graphql" \ --header "Authorization: Bearer $GRAPHQL_TOKEN" \ --form 'operations={"query": "mutation ($files: [Upload!]!, $projectPath: ID!, $iid: ID!) { designManagementUpload(input: { projectPath: $projectPath, iid: $iid, files: $files }) { designs { filename } errors } }", "variables": {"files": [null, null], "projectPath": "/", "iid": ""}}' \ --form 'map={"0": ["variables.files.0"], "1": ["variables.files.1"]}' \ --form '0=@/path/to/first-design.png' \ --form '1=@/path/to/second-design.png' Changing the query URL ---------------------- Sometimes, it is necessary to send GraphQL requests to a different URL. An example are the `GeoNode` queries, which only work against a secondary Geo site URL. To change the URL of a GraphQL request in the GraphiQL explorer, set a custom header in the Header area of GraphiQL (bottom left area, right where Variables are): { "REQUEST_PATH": "" } --- # Project release API | GitLab Docs * * * Project release API =================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to interact with [releases](https://docs.gitlab.com/user/project/releases/) for projects. To interact with releases for a group, see the [group release API](https://docs.gitlab.com/api/group_releases/) . To interact with links as a release asset, see [release links API](https://docs.gitlab.com/api/releases/links/) . Authentication -------------- For authentication, the Releases API accepts either: * A [personal access token](https://docs.gitlab.com/user/profile/personal_access_tokens/) using the `PRIVATE-TOKEN` header. * The [GitLab CI/CD job token](https://docs.gitlab.com/ci/jobs/ci_job_token/) `$CI_JOB_TOKEN` using the `JOB-TOKEN` header. List Releases ------------- Returns a paginated list of releases, sorted by `released_at`. GET /projects/:id/releases | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `order_by` | string | no | The field to use as order. Either `released_at` (default) or `created_at`. | | `sort` | string | no | The direction of the order. Either `desc` (default) for descending order or `asc` for ascending order. | | `include_html_description` | boolean | no | If `true`, a response includes HTML rendered Markdown of the release description. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `[]._links` | object | Links of the release. | | `[]._links.closed_issues_url` | string | HTTP URL of the release’s closed issues. | | `[]._links.closed_merge_requests_url` | string | HTTP URL of the release’s closed merge requests. | | `[]._links.edit_url` | string | HTTP URL of the release’s edit page. | | `[]._links.merged_merge_requests_url` | string | HTTP URL of the release’s merged merge requests. | | `[]._links.opened_issues_url` | string | HTTP URL of the release’s open issues. | | `[]._links.opened_merge_requests_url` | string | HTTP URL of the release’s open merge requests. | | `[]._links.self` | string | HTTP URL of the release. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases" Example response: [\ {\ "tag_name":"v0.2",\ "description":"## CHANGELOG\r\n\r\n- Escape label and milestone titles to prevent XSS in GLFM autocomplete. !2740\r\n- Prevent private snippets from being embeddable.\r\n- Add subresources removal to member destroy service.",\ "name":"Awesome app v0.2 beta",\ "created_at":"2019-01-03T01:56:19.539Z",\ "released_at":"2019-01-03T01:56:19.539Z",\ "author":{\ "id":1,\ "name":"Administrator",\ "username":"root",\ "state":"active",\ "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",\ "web_url":"https://gitlab.example.com/root"\ },\ "commit":{\ "id":"079e90101242458910cccd35eab0e211dfc359c0",\ "short_id":"079e9010",\ "title":"Update README.md",\ "created_at":"2019-01-03T01:55:38.000Z",\ "parent_ids":[\ "f8d3d94cbd347e924aa7b715845e439d00e80ca4"\ ],\ "message":"Update README.md",\ "author_name":"Administrator",\ "author_email":"admin@example.com",\ "authored_date":"2019-01-03T01:55:38.000Z",\ "committer_name":"Administrator",\ "committer_email":"admin@example.com",\ "committed_date":"2019-01-03T01:55:38.000Z"\ },\ "milestones": [\ {\ "id":51,\ "iid":1,\ "project_id":24,\ "title":"v1.0-rc",\ "description":"Voluptate fugiat possimus quis quod aliquam expedita.",\ "state":"closed",\ "created_at":"2019-07-12T19:45:44.256Z",\ "updated_at":"2019-07-12T19:45:44.256Z",\ "due_date":"2019-08-16",\ "start_date":"2019-07-30",\ "web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/1",\ "issue_stats": {\ "total": 98,\ "closed": 76\ }\ },\ {\ "id":52,\ "iid":2,\ "project_id":24,\ "title":"v1.0",\ "description":"Voluptate fugiat possimus quis quod aliquam expedita.",\ "state":"closed",\ "created_at":"2019-07-16T14:00:12.256Z",\ "updated_at":"2019-07-16T14:00:12.256Z",\ "due_date":"2019-08-16",\ "start_date":"2019-07-30",\ "web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/2",\ "issue_stats": {\ "total": 24,\ "closed": 21\ }\ }\ ],\ "commit_path":"/root/awesome-app/commit/588440f66559714280628a4f9799f0c4eb880a4a",\ "tag_path":"/root/awesome-app/-/tags/v0.11.1",\ "assets":{\ "count":6,\ "sources":[\ {\ "format":"zip",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.zip"\ },\ {\ "format":"tar.gz",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.gz"\ },\ {\ "format":"tar.bz2",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.bz2"\ },\ {\ "format":"tar",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar"\ }\ ],\ "links":[\ {\ "id":2,\ "name":"awesome-v0.2.msi",\ "url":"http://192.168.10.15:3000/msi",\ "link_type":"other"\ },\ {\ "id":1,\ "name":"awesome-v0.2.dmg",\ "url":"http://192.168.10.15:3000",\ "link_type":"other"\ }\ ],\ "evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.2/evidence.json"\ },\ "evidences":[\ {\ "sha": "760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d",\ "filepath": "https://gitlab.example.com/root/awesome-app/-/releases/v0.2/evidence.json",\ "collected_at": "2019-01-03T01:56:19.539Z"\ }\ ]\ },\ {\ "tag_name":"v0.1",\ "description":"## CHANGELOG\r\n\r\n-Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516",\ "name":"Awesome app v0.1 alpha",\ "created_at":"2019-01-03T01:55:18.203Z",\ "released_at":"2019-01-03T01:55:18.203Z",\ "author":{\ "id":1,\ "name":"Administrator",\ "username":"root",\ "state":"active",\ "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",\ "web_url":"https://gitlab.example.com/root"\ },\ "commit":{\ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4",\ "short_id":"f8d3d94c",\ "title":"Initial commit",\ "created_at":"2019-01-03T01:53:28.000Z",\ "parent_ids":[\ \ ],\ "message":"Initial commit",\ "author_name":"Administrator",\ "author_email":"admin@example.com",\ "authored_date":"2019-01-03T01:53:28.000Z",\ "committer_name":"Administrator",\ "committer_email":"admin@example.com",\ "committed_date":"2019-01-03T01:53:28.000Z"\ },\ "assets":{\ "count":4,\ "sources":[\ {\ "format":"zip",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip"\ },\ {\ "format":"tar.gz",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz"\ },\ {\ "format":"tar.bz2",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2"\ },\ {\ "format":"tar",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar"\ }\ ],\ "links":[\ \ ],\ "evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.1/evidence.json"\ },\ "evidences":[\ {\ "sha": "c3ffedec13af470e760d6cdfb08790f71cf52c6cde4d",\ "filepath": "https://gitlab.example.com/root/awesome-app/-/releases/v0.1/evidence.json",\ "collected_at": "2019-01-03T01:55:18.203Z"\ }\ ],\ "_links": {\ "closed_issues_url": "https://gitlab.example.com/root/awesome-app/-/issues?release_tag=v0.1&scope=all&state=closed",\ "closed_merge_requests_url": "https://gitlab.example.com/root/awesome-app/-/merge_requests?release_tag=v0.1&scope=all&state=closed",\ "edit_url": "https://gitlab.example.com/root/awesome-app/-/releases/v0.1/edit",\ "merged_merge_requests_url": "https://gitlab.example.com/root/awesome-app/-/merge_requests?release_tag=v0.1&scope=all&state=merged",\ "opened_issues_url": "https://gitlab.example.com/root/awesome-app/-/issues?release_tag=v0.1&scope=all&state=opened",\ "opened_merge_requests_url": "https://gitlab.example.com/root/awesome-app/-/merge_requests?release_tag=v0.1&scope=all&state=opened",\ "self": "https://gitlab.example.com/root/awesome-app/-/releases/v0.1"\ }\ }\ ] Get a Release by a tag name --------------------------- Gets a release for the given tag. GET /projects/:id/releases/:tag_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The Git tag the release is associated with. | | `include_html_description` | boolean | no | If `true`, a response includes HTML rendered Markdown of the release description. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `[]._links` | object | Links of the release. | | `[]._links.closed_issues_url` | string | HTTP URL of the release’s closed issues. | | `[]._links.closed_merge_requests_url` | string | HTTP URL of the release’s closed merge requests. | | `[]._links.edit_url` | string | HTTP URL of the release’s edit page. | | `[]._links.merged_merge_requests_url` | string | HTTP URL of the release’s merged merge requests. | | `[]._links.opened_issues_url` | string | HTTP URL of the release’s open issues. | | `[]._links.opened_merge_requests_url` | string | HTTP URL of the release’s open merge requests. | | `[]._links.self` | string | HTTP URL of the release. | Example request: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1" Example response: { "tag_name":"v0.1", "description":"## CHANGELOG\r\n\r\n- Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516", "name":"Awesome app v0.1 alpha", "created_at":"2019-01-03T01:55:18.203Z", "released_at":"2019-01-03T01:55:18.203Z", "author":{ "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", "short_id":"f8d3d94c", "title":"Initial commit", "created_at":"2019-01-03T01:53:28.000Z", "parent_ids":[\ \ ], "message":"Initial commit", "author_name":"Administrator", "author_email":"admin@example.com", "authored_date":"2019-01-03T01:53:28.000Z", "committer_name":"Administrator", "committer_email":"admin@example.com", "committed_date":"2019-01-03T01:53:28.000Z" }, "milestones": [\ {\ "id":51,\ "iid":1,\ "project_id":24,\ "title":"v1.0-rc",\ "description":"Voluptate fugiat possimus quis quod aliquam expedita.",\ "state":"closed",\ "created_at":"2019-07-12T19:45:44.256Z",\ "updated_at":"2019-07-12T19:45:44.256Z",\ "due_date":"2019-08-16",\ "start_date":"2019-07-30",\ "web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/1",\ "issue_stats": {\ "total": 98,\ "closed": 76\ }\ },\ {\ "id":52,\ "iid":2,\ "project_id":24,\ "title":"v1.0",\ "description":"Voluptate fugiat possimus quis quod aliquam expedita.",\ "state":"closed",\ "created_at":"2019-07-16T14:00:12.256Z",\ "updated_at":"2019-07-16T14:00:12.256Z",\ "due_date":"2019-08-16",\ "start_date":"2019-07-30",\ "web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/2",\ "issue_stats": {\ "total": 24,\ "closed": 21\ }\ }\ ], "commit_path":"/root/awesome-app/commit/588440f66559714280628a4f9799f0c4eb880a4a", "tag_path":"/root/awesome-app/-/tags/v0.11.1", "assets":{ "count":5, "sources":[\ {\ "format":"zip",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip"\ },\ {\ "format":"tar.gz",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz"\ },\ {\ "format":"tar.bz2",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2"\ },\ {\ "format":"tar",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar"\ }\ ], "links":[\ {\ "id":3,\ "name":"hoge",\ "url":"https://gitlab.example.com/root/awesome-app/-/tags/v0.11.1/binaries/linux-amd64",\ "link_type":"other"\ }\ ] }, "evidences":[\ {\ "sha": "760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d",\ "filepath": "https://gitlab.example.com/root/awesome-app/-/releases/v0.1/evidence.json",\ "collected_at": "2019-07-16T14:00:12.256Z"\ },\ "_links": {\ "closed_issues_url": "https://gitlab.example.com/root/awesome-app/-/issues?release_tag=v0.1&scope=all&state=closed",\ "closed_merge_requests_url": "https://gitlab.example.com/root/awesome-app/-/merge_requests?release_tag=v0.1&scope=all&state=closed",\ "edit_url": "https://gitlab.example.com/root/awesome-app/-/releases/v0.1/edit",\ "merged_merge_requests_url": "https://gitlab.example.com/root/awesome-app/-/merge_requests?release_tag=v0.1&scope=all&state=merged",\ "opened_issues_url": "https://gitlab.example.com/root/awesome-app/-/issues?release_tag=v0.1&scope=all&state=opened",\ "opened_merge_requests_url": "https://gitlab.example.com/root/awesome-app/-/merge_requests?release_tag=v0.1&scope=all&state=opened",\ "self": "https://gitlab.example.com/root/awesome-app/-/releases/v0.1"\ }\ ] } Download a release asset ------------------------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/358188) in GitLab 15.4. Download a release asset file by making a request with the following format: GET /projects/:id/releases/:tag_name/downloads/:direct_asset_path | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The Git tag the release is associated with. | | `direct_asset_path` | string | yes | Path to the release asset file as specified when [creating](https://docs.gitlab.com/api/releases/links/#create-a-release-link)
or [updating](https://docs.gitlab.com/api/releases/links/#update-a-release-link)
its link. | Example request: curl --location --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/downloads/bin/asset.exe" ### Get the latest release History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/358188) in GitLab 15.4. Latest release information is accessible through a permanent API URL. The format of the URL is: GET /projects/:id/releases/permalink/latest To call any other GET API that requires a release tag, append a suffix to the `permalink/latest` API path. For example, to get latest [release evidence](https://docs.gitlab.com/api/releases/#collect-release-evidence) you can use: GET /projects/:id/releases/permalink/latest/evidence Another example is [downloading an asset](https://docs.gitlab.com/api/releases/#download-a-release-asset) of the latest release, for which you can use: GET /projects/:id/releases/permalink/latest/downloads/bin/asset.exe #### Sorting preferences By default, GitLab fetches the release using `released_at` time. The use of the query parameter `?order_by=released_at` is optional, and support for `?order_by=semver` is tracked [in issue 352945](https://gitlab.com/gitlab-org/gitlab/-/issues/352945) . Create a release ---------------- Creates a release. Developer level access to the project is required to create a release. POST /projects/:id/releases | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | no | The release name. | | `tag_name` | string | yes | The tag where the release is created from. | | `tag_message` | string | no | Message to use if creating a new annotated tag. | | `description` | string | no | The description of the release. You can use [Markdown](https://docs.gitlab.com/user/markdown/)
. | | `ref` | string | yes, if `tag_name` doesn’t exist | If a tag specified in `tag_name` doesn’t exist, the release is created from `ref` and tagged with `tag_name`. It can be a commit SHA, another tag name, or a branch name. | | `milestones` | array of string | no | The title of each milestone the release is associated with. [GitLab Premium](https://about.gitlab.com/pricing/)
customers can specify group milestones. | | `assets:links` | array of hash | no | An array of assets links. | | `assets:links:name` | string | required by: `assets:links` | The name of the link. Link names must be unique within the release. | | `assets:links:url` | string | required by: `assets:links` | The URL of the link. Link URLs must be unique within the release. | | `assets:links:direct_asset_path` | string | no | Optional path for a [direct asset link](https://docs.gitlab.com/user/project/releases/release_fields/#permanent-links-to-release-assets)
. | | `assets:links:link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`. | | `released_at` | datetime | no | Date and time for the release. Defaults to the current time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Only provide this field if creating an [upcoming](https://docs.gitlab.com/user/project/releases/#upcoming-releases)
or [historical](https://docs.gitlab.com/user/project/releases/#historical-releases)
release. | Example request: curl --header 'Content-Type: application/json' --header "PRIVATE-TOKEN: " \ --data '{ "name": "New release", "tag_name": "v0.3", "description": "Super nice release", "milestones": ["v1.0", "v1.0-rc"], "assets": { "links": [{ "name": "hoge", "url": "https://google.com", "direct_asset_path": "/binaries/linux-amd64", "link_type":"other" }] } }' \ --request POST "https://gitlab.example.com/api/v4/projects/24/releases" Example response: { "tag_name":"v0.3", "description":"Super nice release", "name":"New release", "created_at":"2019-01-03T02:22:45.118Z", "released_at":"2019-01-03T02:22:45.118Z", "author":{ "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"079e90101242458910cccd35eab0e211dfc359c0", "short_id":"079e9010", "title":"Update README.md", "created_at":"2019-01-03T01:55:38.000Z", "parent_ids":[\ "f8d3d94cbd347e924aa7b715845e439d00e80ca4"\ ], "message":"Update README.md", "author_name":"Administrator", "author_email":"admin@example.com", "authored_date":"2019-01-03T01:55:38.000Z", "committer_name":"Administrator", "committer_email":"admin@example.com", "committed_date":"2019-01-03T01:55:38.000Z" }, "milestones": [\ {\ "id":51,\ "iid":1,\ "project_id":24,\ "title":"v1.0-rc",\ "description":"Voluptate fugiat possimus quis quod aliquam expedita.",\ "state":"closed",\ "created_at":"2019-07-12T19:45:44.256Z",\ "updated_at":"2019-07-12T19:45:44.256Z",\ "due_date":"2019-08-16",\ "start_date":"2019-07-30",\ "web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/1",\ "issue_stats": {\ "total": 99,\ "closed": 76\ }\ },\ {\ "id":52,\ "iid":2,\ "project_id":24,\ "title":"v1.0",\ "description":"Voluptate fugiat possimus quis quod aliquam expedita.",\ "state":"closed",\ "created_at":"2019-07-16T14:00:12.256Z",\ "updated_at":"2019-07-16T14:00:12.256Z",\ "due_date":"2019-08-16",\ "start_date":"2019-07-30",\ "web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/2",\ "issue_stats": {\ "total": 24,\ "closed": 21\ }\ }\ ], "commit_path":"/root/awesome-app/commit/588440f66559714280628a4f9799f0c4eb880a4a", "tag_path":"/root/awesome-app/-/tags/v0.11.1", "evidence_sha":"760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d", "assets":{ "count":5, "sources":[\ {\ "format":"zip",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.zip"\ },\ {\ "format":"tar.gz",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.gz"\ },\ {\ "format":"tar.bz2",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.bz2"\ },\ {\ "format":"tar",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar"\ }\ ], "links":[\ {\ "id":3,\ "name":"hoge",\ "url":"https://gitlab.example.com/root/awesome-app/-/tags/v0.11.1/binaries/linux-amd64",\ "link_type":"other"\ }\ ], "evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.3/evidence.json" } } ### Group milestones * Tier: Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Group milestones associated with the project may be specified in the `milestones` array for [Create a release](https://docs.gitlab.com/api/releases/#create-a-release) and [Update a release](https://docs.gitlab.com/api/releases/#update-a-release) API calls. Only milestones associated with the project’s group may be specified, and adding milestones for ancestor groups raises an error. Collect release evidence ------------------------ * Tier: Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Creates an evidence for an existing release. POST /projects/:id/releases/:tag_name/evidence | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The Git tag the release is associated with. | Example request: curl --request POST --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/evidence" Example response: 200 Update a release ---------------- History * [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5. Updates a release. Developer level access to the project is required to update a release. PUT /projects/:id/releases/:tag_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The Git tag the release is associated with. | | `name` | string | no | The release name. | | `description` | string | no | The description of the release. You can use [Markdown](https://docs.gitlab.com/user/markdown/)
. | | `milestones` | array of string | no | The title of each milestone to associate with the release. [GitLab Premium](https://about.gitlab.com/pricing/)
customers can specify group milestones. To remove all milestones from the release, specify `[]`. | | `released_at` | datetime | no | The date when the release is/was ready. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | Example request: curl --header 'Content-Type: application/json' --request PUT --data '{"name": "new name", "milestones": ["v1.2"]}' \ --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1" Example response: { "tag_name":"v0.1", "description":"## CHANGELOG\r\n\r\n- Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516", "name":"new name", "created_at":"2019-01-03T01:55:18.203Z", "released_at":"2019-01-03T01:55:18.203Z", "author":{ "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", "short_id":"f8d3d94c", "title":"Initial commit", "created_at":"2019-01-03T01:53:28.000Z", "parent_ids":[\ \ ], "message":"Initial commit", "author_name":"Administrator", "author_email":"admin@example.com", "authored_date":"2019-01-03T01:53:28.000Z", "committer_name":"Administrator", "committer_email":"admin@example.com", "committed_date":"2019-01-03T01:53:28.000Z" }, "milestones": [\ {\ "id":53,\ "iid":3,\ "project_id":24,\ "title":"v1.2",\ "description":"Voluptate fugiat possimus quis quod aliquam expedita.",\ "state":"active",\ "created_at":"2019-09-01T13:00:00.256Z",\ "updated_at":"2019-09-01T13:00:00.256Z",\ "due_date":"2019-09-20",\ "start_date":"2019-09-05",\ "web_url":"https://gitlab.example.com/root/awesome-app/-/milestones/3",\ "issue_stats": {\ "opened": 11,\ "closed": 78\ }\ }\ ], "commit_path":"/root/awesome-app/commit/588440f66559714280628a4f9799f0c4eb880a4a", "tag_path":"/root/awesome-app/-/tags/v0.11.1", "evidence_sha":"760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d", "assets":{ "count":4, "sources":[\ {\ "format":"zip",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip"\ },\ {\ "format":"tar.gz",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz"\ },\ {\ "format":"tar.bz2",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2"\ },\ {\ "format":"tar",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar"\ }\ ], "links":[\ \ ], "evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.1/evidence.json" } } Delete a Release ---------------- Deletes a release. Deleting a release doesn’t delete the associated tag. Maintainer level access to the project is required to delete a release. DELETE /projects/:id/releases/:tag_name | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | yes | The Git tag the release is associated with. | Example request: curl --request DELETE --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases/v0.1" Example response: { "tag_name":"v0.1", "description":"## CHANGELOG\r\n\r\n- Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516", "name":"new name", "created_at":"2019-01-03T01:55:18.203Z", "released_at":"2019-01-03T01:55:18.203Z", "author":{ "id":1, "name":"Administrator", "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", "short_id":"f8d3d94c", "title":"Initial commit", "created_at":"2019-01-03T01:53:28.000Z", "parent_ids":[\ \ ], "message":"Initial commit", "author_name":"Administrator", "author_email":"admin@example.com", "authored_date":"2019-01-03T01:53:28.000Z", "committer_name":"Administrator", "committer_email":"admin@example.com", "committed_date":"2019-01-03T01:53:28.000Z" }, "commit_path":"/root/awesome-app/commit/588440f66559714280628a4f9799f0c4eb880a4a", "tag_path":"/root/awesome-app/-/tags/v0.11.1", "evidence_sha":"760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d", "assets":{ "count":4, "sources":[\ {\ "format":"zip",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip"\ },\ {\ "format":"tar.gz",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz"\ },\ {\ "format":"tar.bz2",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2"\ },\ {\ "format":"tar",\ "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar"\ }\ ], "links":[\ \ ], "evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.1/evidence.json" } } Upcoming Releases ----------------- A release with a `released_at` attribute set to a future date is labeled as an **Upcoming Release** [in the UI](https://docs.gitlab.com/user/project/releases/#upcoming-releases) . Additionally, if a [release is requested from the API](https://docs.gitlab.com/api/releases/#list-releases) , for each release with a `release_at` attribute set to a future date, an additional attribute `upcoming_release` (set to true) is returned as part of the response. Historical releases ------------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199429) in GitLab 15.2. A release with a `released_at` attribute set to a past date is labeled as an **Historical release** [in the UI](https://docs.gitlab.com/user/project/releases/#historical-releases) . Additionally, if a [release is requested from the API](https://docs.gitlab.com/api/releases/#list-releases) , for each release with a `release_at` attribute set to a past date, an additional attribute `historical_release` (set to true) is returned as part of the response. --- # Project templates API | GitLab Docs * * * Project templates API ===================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to retrieve project-specific version of these endpoints: * [Dockerfile templates](https://docs.gitlab.com/api/templates/dockerfiles/) * [Gitignore templates](https://docs.gitlab.com/api/templates/gitignores/) * [GitLab CI/CD Configuration templates](https://docs.gitlab.com/api/templates/gitlab_ci_ymls/) * [Open source license templates](https://docs.gitlab.com/api/templates/licenses/) * [Issue and merge request templates](https://docs.gitlab.com/user/project/description_templates/) It deprecates these endpoints, which are scheduled for removal in API version 5. In addition to templates common to the entire instance, project-specific templates are also available from this API endpoint. Support is also available for [file templates for groups](https://docs.gitlab.com/user/group/manage/#group-file-templates) . List all templates of a particular type --------------------------------------- Lists all templates of a specified type for a project. GET /projects/:id/templates/:type Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `type` | string | Yes | Type of the template. Accepted values are: `dockerfiles`, `gitignores`, `gitlab_ci_ymls`, `licenses`, `issues`, or `merge_requests`. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `key` | string | Unique identifier for the template. | | `name` | string | Human-readable name of the template. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/templates/licenses" Example response (licenses): [\ {\ "key": "epl-1.0",\ "name": "Eclipse Public License 1.0"\ },\ {\ "key": "lgpl-3.0",\ "name": "GNU Lesser General Public License v3.0"\ },\ {\ "key": "unlicense",\ "name": "The Unlicense"\ },\ {\ "key": "agpl-3.0",\ "name": "GNU Affero General Public License v3.0"\ },\ {\ "key": "gpl-3.0",\ "name": "GNU General Public License v3.0"\ },\ {\ "key": "bsd-3-clause",\ "name": "BSD 3-clause \"New\" or \"Revised\" License"\ },\ {\ "key": "lgpl-2.1",\ "name": "GNU Lesser General Public License v2.1"\ },\ {\ "key": "mit",\ "name": "MIT License"\ },\ {\ "key": "apache-2.0",\ "name": "Apache License 2.0"\ },\ {\ "key": "bsd-2-clause",\ "name": "BSD 2-clause \"Simplified\" License"\ },\ {\ "key": "mpl-2.0",\ "name": "Mozilla Public License 2.0"\ },\ {\ "key": "gpl-2.0",\ "name": "GNU General Public License v2.0"\ }\ ] Retrieve a template of a particular type ---------------------------------------- Retrieves a template of a specified type for a project. GET /projects/:id/templates/:type/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Key of the template, as obtained from the collection endpoint. | | `type` | string | Yes | Type of the template. One of: `dockerfiles`, `gitignores`, `gitlab_ci_ymls`, `licenses`, `issues`, or `merge_requests`. | | `fullname` | string | No | Full name of the copyright holder to use when expanding placeholders in the template. Affects only licenses. | | `project` | string | No | Project name to use when expanding placeholders in the template. Affects only licenses. | | `source_template_project_id` | integer | No | Project ID where a given template is being stored. Helpful when multiple templates from different projects have the same name. If multiple templates have the same name, the match from closest ancestor is returned if `source_template_project_id` is not specified. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `conditions` | array | Array of license conditions. Available for licenses only. | | `content` | string | Template content. | | `description` | string | Description of the license. Available for licenses only. | | `html_url` | string | URL to the license information page. Available for licenses only. | | `key` | string | Unique identifier for the template. Available for licenses only. | | `limitations` | array | Array of license limitations. Available for licenses only. | | `name` | string | Human-readable name of the template. | | `nickname` | string | Common nickname for the license. Available for licenses only. | | `permissions` | array | Array of license permissions. Available for licenses only. | | `popular` | boolean | If `true`, indicates this is a popular license. Available for licenses only. | | `source_url` | string | URL to the license source. Available for licenses only. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/templates/dockerfiles/Binary" Example response (Dockerfile): { "name": "Binary", "content": "# This file is a template, and might need editing before it works on your project.\n# This Dockerfile installs a compiled binary into a bare system.\n# You must either commit your compiled binary into source control (not recommended)\n# or build the binary first as part of a CI/CD pipeline.\n\nFROM buildpack-deps:buster\n\nWORKDIR /usr/local/bin\n\n# Change `app` to whatever your binary is called\nAdd app .\nCMD [\"./app\"]\n" } Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/templates/licenses/mit" Example response (license): { "key": "mit", "name": "MIT License", "nickname": null, "popular": true, "html_url": "http://choosealicense.com/licenses/mit/", "source_url": "https://opensource.org/licenses/MIT", "description": "A short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.", "conditions": [\ "include-copyright"\ ], "permissions": [\ "commercial-use",\ "modifications",\ "distribution",\ "private-use"\ ], "limitations": [\ "liability",\ "warranty"\ ], "content": "MIT License\n\nCopyright (c) 2018 [fullname]\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" } --- # REST API deprecations | GitLab Docs * * * REST API deprecations ===================== You should regularly review the following deprecations and make the recommended changes. These deprecations often signal improved API features and recommend using new fields or endpoints for features. Though some deprecations mention a v5 REST API, no v5 REST API development is active. GitLab will not make these changes within REST API v4, and [follows semantic versioning for the REST API](https://docs.gitlab.com/api/rest/#versioning-and-deprecations) . `geo_nodes` API endpoints ------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/369140) . The [`geo_nodes` API endpoints](https://docs.gitlab.com/api/geo_nodes/) are deprecated and are replaced by [`geo_sites`](https://docs.gitlab.com/api/geo_sites/) . It is a part of the global change on [how to refer to Geo deployments](https://docs.gitlab.com/administration/geo/glossary/) . Nodes are renamed to sites across the application. The functionality of both endpoints remains the same. `merged_by` API field --------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/350534) . The `merged_by` field in the [merge request API](https://docs.gitlab.com/api/merge_requests/#list-merge-requests) has been deprecated in favor of the `merge_user` field which more correctly identifies who merged a merge request when performing actions (set to auto-merge, add to merge train) other than a simple merge. API users are encouraged to use the new `merge_user` field instead. The `merged_by` field will be removed in v5 of the GitLab REST API. `merge_status` API field ------------------------ Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382032) . The `merge_status` field in the [merge request API](https://docs.gitlab.com/api/merge_requests/#merge-status) has been deprecated in favor of the `detailed_merge_status` field which more correctly identifies all of the potential statuses that a merge request can be in. API users are encouraged to use the new `detailed_merge_status` field instead. The `merge_status` field will be removed in v5 of the GitLab REST API. ### Null value for `private_profile` attribute in User API Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/387005) . When creating and updating users through the API, `null` was a valid value for the `private_profile` attribute, which would internally be converted to the default value. In v5 of the GitLab REST API, `null` will no longer be a valid value for this parameter, and the response will be a 400 if used. After this change, the only valid values will be `true` and `false`. Single merge request changes API endpoint ----------------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/322117) . The endpoint to get [changes from a single merge request](https://docs.gitlab.com/api/merge_requests/#retrieve-merge-request-changes) has been deprecated in favor the [list merge request diffs](https://docs.gitlab.com/api/merge_requests/#list-merge-request-diffs) endpoint. API users are encouraged to switch to the new diffs endpoint instead. The `changes from a single merge request` endpoint will be removed in v5 of the GitLab REST API. Managed Licenses API endpoint ----------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/397067) . The endpoint to get all managed licenses for a given project has been deprecated in favor the [License Approval policy](https://docs.gitlab.com/user/compliance/license_approval_policies/) feature. Users who wish to continue to enforce approvals based on detected licenses are encouraged to create a new [License Approval policy](https://docs.gitlab.com/user/compliance/license_approval_policies/) instead. The `managed licenses` endpoint will be removed in v5 of the GitLab REST API. Approvers and Approver Group fields in Merge Request Approval API ----------------------------------------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/353097) . The endpoint to get the configuration of approvals for a project returns empty arrays for `approvers` and `approval_groups`. These fields were deprecated in favor of the endpoint to [list all approval rules](https://docs.gitlab.com/api/merge_request_approvals/#list-all-approval-rules-for-a-merge-request) for a merge request. API users are encouraged to switch to this endpoint instead. These fields will be removed from the `get configuration` endpoint in v5 of the GitLab REST API. Runner usage of `active` replaced by `paused` --------------------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/351109) . Occurrences of the `active` identifier in the GitLab Runner GraphQL API endpoints will be renamed to `paused` in GitLab 16.0. * In v4 of the REST API, you can use the `paused` property in place of `active` * In v5 of the REST API, this change will affect endpoints taking or returning `active` property, such as: * `GET /runners` * `GET /runners/all` * `GET /runners/:id` / `PUT /runners/:id` * `PUT --form "active=false" /runners/:runner_id` * `GET /projects/:id/runners` / `POST /projects/:id/runners` * `GET /groups/:id/runners` The 16.0 release of GitLab Runner will start using the `paused` property when registering runners. Runner status will not return `paused` -------------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/344648) . In a future v5 of the REST API, the endpoints for GitLab Runner will not return `paused` or `active`. A runner’s status will only relate to runner contact status, such as: `online`, `offline`, or `not_connected`. Status `paused` or `active` will no longer appear. When checking if a runner is `paused`, API users are advised to check the boolean attribute `paused` to be `true` instead. When checking if a runner is `active`, check if `paused` is `false`. Runner will not return `ip_address` ----------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/415159) . In GitLab 17.0, the [Runners API](https://docs.gitlab.com/api/runners/) will return `""` in place of `ip_address` for runners. In v5 of the REST API, the field will be removed. `default_branch_protection` API field ------------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/408315) . The `default_branch_protection` field is deprecated in GitLab 17.0 for the following APIs: * [New group API](https://docs.gitlab.com/api/groups/#create-a-group) . * [Update group API](https://docs.gitlab.com/api/groups/#update-group-attributes) . * [Application Settings API](https://docs.gitlab.com/api/settings/#update-application-settings) You should use the `default_branch_protection_defaults` field instead, which provides more finer grained control over the default branch protections. The `default_branch_protection` field will be removed in v5 of the GitLab REST API. `require_password_to_approve` API field --------------------------------------- The `require_password_to_approve` was deprecated in GitLab 16.9. Use the `require_reauthentication_to_approve` field instead. If you supply values to both fields, the `require_reauthentication_to_approve` field takes precedence. The `require_password_to_approve` field will be removed in v5 of the GitLab REST API. Pull mirroring configuration with the projects API endpoint ----------------------------------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/494294) . In GitLab 17.6, the [pull mirroring configuration with the Projects API](https://docs.gitlab.com/api/project_pull_mirroring/#update-pull-mirroring-for-a-project-deprecated) is deprecated. It is replaced by a new configuration and endpoint, [`projects/:id/mirror/pull`](https://docs.gitlab.com/api/project_pull_mirroring/#update-project-pull-mirroring-settings) . The previous configuration using the Projects API will be removed in v5 of the GitLab REST API. `restrict_user_defined_variables` parameter with the projects API endpoint -------------------------------------------------------------------------- In GitLab 17.7, the [`restrict_user_defined_variables` parameter in Projects API](https://docs.gitlab.com/api/projects/#update-a-project) is deprecated in favour of using only `ci_pipeline_variables_minimum_override_role`. To match the same behavior of `restrict_user_defined_variables: false` set `ci_pipeline_variables_minimum_override_role` as `developer`. `namespace` parameter in project import API endpoints ----------------------------------------------------- Breaking change. [Related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/511053) . In GitLab 18.7, the `namespace` parameter in the [project import and export API](https://docs.gitlab.com/api/project_import_export/) is deprecated in favor of the `namespace_id` and `namespace_path` parameters. The `namespace` parameter accepted both an ID or path, which caused ambiguity when namespace paths contained only digits. Instead, you should use: * `namespace_id` when specifying a namespace by its numeric ID. * `namespace_path` when specifying a namespace by its path. The `namespace` parameter will be removed in v5 of the GitLab REST API. --- # Protected tags API | GitLab Docs * * * Protected tags API ================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [protected tags](https://docs.gitlab.com/user/project/protected_tags/) . Valid access levels ------------------- These access levels are recognized: * `0`: No access * `30`: Developer role * `40`: Maintainer role List protected tags ------------------- History * Deploy key information [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116846) in GitLab 16.0. Get a list of [protected tags](https://docs.gitlab.com/user/project/protected_tags/) from a project. This function takes pagination parameters `page` and `per_page` to restrict the list of protected tags. GET /projects/:id/protected_tags Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `create_access_levels` | array | Array of create access level configurations. | | `create_access_levels[].access_level` | integer | Access level for creating tags. | | `create_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `create_access_levels[].deploy_key_id` | integer | ID of the deploy key with create access. | | `create_access_levels[].group_id` | integer | ID of the group with create access. Premium and Ultimate only. | | `create_access_levels[].id` | integer | ID of the create access level configuration. | | `create_access_levels[].user_id` | integer | ID of the user with create access. Premium and Ultimate only. | | `name` | string | Name of the protected tag. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_tags" Example response: [\ {\ "name": "release-1-0",\ "create_access_levels": [\ {\ "id":1,\ "access_level": 40,\ "access_level_description": "Maintainers"\ },\ {\ "id": 2,\ "access_level": 40,\ "access_level_description": "Deploy key",\ "deploy_key_id": 1\ }\ ]\ }\ ] Get a protected tag or wildcard protected tag --------------------------------------------- Get a single protected tag or wildcard protected tag. GET /projects/:id/protected_tags/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the tag or wildcard. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `create_access_levels` | array | Array of create access level configurations. | | `create_access_levels[].access_level` | integer | Access level for creating tags. | | `create_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `create_access_levels[].deploy_key_id` | integer | ID of the deploy key with create access. | | `create_access_levels[].group_id` | integer | ID of the group with create access. Premium and Ultimate only. | | `create_access_levels[].id` | integer | ID of the create access level configuration. | | `create_access_levels[].user_id` | integer | ID of the user with create access. Premium and Ultimate only. | | `name` | string | Name of the protected tag. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_tags/release-1-0" Example response: { "name": "release-1-0", "create_access_levels": [\ {\ "id": 1,\ "access_level": 40,\ "access_level_description": "Maintainers"\ }\ ] } Protect a repository tag ------------------------ History * `deploy_key_id` configuration [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166866) in GitLab 17.5. * `deploy_key_id` configuration [moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/224542) from GitLab Premium to GitLab Free in GitLab 18.10. Protect a single repository tag, or several project repository tags, using a wildcard protected tag. POST /projects/:id/protected_tags Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the tag or wildcard. | | `allowed_to_create` | array | No | Array of access levels allowed to create tags, with each described by a hash of the form `{user_id: integer}`, `{group_id: integer}`, `{deploy_key_id: integer}`, or `{access_level: integer}`. `user_id`, `group_id`, and `access_level` are Premium and Ultimate only. | | `create_access_level` | integer | No | Access levels allowed to create. Default is `40` (Maintainer role). | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `create_access_levels` | array | Array of create access level configurations. | | `create_access_levels[].access_level` | integer | Access level for creating tags. | | `create_access_levels[].access_level_description` | string | Human-readable description of the access level. | | `create_access_levels[].deploy_key_id` | integer | ID of the deploy key with create access. | | `create_access_levels[].group_id` | integer | ID of the group with create access. Premium and Ultimate only. | | `create_access_levels[].id` | integer | ID of the create access level configuration. | | `create_access_levels[].user_id` | integer | ID of the user with create access. Premium and Ultimate only. | | `name` | string | Name of the protected tag. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --url "https://gitlab.example.com/api/v4/projects/5/protected_tags" \ --data '{ "allowed_to_create" : [\ {\ "user_id" : 1\ },\ {\ "access_level" : 30\ }\ ], "create_access_level" : 30, "name" : "*-stable" }' Example response: { "name": "*-stable", "create_access_levels": [\ {\ "id": 1,\ "access_level": 30,\ "access_level_description": "Developers + Maintainers"\ }\ ] } ### Example with user and group access Elements in the `allowed_to_create` array should take the form `{user_id: integer}`, `{group_id: integer}`, `{deploy_key_id: integer}`, or `{access_level: integer}`. Each user must have access to the project and each group must [have this project shared](https://docs.gitlab.com/user/project/members/sharing_projects_groups/) . These access levels allow more granular control over protected tag access. For more information, see [add a group to protected tags](https://docs.gitlab.com/user/project/protected_tags/#add-a-group-to-protected-tags) . This example request demonstrates how to create a protected tag that allows creation access to a specific user and group: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_tags" \ --data "name=*-stable" \ --data "allowed_to_create[][user_id]=10" \ --data "allowed_to_create[][group_id]=20" This example response includes: * A protected tag with name `"*-stable"`. * `create_access_levels` with ID `1` for user with ID `10`. * `create_access_levels` with ID `2` for group with ID `20`. { "name": "*-stable", "create_access_levels": [\ {\ "id": 1,\ "access_level": null,\ "user_id": 10,\ "group_id": null,\ "access_level_description": "Administrator"\ },\ {\ "id": 2,\ "access_level": null,\ "user_id": null,\ "group_id": 20,\ "access_level_description": "Example Create Group"\ }\ ] } Unprotect repository tags ------------------------- Unprotect the given protected tag or wildcard protected tag. DELETE /projects/:id/protected_tags/:name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `name` | string | Yes | Name of the tag. | If successful, returns [`204 No Content`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/protected_tags/*-stable" Related topics -------------- * [Tags API](https://docs.gitlab.com/api/tags/) for all tags * [Tags](https://docs.gitlab.com/user/project/repository/tags/) user documentation * [Protected tags](https://docs.gitlab.com/user/project/protected_tags/) user documentation --- # Project snippets | GitLab Docs * * * Project snippets ================ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [project snippets](https://docs.gitlab.com/user/snippets/) . Related APIs exist for [personal snippets](https://docs.gitlab.com/api/snippets/) and [moving snippets between storages](https://docs.gitlab.com/api/snippet_repository_storage_moves/) . List all snippets for a project ------------------------------- Lists all snippets for a specified project. GET /projects/:id/snippets Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author.created_at` | string | Date and time when the author account was created. | | `author.email` | string | Email address of the snippet author. | | `author.id` | integer | ID of the snippet author. | | `author.name` | string | Display name of the snippet author. | | `author.state` | string | State of the author account. | | `author.username` | string | Username of the snippet author. | | `created_at` | string | Date and time when the snippet was created in ISO 8601 format. | | `description` | string | Description of the snippet. | | `file_name` | string | Name of the snippet file. | | `id` | integer | ID of the snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of the import if the snippet was imported. | | `project_id` | integer | ID of the project containing the snippet. | | `raw_url` | string | Direct URL to the raw snippet content. | | `title` | string | Title of the snippet. | | `updated_at` | string | Date and time when the snippet was last updated in ISO 8601 format. | | `web_url` | string | URL to view the snippet in the GitLab web interface. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/snippets" Example response: [\ {\ "id": 1,\ "title": "test",\ "file_name": "add.rb",\ "description": "Ruby test snippet",\ "author": {\ "id": 1,\ "username": "john_smith",\ "email": "john@example.com",\ "name": "John Smith",\ "state": "active",\ "created_at": "2012-05-23T08:00:58Z"\ },\ "updated_at": "2012-06-28T10:52:04Z",\ "created_at": "2012-06-28T10:52:04Z",\ "imported": false,\ "imported_from": "none",\ "project_id": 1,\ "web_url": "http://example.com/example/example/snippets/1",\ "raw_url": "http://example.com/example/example/snippets/1/raw"\ },\ {\ "id": 3,\ "title": "Configuration helper",\ "file_name": "config.yml",\ "description": "YAML configuration snippet",\ "author": {\ "id": 2,\ "username": "jane_doe",\ "email": "jane@example.com",\ "name": "Jane Doe",\ "state": "active",\ "created_at": "2013-02-15T10:30:20Z"\ },\ "updated_at": "2013-03-10T14:15:30Z",\ "created_at": "2013-03-01T09:45:12Z",\ "imported": false,\ "imported_from": "none",\ "project_id": 1,\ "web_url": "http://example.com/example/example/snippets/3",\ "raw_url": "http://example.com/example/example/snippets/3/raw"\ }\ ] Retrieve a snippet ------------------ Retrieves a specified project snippet. GET /projects/:id/snippets/:snippet_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `snippet_id` | integer | Yes | ID of a project’s snippet. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author.created_at` | string | Date and time when the author account was created. | | `author.email` | string | Email address of the snippet author. | | `author.id` | integer | ID of the snippet author. | | `author.name` | string | Display name of the snippet author. | | `author.state` | string | State of the author account. | | `author.username` | string | Username of the snippet author. | | `created_at` | string | Date and time when the snippet was created in ISO 8601 format. | | `description` | string | Description of the snippet. | | `file_name` | string | Name of the snippet file. | | `id` | integer | ID of the snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of the import if the snippet was imported. | | `project_id` | integer | ID of the project containing the snippet. | | `raw_url` | string | Direct URL to the raw snippet content. | | `title` | string | Title of the snippet. | | `updated_at` | string | Date and time when the snippet was last updated in ISO 8601 format. | | `web_url` | string | URL to view the snippet in the GitLab web interface. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/snippets/2" Example response: { "id": 2, "title": "test", "file_name": "add.rb", "description": "Ruby test snippet", "author": { "id": 1, "username": "john_smith", "email": "john@example.com", "name": "John Smith", "state": "active", "created_at": "2012-05-23T08:00:58Z" }, "updated_at": "2012-06-28T10:52:04Z", "created_at": "2012-06-28T10:52:04Z", "imported": false, "imported_from": "none", "project_id": 1, "web_url": "http://example.com/example/example/snippets/2", "raw_url": "http://example.com/example/example/snippets/2/raw" } Create a snippet ---------------- Creates a project snippet. The user must have permission to create snippets. POST /projects/:id/snippets Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `files` | array of hashes | Yes | An array of snippet files. | | `files:content` | string | Yes | Content of the snippet file. | | `files:file_path` | string | Yes | File path of the snippet file. | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `title` | string | Yes | Title of a snippet. | | `content` | string | No | Deprecated: Use `files` instead. Content of a snippet. | | `description` | string | No | Description of a snippet. | | `file_name` | string | No | Deprecated: Use `files` instead. Name of a snippet file. | | `visibility` | string | No | Visibility level for the snippet. Possible values: `public`, `private`, and `internal`. On GitLab.com, the `internal` value is not available. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author.created_at` | string | Date and time when the author account was created. | | `author.email` | string | Email address of the snippet author. | | `author.id` | integer | ID of the snippet author. | | `author.name` | string | Display name of the snippet author. | | `author.state` | string | State of the author account. | | `author.username` | string | Username of the snippet author. | | `created_at` | string | Date and time when the snippet was created in ISO 8601 format. | | `description` | string | Description of the snippet. | | `file_name` | string | Name of the snippet file. | | `id` | integer | ID of the snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of the import if the snippet was imported. | | `project_id` | integer | ID of the project containing the snippet. | | `raw_url` | string | Direct URL to the raw snippet content. | | `title` | string | Title of the snippet. | | `updated_at` | string | Date and time when the snippet was last updated in ISO 8601 format. | | `web_url` | string | URL to view the snippet in the GitLab web interface. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"title": "Example Snippet Title", "description": "More verbose snippet description", "visibility": "private", "files": [{"file_path": "example.txt", "content": "source code \n with multiple lines\n"}]}' \ --url "https://gitlab.example.com/api/v4/projects/1/snippets" Example response: { "id": 1, "title": "Example Snippet Title", "file_name": "example.txt", "description": "More verbose snippet description", "author": { "id": 1, "username": "john_smith", "email": "john@example.com", "name": "John Smith", "state": "active", "created_at": "2012-05-23T08:00:58Z" }, "updated_at": "2012-06-28T10:52:04Z", "created_at": "2012-06-28T10:52:04Z", "imported": false, "imported_from": "none", "project_id": 1, "web_url": "http://example.com/example/example/snippets/1", "raw_url": "http://example.com/example/example/snippets/1/raw" } Update a snippet ---------------- Updates a specified project snippet. The user must have permission to change existing snippets. Updates to snippets with multiple files must use the `files` attribute. PUT /projects/:id/snippets/:snippet_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `snippet_id` | integer | Yes | ID of a project’s snippet. | | `files:action` | string | Conditionally | Type of action to perform on the file. One of: `create`, `update`, `delete`, `move`. Required when using the `files` attribute. | | `content` | string | No | Deprecated: Use `files` instead. Content of a snippet. | | `description` | string | No | Description of a snippet. | | `file_name` | string | No | Deprecated: Use `files` instead. Name of a snippet file. | | `files` | array of hashes | No | An array of snippet files. | | `files:content` | string | No | Content of the snippet file. | | `files:file_path` | string | No | File path of the snippet file. | | `files:previous_path` | string | No | Previous path of the snippet file. | | `title` | string | No | Title of a snippet. | | `visibility` | string | No | Visibility level for the snippet. Possible values: `public`, `private`, and `internal`. On GitLab.com, the `internal` value is not available. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author.created_at` | string | Date and time when the author account was created. | | `author.email` | string | Email address of the snippet author. | | `author.id` | integer | ID of the snippet author. | | `author.name` | string | Display name of the snippet author. | | `author.state` | string | State of the author account. | | `author.username` | string | Username of the snippet author. | | `created_at` | string | Date and time when the snippet was created in ISO 8601 format. | | `description` | string | Description of the snippet. | | `file_name` | string | Name of the snippet file. | | `id` | integer | ID of the snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of the import if the snippet was imported. | | `project_id` | integer | ID of the project containing the snippet. | | `raw_url` | string | Direct URL to the raw snippet content. | | `title` | string | Title of the snippet. | | `updated_at` | string | Date and time when the snippet was last updated in ISO 8601 format. | | `web_url` | string | URL to view the snippet in the GitLab web interface. | Example request: curl --request PUT \ --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"title": "Updated Snippet Title", "description": "More verbose snippet description", "visibility": "private", "files": [{"action": "update", "file_path": "example.txt", "content": "updated source code \n with multiple lines\n"}]}' \ --url "https://gitlab.example.com/api/v4/projects/1/snippets/2" Example response: { "id": 2, "title": "Updated Snippet Title", "file_name": "example.txt", "description": "More verbose snippet description", "author": { "id": 1, "username": "john_smith", "email": "john@example.com", "name": "John Smith", "state": "active", "created_at": "2012-05-23T08:00:58Z" }, "updated_at": "2012-06-28T10:52:04Z", "created_at": "2012-06-28T10:52:04Z", "imported": false, "imported_from": "none", "project_id": 1, "web_url": "http://example.com/example/example/snippets/2", "raw_url": "http://example.com/example/example/snippets/2/raw" } Delete a snippet ---------------- Deletes a specified project snippet. This returns a `204 No Content` status code if the operation was successfully or `404` if the resource was not found. DELETE /projects/:id/snippets/:snippet_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `snippet_id` | integer | Yes | ID of a project’s snippet. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/snippets/2" Retrieve snippet content ------------------------ Retrieves the raw project snippet as plain text. GET /projects/:id/snippets/:snippet_id/raw Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `snippet_id` | integer | Yes | ID of a project’s snippet. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/snippets/2/raw" Retrieve snippet repository file content ---------------------------------------- Retrieves the raw file content as plain text. GET /projects/:id/snippets/:snippet_id/files/:ref/:file_path/raw Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `file_path` | string | Yes | URL-encoded path to the file, for example, `snippet%2Erb`. | | `ref` | string | Yes | Name of a branch, tag or commit, for example, `main`. | | `snippet_id` | integer | Yes | ID of a project’s snippet. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/snippets/2/files/master/snippet%2Erb/raw" Retrieve user agent details --------------------------- Retrieves user agent details for a specified snippet. Available only for users with administrator access. GET /projects/:id/snippets/:snippet_id/user_agent_detail Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `snippet_id` | integer | Yes | ID of a snippet. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `akismet_submitted` | boolean | If `true`, the snippet was submitted to Akismet for spam detection. | | `ip_address` | string | IP address of the user who created the snippet. | | `user_agent` | string | User agent string of the browser used to create the snippet. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/snippets/2/user_agent_detail" Example response: { "user_agent": "AppleWebKit/537.36", "ip_address": "127.0.0.1", "akismet_submitted": false } --- # Project integrations API | GitLab Docs * * * Project integrations API ======================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [integrations](https://docs.gitlab.com/user/project/integrations/) for a project. Prerequisites: * You must have the Maintainer or Owner role for the project. List all active integrations ---------------------------- History * `vulnerability_events` field [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131831) in GitLab 16.4. * `inherited` field [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154915) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `inherited` field [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. Get a list of all active project integrations. The `vulnerability_events` field is only available for GitLab Enterprise Edition. GET /projects/:id/integrations Example response: [\ {\ "id": 75,\ "title": "Jenkins CI",\ "slug": "jenkins",\ "created_at": "2019-11-20T11:20:25.297Z",\ "updated_at": "2019-11-20T12:24:37.498Z",\ "active": true,\ "commit_events": true,\ "push_events": true,\ "issues_events": true,\ "alert_events": true,\ "confidential_issues_events": true,\ "merge_requests_events": true,\ "tag_push_events": false,\ "deployment_events": false,\ "note_events": true,\ "confidential_note_events": true,\ "pipeline_events": true,\ "wiki_page_events": true,\ "job_events": true,\ "comment_on_event_enabled": true,\ "inherited": false,\ "vulnerability_events": true\ },\ {\ "id": 76,\ "title": "Alerts endpoint",\ "slug": "alerts",\ "created_at": "2019-11-20T11:20:25.297Z",\ "updated_at": "2019-11-20T12:24:37.498Z",\ "active": true,\ "commit_events": true,\ "push_events": true,\ "issues_events": true,\ "alert_events": true,\ "confidential_issues_events": true,\ "merge_requests_events": true,\ "tag_push_events": true,\ "deployment_events": false,\ "note_events": true,\ "confidential_note_events": true,\ "pipeline_events": true,\ "wiki_page_events": true,\ "job_events": true,\ "comment_on_event_enabled": true,\ "inherited": false,\ "vulnerability_events": true\ }\ ] Apple App Store Connect ----------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Apple App Store Connect Set up the Apple App Store Connect integration for a project. PUT /projects/:id/integrations/apple_app_store Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `app_store_issuer_id` | string | yes | Apple App Store Connect issuer ID. | | `app_store_key_id` | string | yes | Apple App Store Connect key ID. | | `app_store_private_key_file_name` | string | yes | Apple App Store Connect private key filename. | | `app_store_private_key` | string | yes | Apple App Store Connect private key. | | `app_store_protected_refs` | boolean | no | Set variables on protected branches and tags only. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Apple App Store Connect Disable the Apple App Store Connect integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/apple_app_store ### Get Apple App Store Connect settings Get the Apple App Store Connect integration settings for a project. GET /projects/:id/integrations/apple_app_store Asana ----- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Asana Set up the Asana integration for a project. PUT /projects/:id/integrations/asana Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `api_key` | string | yes | User API token. The user must have access to the task. All comments are attributed to this user. | | `restrict_to_branch` | string | no | Comma-separated list of branches to be automatically inspected. Leave blank to include all branches. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Asana Disable the Asana integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/asana ### Get Asana settings Get the Asana integration settings for a project. GET /projects/:id/integrations/asana Assembla -------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Assembla Set up the Assembla integration for a project. PUT /projects/:id/integrations/assembla Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The authentication token. | | `subdomain` | string | no | The subdomain setting. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Assembla Disable the Assembla integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/assembla ### Get Assembla settings Get the Assembla integration settings for a project. GET /projects/:id/integrations/assembla Atlassian Bamboo ---------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Atlassian Bamboo Set up the Atlassian Bamboo integration for a project. You must configure automatic revision labeling and a repository trigger in Bamboo. PUT /projects/:id/integrations/bamboo Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `bamboo_url` | string | yes | Bamboo root URL (for example, `https://bamboo.example.com`). | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `build_key` | string | yes | Bamboo build plan key (for example, `KEY`). | | `username` | string | yes | User with API access to the Bamboo server. | | `password` | string | yes | Password of the user. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Atlassian Bamboo Disable the Atlassian Bamboo integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/bamboo ### Get Atlassian Bamboo settings Get the Atlassian Bamboo integration settings for a project. GET /projects/:id/integrations/bamboo Bugzilla -------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Bugzilla Set up the Bugzilla integration for a project. PUT /projects/:id/integrations/bugzilla Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Bugzilla Disable the Bugzilla integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/bugzilla ### Get Bugzilla settings Get the Bugzilla integration settings for a project. GET /projects/:id/integrations/bugzilla Buildkite --------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Buildkite Set up the Buildkite integration for a project. PUT /projects/:id/integrations/buildkite Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | Token you get after you create a Buildkite pipeline with a GitLab repository. | | `project_url` | string | yes | Pipeline URL (for example, `https://buildkite.com/example/pipeline`). | | `enable_ssl_verification` | boolean | no | **Deprecated**: This parameter has no effect because SSL verification is always enabled. | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Buildkite Disable the Buildkite integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/buildkite ### Get Buildkite settings Get the Buildkite integration settings for a project. GET /projects/:id/integrations/buildkite Campfire Classic ---------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. You can integrate with Campfire Classic. However, Campfire Classic is an old product that is [no longer sold](https://gitlab.com/gitlab-org/gitlab/-/issues/329337) by Basecamp. ### Set up Campfire Classic Set up the Campfire Classic integration for a project. PUT /projects/:id/integrations/campfire Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | API authentication token from Campfire Classic. To get the token, sign in to Campfire Classic and select **My info**. | | `subdomain` | string | no | `.campfirenow.com` subdomain when you’re signed in. | | `room` | string | no | ID portion of the Campfire Classic room URL. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Campfire Classic Disable the Campfire Classic integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/campfire ### Get Campfire Classic settings Get the Campfire Classic integration settings for a project. GET /projects/:id/integrations/campfire ClickUp ------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120732) in GitLab 16.1. * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up ClickUp Set up the ClickUp integration for a project. PUT /projects/:id/integrations/clickup Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable ClickUp Disable the ClickUp integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/clickup ### Get ClickUp settings Get the ClickUp integration settings for a project. GET /projects/:id/integrations/clickup Confluence Workspace -------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. Use a Confluence Cloud Workspace as your project wiki. ### Set up Confluence Workspace Set up the Confluence Workspace integration for a project. PUT /projects/:id/integrations/confluence Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `confluence_url` | string | yes | URL of the Confluence Workspace hosted on `atlassian.net`. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Confluence Workspace Disable the Confluence Workspace integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/confluence ### Get Confluence Workspace settings Get the Confluence Workspace integration settings for a project. GET /projects/:id/integrations/confluence Custom issue tracker -------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up a custom issue tracker Set up a custom issue tracker for a project. PUT /projects/:id/integrations/custom-issue-tracker Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable a custom issue tracker Disable a custom issue tracker for a project. Integration settings are reset. DELETE /projects/:id/integrations/custom-issue-tracker ### Get custom issue tracker settings Get the custom issue tracker settings for a project. GET /projects/:id/integrations/custom-issue-tracker Datadog ------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Datadog Set up the Datadog integration for a project. PUT /projects/:id/integrations/datadog Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `api_key` | string | yes | [API key](https://docs.datadoghq.com/account_management/api-app-keys/)
used for authentication with Datadog. | | `datadog_ci_visibility` | boolean | yes | Enables collection of pipeline and job events in Datadog to display pipeline execution traces. | | `api_url` | string | no | Full URL of your Datadog site. | | `datadog_env` | string | no | For self-managed deployments, `env%` tag for all the data sent to Datadog. | | `datadog_service` | string | no | GitLab instance to tag all data from in Datadog. Can be used when managing several self-managed deployments. | | `datadog_site` | string | no | Datadog site to send data to. To send data to the EU site, use `datadoghq.eu`. | | `datadog_tags` | string | no | Custom tags in Datadog. Specify one tag per line in the format `key:value\nkey2:value2`. | | `archive_trace_events` | boolean | no | When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346339)
in GitLab 15.3). | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Datadog Disable the Datadog integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/datadog ### Get Datadog settings Get the Datadog integration settings for a project. GET /projects/:id/integrations/datadog Diffblue Cover -------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Diffblue Cover Set up the Diffblue Cover integration for a project. PUT /projects/:id/integrations/diffblue-cover Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `diffblue_license_key` | string | yes | Diffblue Cover license key. | | `diffblue_access_token_name` | string | yes | Access token name used by Diffblue Cover in pipelines. | | `diffblue_access_token_secret` | string | yes | Access token secret used by Diffblue Cover in pipelines. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Diffblue Cover Disable the Diffblue Cover integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/diffblue-cover ### Get Diffblue Cover settings Get the Diffblue Cover integration settings for a project. GET /projects/:id/integrations/diffblue-cover Discord Notifications --------------------- History * `_channel` parameters [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125621) in GitLab 16.3. * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Discord Notifications Set up Discord Notifications for a project. PUT /projects/:id/integrations/discord Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | Discord webhook (for example, `https://discord.com/api/webhooks/...`). | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `confidential_issue_channel` | string | no | The webhook override to receive notifications for confidential issue events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `confidential_note_channel` | string | no | The webhook override to receive notifications for confidential note events. | | `deployment_events` | boolean | no | Enable notifications for deployment events. | | `deployment_channel` | string | no | The webhook override to receive notifications for deployment events. | | `group_confidential_mentions_events` | boolean | no | Enable notifications for group confidential mention events. | | `group_confidential_mentions_channel` | string | no | The webhook override to receive notifications for group confidential mention events. | | `group_mentions_events` | boolean | no | Enable notifications for group mention events. | | `group_mentions_channel` | string | no | The webhook override to receive notifications for group mention events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `issue_channel` | string | no | The webhook override to receive notifications for issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `merge_request_channel` | string | no | The webhook override to receive notifications for merge request events. | | `note_events` | boolean | no | Enable notifications for note events. | | `note_channel` | string | no | The webhook override to receive notifications for note events. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `pipeline_channel` | string | no | The webhook override to receive notifications for pipeline events. | | `push_events` | boolean | no | Enable notifications for push events. | | `push_channel` | string | no | The webhook override to receive notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `tag_push_channel` | string | no | The webhook override to receive notifications for tag push events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `wiki_page_channel` | string | no | The webhook override to receive notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Discord Notifications Disable Discord Notifications for a project. Integration settings are reset. DELETE /projects/:id/integrations/discord ### Get Discord Notifications settings Get the Discord Notifications settings for a project. GET /projects/:id/integrations/discord Drone ----- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Drone Set up the Drone integration for a project. PUT /projects/:id/integrations/drone-ci Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | Drone CI token. | | `drone_url` | string | yes | Drone CI URL (for example, `http://drone.example.com`). | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Drone Disable the Drone integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/drone-ci ### Get Drone settings Get the Drone integration settings for a project. GET /projects/:id/integrations/drone-ci Emails on push -------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up emails on push Set up the emails on push integration for a project. PUT /projects/:id/integrations/emails-on-push Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `recipients` | string | yes | Emails separated by whitespace. | | `disable_diffs` | boolean | no | Disable code diffs. | | `send_from_committer_email` | boolean | no | Send from committer. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. Notifications are always fired for tag pushes. The default value is `all`. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable emails on push Disable the emails on push integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/emails-on-push ### Get emails on push settings Get the emails on push integration settings for a project. GET /projects/:id/integrations/emails-on-push Engineering Workflow Management (EWM) ------------------------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up EWM Set up the EWM integration for a project. PUT /projects/:id/integrations/ewm Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `project_url` | string | yes | URL of the project. | | `issues_url` | string | yes | URL of the issue. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable EWM Disable the EWM integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/ewm ### Get EWM settings Get the EWM integration settings for a project. GET /projects/:id/integrations/ewm External wiki ------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up an external wiki Set up an external wiki for a project. PUT /projects/:id/integrations/external-wiki Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `external_wiki_url` | string | yes | URL of the external wiki. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable an external wiki Disable an external wiki for a project. Integration settings are reset. DELETE /projects/:id/integrations/external-wiki ### Get external wiki settings Get the external wiki settings for a project. GET /projects/:id/integrations/external-wiki GitGuardian ----------- * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/435706) in GitLab 16.9 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `git_guardian_integration`. Enabled by default. Disabled on GitLab.com. * [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/438695#note_2226917025) in GitLab 17.7. * [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176391) in GitLab 17.8. Feature flag `git_guardian_integration` removed. * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. [GitGuardian](https://www.gitguardian.com/) is a cybersecurity service that detects sensitive data such as API keys and passwords in source code repositories. It scans Git repositories, alerts on policy violations, and helps organizations fix security issues before hackers can exploit them. You can configure GitLab to reject commits based on GitGuardian policies. For known issues and troubleshooting steps, see [GitGuardian troubleshooting](https://docs.gitlab.com/user/project/integrations/git_guardian/#troubleshooting) . ### Set up GitGuardian Set up the GitGuardian integration for a project. PUT /projects/:id/integrations/git-guardian Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | GitGuardian API token with `scan` scope. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable GitGuardian Disable the GitGuardian integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/git-guardian ### Get GitGuardian settings Get the GitGuardian integration settings for a project. GET /projects/:id/integrations/git-guardian GitHub ------ * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up GitHub Set up the GitHub integration for a project. PUT /projects/:id/integrations/github Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | GitHub API token with `repo:status` OAuth scope. | | `repository_url` | string | yes | GitHub repository URL. | | `static_context` | boolean | no | Append the hostname of your GitLab instance to the [status check name](https://docs.gitlab.com/user/project/integrations/github/#static-or-dynamic-status-check-names)
. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable GitHub Disable the GitHub integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/github ### Get GitHub settings Get the GitHub integration settings for a project. GET /projects/:id/integrations/github GitLab for Jira Cloud app ------------------------- The GitLab for Jira Cloud app integration is enabled or disabled automatically through [group linking and unlinking in Jira](https://docs.gitlab.com/integration/jira/connect-app/#configure-the-gitlab-for-jira-cloud-app) . You cannot enable or disable the integration with the GitLab integrations form or the API. ### Update integration for a project Use this API endpoint to update an integration you create with group linking in Jira. PUT /projects/:id/integrations/jira-cloud-app Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `jira_cloud_app_service_ids` | string | no | Jira Service Management Service IDs. Use commas (`,`) to separate multiple IDs. | | `jira_cloud_app_enable_deployment_gating` | boolean | no | Enables deployment gating for blocked GitLab deployments from Jira Service Management. | | `jira_cloud_app_deployment_gating_environments` | string | no | The environments (production, staging, testing, or development) to enable deployment gating. Required if deployment gating is enabled. Use commas (`,`) to separate multiple environments. | ### Get GitLab for Jira Cloud app settings Get the GitLab for Jira Cloud app integration settings for a project. GET /projects/:id/integrations/jira-cloud-app GitLab for Slack app -------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up GitLab for Slack app Update the GitLab for Slack app integration for a project. You cannot create a GitLab for Slack app through the API because the integration requires an OAuth 2.0 token that you cannot get from the GitLab API alone. Instead, you must [install the app](https://docs.gitlab.com/user/project/integrations/gitlab_slack_application/#install-the-gitlab-for-slack-app) from the GitLab UI. You can then use this API endpoint to update the integration. PUT /projects/:id/integrations/gitlab-slack-application Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channel` | string | no | Default channel to use if no other channel is configured. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `alert_events` | boolean | no | Enable notifications for alert events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `deployment_events` | boolean | no | Enable notifications for deployment events. | | `incidents_events` | boolean | no | Enable notifications for incident events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `vulnerability_events` | boolean | no | Enable notifications for vulnerability events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `labels_to_be_notified` | string | no | Labels to send notifications for. If not set, receive notifications for all events. | | `labels_to_be_notified_behavior` | string | no | Labels to be notified for. Valid options are `match_any` and `match_all`. Defaults to `match_any`. | | `push_channel` | string | no | Name of the channel to receive notifications for push events. | | `issue_channel` | string | no | Name of the channel to receive notifications for issue events. | | `confidential_issue_channel` | string | no | Name of the channel to receive notifications for confidential issue events. | | `merge_request_channel` | string | no | Name of the channel to receive notifications for merge request events. | | `note_channel` | string | no | Name of the channel to receive notifications for note events. | | `confidential_note_channel` | string | no | Name of the channel to receive notifications for confidential note events. | | `tag_push_channel` | string | no | Name of the channel to receive notifications for tag push events. | | `pipeline_channel` | string | no | Name of the channel to receive notifications for pipeline events. | | `wiki_page_channel` | string | no | Name of the channel to receive notifications for wiki page events. | | `deployment_channel` | string | no | Name of the channel to receive notifications for deployment events. | | `incident_channel` | string | no | Name of the channel to receive notifications for incident events. | | `vulnerability_channel` | string | no | Name of the channel to receive notifications for vulnerability events. | | `alert_channel` | string | no | Name of the channel to receive notifications for alert events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable GitLab for Slack app Disable the GitLab for Slack app integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/gitlab-slack-application ### Get GitLab for Slack app settings Get the GitLab for Slack app integration settings for a project. GET /projects/:id/integrations/gitlab-slack-application Google Chat ----------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Google Chat Set up the Google Chat integration for a project. PUT /projects/:id/integrations/hangouts-chat Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Hangouts Chat webhook (for example, `https://chat.googleapis.com/v1/spaces...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Google Chat Disable the Google Chat integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/hangouts-chat ### Get Google Chat settings Get the Google Chat integration settings for a project. GET /projects/:id/integrations/hangouts-chat Google Artifact Management -------------------------- * Tier: Free, Premium, Ultimate * Offering: GitLab.com * Status: Beta History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/425066) in GitLab 16.9 as a [beta](https://docs.gitlab.com/policy/development_stages_support/) feature [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `google_cloud_support_feature_flag`. Disabled by default. * [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150472) in GitLab 17.1. Feature flag `google_cloud_support_feature_flag` removed. * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. This feature is in [beta](https://docs.gitlab.com/policy/development_stages_support/) . ### Set up Google Artifact Management Set up the Google Artifact Management integration for a project. PUT /projects/:id/integrations/google-cloud-platform-artifact-registry Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `artifact_registry_project_id` | string | yes | ID of the Google Cloud project. | | `artifact_registry_location` | string | yes | Location of the Artifact Registry repository. | | `artifact_registry_repositories` | string | yes | Repository of Artifact Registry. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Google Artifact Management Disable the Google Artifact Management integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/google-cloud-platform-artifact-registry ### Get Google Artifact Management settings Get the Google Artifact Management integration settings for a project. GET /projects/:id/integrations/google-cloud-platform-artifact-registry Google Cloud Identity and Access Management (IAM) ------------------------------------------------- * Tier: Free, Premium, Ultimate * Offering: GitLab.com * Status: Beta History * Introduced in GitLab 16.10 as a [beta](https://docs.gitlab.com/policy/development_stages_support/) feature [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `google_cloud_support_feature_flag`. Disabled by default. * [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150472) in GitLab 17.1. Feature flag `google_cloud_support_feature_flag` removed. * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. This feature is in [beta](https://docs.gitlab.com/policy/development_stages_support/) . ### Set up Google Cloud Identity and Access Management Set up the Google Cloud Identity and Access Management integration for a project. PUT /projects/:id/integrations/google-cloud-platform-workload-identity-federation Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `workload_identity_federation_project_id` | string | yes | Google Cloud project ID for the Workload Identity Federation. | | `workload_identity_federation_project_number` | integer | yes | Google Cloud project number for the Workload Identity Federation. | | `workload_identity_pool_id` | string | yes | ID of the workload identity pool. | | `workload_identity_pool_provider_id` | string | yes | ID of the workload identity pool provider. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Google Cloud Identity and Access Management Disable the Google Cloud Identity and Access Management integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/google-cloud-platform-workload-identity-federation ### Get Google Cloud Identity and Access Management Get the settings for the Google Cloud Identity and Access Management for a project. GET /projects/:id/integration/google-cloud-platform-workload-identity-federation Google Play ----------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Google Play Set up the Google Play integration for a project. PUT /projects/:id/integrations/google-play Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `package_name` | string | yes | Package name of the app in Google Play. | | `service_account_key` | string | yes | Google Play service account key. | | `service_account_key_file_name` | string | yes | File name of the Google Play service account key. | | `google_play_protected_refs` | boolean | no | Set variables on protected branches and tags only. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Google Play Disable the Google Play integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/google-play ### Get Google Play settings Get the Google Play integration settings for a project. GET /projects/:id/integrations/google-play Harbor ------ History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Harbor Set up the Harbor integration for a project. PUT /projects/:id/integrations/harbor Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | The base URL to the Harbor instance linked to the GitLab project. For example, `https://demo.goharbor.io`. | | `project_name` | string | yes | The name of the project in the Harbor instance. For example, `testproject`. | | `username` | string | yes | The username created in the Harbor interface. | | `password` | string | yes | The password of the user. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Harbor Disable the Harbor integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/harbor ### Get Harbor settings Get the Harbor integration settings for a project. GET /projects/:id/integrations/harbor irker (IRC gateway) ------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up irker Set up the irker integration for a project. PUT /projects/:id/integrations/irker Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `recipients` | string | yes | Comma-separated list of channels or email addresses. | | `default_irc_uri` | string | no | URI to add before each recipient. The default value is `irc://irc.network.net:6697/`. | | `server_host` | string | no | irker daemon hostname. The default value is `localhost`. | | `server_port` | integer | no | irker daemon port. The default value is `6659`. | | `colorize_messages` | boolean | no | Colorize messages. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable irker Disable the irker integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/irker ### Get irker settings Get the irker integration settings for a project. GET /projects/:id/integrations/irker Jenkins ------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Jenkins Set up the Jenkins integration for a project. PUT /projects/:id/integrations/jenkins Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `jenkins_url` | string | yes | URL of the Jenkins server. | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `project_name` | string | yes | Name of the Jenkins project. | | `username` | string | no | Username of the Jenkins server. | | `password` | string | no | Password of the Jenkins server. | | `push_events` | boolean | no | Enables notifications for push events. | | `merge_requests_events` | boolean | no | Enables notifications for merge request events. | | `tag_push_events` | boolean | no | Enables notifications for tag push events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Jenkins Disable the Jenkins integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/jenkins ### Get Jenkins settings Get the Jenkins integration settings for a project. GET /projects/:id/integrations/jenkins JetBrains TeamCity ------------------ History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up JetBrains TeamCity Set up the JetBrains TeamCity integration for a project. The build configuration in TeamCity must use the build number format `%build.vcs.number%`. In the advanced settings for VCS root, configure monitoring for all branches so merge requests can build. PUT /projects/:id/integrations/teamcity Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `teamcity_url` | string | yes | TeamCity root URL (for example, `https://teamcity.example.com`). | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `build_type` | string | yes | The build configuration ID of the TeamCity project. | | `username` | string | yes | A user with permissions to trigger a manual build. | | `password` | string | yes | The password of the user. | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable JetBrains TeamCity Disable the JetBrains TeamCity integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/teamcity ### Get JetBrains TeamCity settings Get the JetBrains TeamCity integration settings for a project. GET /projects/:id/integrations/teamcity Jira issues ----------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Jira issues Set up the [Jira issues integration](https://docs.gitlab.com/integration/jira/configure/) for a project. PUT /projects/:id/integrations/jira Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | The URL to the Jira project which is being linked to this GitLab project (for example, `https://jira.example.com`). | | `api_url` | string | no | The base URL to the Jira instance API. Web URL value is used if not set (for example, `https://jira-api.example.com`). | | `username` | string | no | The email or username to use with Jira. Use an email for Jira Cloud, and a username for Jira Data Center and Jira Server. Required when using Basic Authentication (`jira_auth_type` is `0`). | | `password` | string | yes | The Jira API token, password, or personal access token to use with Jira. When using Basic Authentication (`jira_auth_type` is `0`), use an API token for Jira Cloud, and a password for Jira Data Center or Jira Server. For a Jira personal access token (`jira_auth_type` is `1`), use the personal access token. | | `jira_auth_type` | integer | no | The authentication method to use with Jira. Use `0` for Basic Authentication, and `1` for Jira personal access token. Defaults to `0`. | | `jira_issue_prefix` | string | no | Prefix to match Jira issue keys. | | `jira_issue_regex` | string | no | Regular expression to match Jira issue keys. | | `jira_issue_transition_automatic` | boolean | no | Enable [automatic issue transitions](https://docs.gitlab.com/integration/jira/issues/#automatic-issue-transitions)
. Takes precedence over `jira_issue_transition_id` if enabled. Defaults to `false`. | | `jira_issue_transition_id` | string | no | The ID of one or more transitions for [custom issue transitions](https://docs.gitlab.com/integration/jira/issues/#custom-issue-transitions)
.Ignored when `jira_issue_transition_automatic` is enabled. Defaults to a blank string,which disables custom transitions. | | `commit_events` | boolean | no | Enable notifications for commit events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `comment_on_event_enabled` | boolean | no | Enable comments in Jira issues on each GitLab event (commit or merge request). | | `issues_enabled` | boolean | no | Enable viewing Jira issues in GitLab. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267015)
in GitLab 17.0. | | `project_keys` | array of strings | no | Keys of Jira projects. When `issues_enabled` is `true`, this setting specifies which Jira projects to view issues from in GitLab. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267015)
in GitLab 17.0. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | | `vulnerabilities_enabled` | boolean | no | Available only in GitLab EE. When set to `true`, creates Jira issues for GitLab vulnerabilities. | | `vulnerabilities_issuetype` | number | no | Available only in GitLab EE. ID of the Jira issue type to use when creating issues from vulnerabilities. | | `project_key` | string | no | Available only in GitLab EE. Key of the project to use when creating issues from vulnerabilities. This parameter is required if using the integration to create issues from vulnerabilities. | | `customize_jira_issue_enabled` | boolean | no | Available only in GitLab EE. When set to `true`, opens a prefilled form on the Jira instance when creating a Jira issue from a vulnerability. | ### Disable Jira Disable the Jira issues integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/jira ### Get Jira settings Get the Jira issues integration settings for a project. GET /projects/:id/integrations/jira Linear ------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/198297) in GitLab 18.3. ### Set up Linear Set up the Linear integration for a group. PUT /projects/:id/integrations/linear Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `workspace_url` | string | yes | URL of the issue. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Linear Disable the Linear integration for a group. Integration settings are reset. DELETE /projects/:id/integrations/linear ### Get Linear settings Get the Linear integration settings for a group. GET /projects/:id/integrations/linear Matrix notifications -------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Matrix notifications Set up Matrix notifications for a project. PUT /projects/:id/integrations/matrix Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `hostname` | string | no | Custom hostname of the Matrix server. The default value is `https://matrix.org`. | | `token` | string | yes | The Matrix access token (for example, `syt-zyx57W2v1u123ew11`). | | `room` | string | yes | Unique identifier for the target room (in the format `!qPKKM111FFKKsfoCVy:matrix.org`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Matrix notifications Disable Matrix notifications for a project. Integration settings are reset. DELETE /projects/:id/integrations/matrix ### Get Matrix notifications settings Get the Matrix notifications settings for a project. GET /projects/:id/integrations/matrix Mattermost notifications ------------------------ History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Mattermost notifications Set up Mattermost notifications for a project. PUT /projects/:id/integrations/mattermost Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | Mattermost notifications webhook (for example, `http://mattermost.example.com/hooks/...`). | | `username` | string | no | Mattermost notifications username. | | `channel` | string | no | Default channel to use if no other channel is configured. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `labels_to_be_notified` | string | no | Labels to send notifications for. Leave blank to receive notifications for all events. | | `labels_to_be_notified_behavior` | string | no | Labels to be notified for. Valid options are `match_any` and `match_all`. The default value is `match_any`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `push_channel` | string | no | The name of the channel to receive notifications for push events. | | `issue_channel` | string | no | The name of the channel to receive notifications for issue events. | | `confidential_issue_channel` | string | no | The name of the channel to receive notifications for confidential issue events. | | `merge_request_channel` | string | no | The name of the channel to receive notifications for merge request events. | | `note_channel` | string | no | The name of the channel to receive notifications for note events. | | `confidential_note_channel` | string | no | The name of the channel to receive notifications for confidential note events. | | `tag_push_channel` | string | no | The name of the channel to receive notifications for tag push events. | | `pipeline_channel` | string | no | The name of the channel to receive notifications for pipeline events. | | `wiki_page_channel` | string | no | The name of the channel to receive notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Mattermost notifications Disable Mattermost notifications for a project. Integration settings are reset. DELETE /projects/:id/integrations/mattermost ### Get Mattermost notifications settings Get the Mattermost notifications settings for a project. GET /projects/:id/integrations/mattermost Mattermost slash commands ------------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Mattermost slash commands Set up Mattermost slash commands for a project. PUT /projects/:id/integrations/mattermost-slash-commands Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The Mattermost token. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Mattermost slash commands Disable Mattermost slash commands for a project. Integration settings are reset. DELETE /projects/:id/integrations/mattermost-slash-commands ### Get Mattermost slash commands settings Get the Mattermost slash commands settings for a project. GET /projects/:id/integrations/mattermost-slash-commands Microsoft Teams notifications ----------------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Microsoft Teams notifications Set up Microsoft Teams notifications for a project. PUT /projects/:id/integrations/microsoft-teams Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Microsoft Teams webhook (for example, `https://outlook.office.com/webhook/...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Microsoft Teams notifications Disable Microsoft Teams notifications for a project. Integration settings are reset. DELETE /projects/:id/integrations/microsoft-teams ### Get Microsoft Teams notifications settings Get the Microsoft Teams notifications settings for a project. GET /projects/:id/integrations/microsoft-teams Mock CI ------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. This integration is only available in a development environment. For an example Mock CI server, see [`gitlab-org/gitlab-mock-ci-service`](https://gitlab.com/gitlab-org/gitlab-mock-ci-service) . ### Set up Mock CI Set up the Mock CI integration for a project. PUT /projects/:id/integrations/mock-ci Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `mock_service_url` | string | yes | URL of the Mock CI integration. | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Mock CI Disable the Mock CI integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/mock-ci ### Get Mock CI settings Get the Mock CI integration settings for a project. GET /projects/:id/integrations/mock-ci Packagist --------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Packagist Set up the Packagist integration for a project. PUT /projects/:id/integrations/packagist Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `username` | string | yes | Username of a Packagist account. | | `token` | string | yes | API token of the Packagist server. | | `server` | boolean | no | URL of the Packagist server. The default value is `https://packagist.org`. | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Packagist Disable the Packagist integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/packagist ### Get Packagist settings Get the Packagist integration settings for a project. GET /projects/:id/integrations/packagist Phorge ------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145863) in GitLab 16.11. * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Phorge Set up the Phorge integration for a project. PUT /projects/:id/integrations/phorge Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Phorge Disable the Phorge integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/phorge ### Get Phorge settings Get the Phorge integration settings for a project. GET /projects/:id/integrations/phorge Pipeline status emails ---------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up pipeline status emails Set up pipeline status emails for a project. PUT /projects/:id/integrations/pipelines-email Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `recipients` | string | yes | Comma-separated list of recipient email addresses. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `notify_only_default_branch` | boolean | no | Send notifications for the default branch. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable pipeline status emails Disable pipeline status emails for a project. Integration settings are reset. DELETE /projects/:id/integrations/pipelines-email ### Get pipeline status emails settings Get the pipeline status emails settings for a project. GET /projects/:id/integrations/pipelines-email Pivotal Tracker --------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Pivotal Tracker Set up the Pivotal Tracker integration for a project. PUT /projects/:id/integrations/pivotaltracker Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The Pivotal Tracker token. | | `restrict_to_branch` | boolean | no | Comma-separated list of branches to automatically inspect. Leave blank to include all branches. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Pivotal Tracker Disable the Pivotal Tracker integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/pivotaltracker ### Get Pivotal Tracker settings Get the Pivotal Tracker integration settings for a project. GET /projects/:id/integrations/pivotaltracker Pumble ------ History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Pumble Set up the Pumble integration for a project. PUT /projects/:id/integrations/pumble Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Pumble webhook (for example, `https://api.pumble.com/workspaces/x/...`). | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default is `default`. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `note_events` | boolean | no | Enable notifications for note events. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Pumble Disable the Pumble integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/pumble ### Get Pumble settings Get the Pumble integration settings for a project. GET /projects/:id/integrations/pumble Pushover -------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Pushover Set up the Pushover integration for a project. PUT /projects/:id/integrations/pushover Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `api_key` | string | yes | The application key. | | `user_key` | string | yes | The user key. | | `priority` | string | yes | The priority. | | `device` | string | no | Leave blank for all active devices. | | `sound` | string | no | The sound of the notification. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Pushover Disable the Pushover integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/pushover ### Get Pushover settings Get the Pushover integration settings for a project. GET /projects/:id/integrations/pushover Redmine ------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Redmine Set up the Redmine integration for a project. PUT /projects/:id/integrations/redmine Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `project_url` | string | yes | URL of the project. | | `issues_url` | string | yes | URL of the issue. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Redmine Disable the Redmine integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/redmine ### Get Redmine settings Get the Redmine integration settings for a project. GET /projects/:id/integrations/redmine Slack notifications ------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Slack notifications Set up Slack notifications for a project. PUT /projects/:id/integrations/slack Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | Slack notifications webhook (for example, `https://hooks.slack.com/services/...`). | | `username` | string | no | Slack notifications username. | | `channel` | string | no | Default channel to use if no other channel is configured. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `labels_to_be_notified` | string | no | Labels to send notifications for. Leave blank to receive notifications for all events. | | `labels_to_be_notified_behavior` | string | no | Labels to be notified for. Valid options are `match_any` and `match_all`. The default value is `match_any`. | | `alert_channel` | string | no | The name of the channel to receive notifications for alert events. | | `alert_events` | boolean | no | Enable notifications for alert events. | | `commit_events` | boolean | no | Enable notifications for commit events. | | `confidential_issue_channel` | string | no | The name of the channel to receive notifications for confidential issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `confidential_note_channel` | string | no | The name of the channel to receive notifications for confidential note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `deployment_channel` | string | no | The name of the channel to receive notifications for deployment events. | | `deployment_events` | boolean | no | Enable notifications for deployment events. | | `incident_channel` | string | no | The name of the channel to receive notifications for incident events. | | `incidents_events` | boolean | no | Enable notifications for incident events. | | `issue_channel` | string | no | The name of the channel to receive notifications for issue events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `job_events` | boolean | no | Enable notifications for job events. | | `merge_request_channel` | string | no | The name of the channel to receive notifications for merge request events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `note_channel` | string | no | The name of the channel to receive notifications for note events. | | `note_events` | boolean | no | Enable notifications for note events. | | `pipeline_channel` | string | no | The name of the channel to receive notifications for pipeline events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `push_channel` | string | no | The name of the channel to receive notifications for push events. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_channel` | string | no | The name of the channel to receive notifications for tag push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `wiki_page_channel` | string | no | The name of the channel to receive notifications for wiki page events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Slack notifications Disable Slack notifications for a project. Integration settings are reset. DELETE /projects/:id/integrations/slack ### Get Slack notifications settings Get the Slack notifications settings for a project. GET /projects/:id/integrations/slack Slack slash commands -------------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Slack slash commands Set up Slack slash commands for a project. PUT /projects/:id/integrations/slack-slash-commands Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The Slack token. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Slack slash commands Disable Slack slash commands for a project. Integration settings are reset. DELETE /projects/:id/integrations/slack-slash-commands ### Get Slack slash commands settings Get the Slack slash commands settings for a project. GET /projects/:id/integrations/slack-slash-commands Example response: { "id": 4, "title": "Slack slash commands", "slug": "slack-slash-commands", "created_at": "2017-06-27T05:51:39-07:00", "updated_at": "2017-06-27T05:51:39-07:00", "active": true, "push_events": true, "issues_events": true, "confidential_issues_events": true, "merge_requests_events": true, "tag_push_events": true, "note_events": true, "job_events": true, "pipeline_events": true, "comment_on_event_enabled": false, "inherited": false, "properties": { "token": "" } } Squash TM --------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337855) in GitLab 15.10. * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Squash TM Set up the Squash TM integration settings for a project. PUT /projects/:id/integrations/squash-tm Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | URL of the Squash TM webhook. | | `token` | string | no | Secret token. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Squash TM Disable the Squash TM integration for a project. Integration settings are preserved. DELETE /projects/:id/integrations/squash-tm ### Get Squash TM settings Get the Squash TM integration settings for a project. GET /projects/:id/integrations/squash-tm Telegram -------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Telegram Set up the Telegram integration for a project. PUT /projects/:id/integrations/telegram Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `hostname` | string | no | Custom hostname of the Telegram API ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/461313)
in GitLab 17.1). The default value is `https://api.telegram.org`. | | `token` | string | yes | The Telegram bot token (for example, `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`). | | `room` | string | yes | Unique identifier for the target chat or the username of the target channel (in the format `@channelusername`). | | `thread` | integer | no | Unique identifier for the target message thread (topic in a forum supergroup). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/441097)
in GitLab 16.11. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `branches_to_be_notified` | string | no | Branches to send notifications for ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134361)
in GitLab 16.5). Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | yes | Enable notifications for push events. | | `issues_events` | boolean | yes | Enable notifications for issue events. | | `confidential_issues_events` | boolean | yes | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | yes | Enable notifications for merge request events. | | `tag_push_events` | boolean | yes | Enable notifications for tag push events. | | `note_events` | boolean | yes | Enable notifications for note events. | | `confidential_note_events` | boolean | yes | Enable notifications for confidential note events. | | `pipeline_events` | boolean | yes | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | yes | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Telegram Disable the Telegram integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/telegram ### Get Telegram settings Get the Telegram integration settings for a project. GET /projects/:id/integrations/telegram Unify Circuit ------------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Unify Circuit Set up the Unify Circuit integration for a project. PUT /projects/:id/integrations/unify-circuit Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Unify Circuit webhook (for example, `https://circuit.com/rest/v2/webhooks/incoming/...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Unify Circuit Disable the Unify Circuit integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/unify-circuit ### Get Unify Circuit settings Get the Unify Circuit integration settings for a project. GET /projects/:id/integrations/unify-circuit Webex Teams ----------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up Webex Teams Set up Webex Teams for a project. PUT /projects/:id/integrations/webex-teams Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Webex Teams webhook (for example, `https://api.ciscospark.com/v1/webhooks/incoming/...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable Webex Teams Disable Webex Teams for a project. Integration settings are reset. DELETE /projects/:id/integrations/webex-teams ### Get Webex Teams settings Get the Webex Teams settings for a project. GET /projects/:id/integrations/webex-teams YouTrack -------- History * `use_inherited_settings` parameter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467089) in GitLab 17.2 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `integration_api_inheritance`. Disabled by default. * `use_inherited_settings` parameter [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/467186) in GitLab 17.3. Feature flag `integration_api_inheritance` removed. ### Set up YouTrack Set up the YouTrack integration for a project. PUT /projects/:id/integrations/youtrack Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether to inherit the default settings. Defaults to `false`. | ### Disable YouTrack Disable the YouTrack integration for a project. Integration settings are reset. DELETE /projects/:id/integrations/youtrack ### Get YouTrack settings Get the YouTrack integration settings for a project. GET /projects/:id/integrations/youtrack --- # Notes API | GitLab Docs * * * Notes API ========= * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage comments and system records attached to GitLab content. You can: * Create and modify comments on issues, merge requests, epics, snippets, and commits. * Retrieve [system-generated notes](https://docs.gitlab.com/user/project/system_notes/) about object changes. * Sort and paginate results. * Control visibility with confidential and internal flags. * Prevent abuse with rate limiting. Some system-generated notes are tracked as separate resource events: * [Resource label events](https://docs.gitlab.com/api/resource_label_events/) * [Resource state events](https://docs.gitlab.com/api/resource_state_events/) * [Resource milestone events](https://docs.gitlab.com/api/resource_milestone_events/) * [Resource weight events](https://docs.gitlab.com/api/resource_weight_events/) * [Resource iteration events](https://docs.gitlab.com/api/resource_iteration_events/) By default, `GET` requests return 20 results at a time, because the API results are paginated. For more information, see [pagination](https://docs.gitlab.com/api/rest/#pagination) . Resource events --------------- Some system notes are not part of this API, but are recorded as separate events: * [Resource label events](https://docs.gitlab.com/api/resource_label_events/) * [Resource state events](https://docs.gitlab.com/api/resource_state_events/) * [Resource milestone events](https://docs.gitlab.com/api/resource_milestone_events/) * [Resource weight events](https://docs.gitlab.com/api/resource_weight_events/) * [Resource iteration events](https://docs.gitlab.com/api/resource_iteration_events/) Notes pagination ---------------- By default, `GET` requests return 20 results at a time because the API results are paginated. Read more on [pagination](https://docs.gitlab.com/api/rest/#pagination) . Rate limits ----------- To help avoid abuse, you can limit your users to a specific number of `Create` request per minute. For more information, see [Rate limits on note creation](https://docs.gitlab.com/administration/settings/rate_limit_on_notes_creation/) . Issues ------ ### List all issue notes Lists all notes for a specified issue. GET /projects/:id/issues/:issue_iid/notes GET /projects/:id/issues/:issue_iid/notes?sort=asc&order_by=updated_at GET /projects/:id/issues/:issue_iid/notes?activity_filter=only_comments | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `issue_iid` | integer | yes | The IID of an issue | | `activity_filter` | string | no | Filter notes by activity type. Valid values: `all_notes`, `only_comments`, `only_activity`. Default is `all_notes` | | `sort` | string | no | Return issue notes sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return issue notes ordered by `created_at` or `updated_at` fields. Default is `created_at` | [\ {\ "id": 302,\ "body": "closed",\ "author": {\ "id": 1,\ "username": "pipin",\ "email": "admin@example.com",\ "name": "Pip",\ "state": "active",\ "created_at": "2013-09-30T13:46:01Z"\ },\ "created_at": "2013-10-02T09:22:45Z",\ "updated_at": "2013-10-02T10:22:45Z",\ "system": true,\ "noteable_id": 377,\ "noteable_type": "Issue",\ "project_id": 5,\ "noteable_iid": 377,\ "resolvable": false,\ "confidential": false,\ "internal": false,\ "imported": false,\ "imported_from": "none"\ },\ {\ "id": 305,\ "body": "Text of the comment\r\n",\ "author": {\ "id": 1,\ "username": "pipin",\ "email": "admin@example.com",\ "name": "Pip",\ "state": "active",\ "created_at": "2013-09-30T13:46:01Z"\ },\ "created_at": "2013-10-02T09:56:03Z",\ "updated_at": "2013-10-02T09:56:03Z",\ "system": true,\ "noteable_id": 121,\ "noteable_type": "Issue",\ "project_id": 5,\ "noteable_iid": 121,\ "resolvable": false,\ "confidential": true,\ "internal": true,\ "imported": false,\ "imported_from": "none"\ }\ ] curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/issues/11/notes" ### Retrieve an issue note Retrieves a specified note for a project issue. GET /projects/:id/issues/:issue_iid/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `issue_iid` | integer | yes | The IID of a project issue | | `note_id` | integer | yes | The ID of an issue note | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/issues/11/notes/1" ### Create an issue note Creates a note for a specified project issue. POST /projects/:id/issues/:issue_iid/notes Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `issue_iid` | integer | yes | The IID of an issue. | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `confidential` | boolean | no | **Deprecated**: Scheduled to be removed in GitLab 16.0 and renamed to `internal`. The confidential flag of a note. Default is false. | | `internal` | boolean | no | The internal flag of a note. Overrides `confidential` when both parameters are submitted. Default is false. | | `created_at` | string | no | Date time string, ISO 8601 formatted. It must be after 1970-01-01. Example: `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) | curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/issues/11/notes?body=note" ### Update an issue note Updates a specified note of an issue. PUT /projects/:id/issues/:issue_iid/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `issue_iid` | integer | yes | The IID of an issue. | | `note_id` | integer | yes | The ID of a note. | | `body` | string | no | The content of a note. Limited to 1,000,000 characters. | | `confidential` | boolean | no | **Deprecated**: Scheduled to be removed in GitLab 16.0. The confidential flag of a note. Default is false. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/issues/11/notes/636?body=note" ### Delete an issue note Deletes an existing note of an issue. DELETE /projects/:id/issues/:issue_iid/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `issue_iid` | integer | yes | The IID of an issue | | `note_id` | integer | yes | The ID of a note | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/issues/11/notes/636" Snippets -------- The Snippets Notes API is intended for project-level snippets, and not for personal snippets. ### List all snippet notes Lists all notes for a specified snippet. Snippet notes are comments users can post to a snippet. GET /projects/:id/snippets/:snippet_id/notes GET /projects/:id/snippets/:snippet_id/notes?sort=asc&order_by=updated_at | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `snippet_id` | integer | yes | The ID of a project snippet | | `sort` | string | no | Return snippet notes sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return snippet notes ordered by `created_at` or `updated_at` fields. Default is `created_at` | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/snippets/11/notes" ### Retrieve a snippet note Retrieves a specified note for a snippet. GET /projects/:id/snippets/:snippet_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `snippet_id` | integer | yes | The ID of a project snippet | | `note_id` | integer | yes | The ID of a snippet note | { "id": 302, "body": "closed", "author": { "id": 1, "username": "pipin", "email": "admin@example.com", "name": "Pip", "state": "active", "created_at": "2013-09-30T13:46:01Z" }, "created_at": "2013-10-02T09:22:45Z", "updated_at": "2013-10-02T10:22:45Z", "system": true, "noteable_id": 377, "noteable_type": "Issue", "project_id": 5, "noteable_iid": 377, "resolvable": false, "confidential": false, "internal": false, "imported": false, "imported_from": "none" } curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/snippets/11/notes/11" ### Create a snippet note Creates a new note for a specified snippet. Snippet notes are user comments on snippets. If you create a note where the body only contains an emoji reaction, GitLab returns this object. POST /projects/:id/snippets/:snippet_id/notes Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `snippet_id` | integer | yes | The ID of a snippet | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `created_at` | string | no | Date time string, ISO 8601 formatted. Example: `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) | curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/snippet/11/notes?body=note" ### Update a snippet note Updates a specified note of a snippet. PUT /projects/:id/snippets/:snippet_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `snippet_id` | integer | yes | The ID of a snippet | | `note_id` | integer | yes | The ID of a snippet note | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/snippets/11/notes/1659?body=note" ### Delete a snippet note Deletes an existing note of a snippet. DELETE /projects/:id/snippets/:snippet_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `snippet_id` | integer | yes | The ID of a snippet | | `note_id` | integer | yes | The ID of a note | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/snippets/52/notes/1659" Merge requests -------------- ### List all merge request notes Lists all notes for a specified merge request. GET /projects/:id/merge_requests/:merge_request_iid/notes GET /projects/:id/merge_requests/:merge_request_iid/notes?sort=asc&order_by=updated_at | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `merge_request_iid` | integer | yes | The IID of a project merge request | | `sort` | string | no | Return merge request notes sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return merge request notes ordered by `created_at` or `updated_at` fields. Default is `created_at` | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes" ### Retrieve a merge request note Retrieves a specified note for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `merge_request_iid` | integer | yes | The IID of a project merge request | | `note_id` | integer | yes | The ID of a merge request note | { "id": 301, "body": "Comment for MR", "author": { "id": 1, "username": "pipin", "email": "admin@example.com", "name": "Pip", "state": "active", "created_at": "2013-09-30T13:46:01Z" }, "created_at": "2013-10-02T08:57:14Z", "updated_at": "2013-10-02T08:57:14Z", "system": false, "noteable_id": 2, "noteable_type": "MergeRequest", "project_id": 5, "noteable_iid": 2, "resolvable": false, "confidential": false, "internal": false } curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes/1" ### Create a merge request note Creates a note for a specified merge request. Notes are not attached to specific lines in a merge request. For other approaches with more granular control, see [post comment to commit](https://docs.gitlab.com/api/commits/#post-comment-to-commit) in the commits API, and [create a new thread in the merge request diff](https://docs.gitlab.com/api/discussions/#create-a-new-thread-in-the-merge-request-diff) in the discussions API. If you create a note where the body only contains an emoji reaction, GitLab returns this object. POST /projects/:id/merge_requests/:merge_request_iid/notes Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `merge_request_iid` | integer | yes | The IID of a project merge request | | `created_at` | string | no | Date time string, ISO 8601 formatted. Example: `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) | | `internal` | boolean | no | The internal flag of a note. Default is false. | | `merge_request_diff_head_sha` | string | no | Required for the [`/merge`](https://docs.gitlab.com/user/project/quick_actions/#merge)
quick action. The SHA of the head commit, which ensures the merge request wasn’t updated after the API request was sent. | curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes?body=note" ### Update a merge request note Updates a specified note of a merge request. PUT /projects/:id/merge_requests/:merge_request_iid/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `merge_request_iid` | integer | yes | The IID of a project merge request | | `note_id` | integer | no | The ID of a note | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `confidential` | boolean | no | **Deprecated**: Scheduled to be removed in GitLab 16.0. The confidential flag of a note. Default is false. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes/1?body=note" ### Delete a merge request note Deletes an existing note of a merge request. DELETE /projects/:id/merge_requests/:merge_request_iid/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `merge_request_iid` | integer | yes | The IID of a merge request | | `note_id` | integer | yes | The ID of a note | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/7/notes/1602" Epics ----- * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated The Epics REST API was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/460668) in GitLab 17.0 and is planned for removal in v5 of the API. From GitLab 17.4 to 18.0, if [the new look for epics](https://docs.gitlab.com/user/group/epics/#epics-as-work-items) is enabled, and in GitLab 18.1 and later, use the Work Items API instead. For more information, see [migrate epic APIs to work items](https://docs.gitlab.com/api/graphql/epic_work_items_api_migration_guide/) . This change is a breaking change. ### List all epic notes Lists all notes for a specified epic. Epic notes are comments users can post to an epic. The epics notes API uses the epic ID instead of epic IID. If you use the epic’s IID, GitLab returns either a 404 error or notes for the wrong epic. It’s different from the [issue notes API](https://docs.gitlab.com/api/notes/#issues) and [merge requests notes API](https://docs.gitlab.com/api/notes/#merge-requests) . GET /groups/:id/epics/:epic_id/notes GET /groups/:id/epics/:epic_id/notes?sort=asc&order_by=updated_at | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `epic_id` | integer | yes | The ID of a group epic | | `sort` | string | no | Return epic notes sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return epic notes ordered by `created_at` or `updated_at` fields. Default is `created_at` | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/epics/11/notes" ### Retrieve an epic note Retrieves a specified note for an epic. GET /groups/:id/epics/:epic_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `epic_id` | integer | yes | The ID of an epic | | `note_id` | integer | yes | The ID of a note | { "id": 302, "body": "Epic note", "author": { "id": 1, "username": "pipin", "email": "admin@example.com", "name": "Pip", "state": "active", "created_at": "2013-09-30T13:46:01Z" }, "created_at": "2013-10-02T09:22:45Z", "updated_at": "2013-10-02T10:22:45Z", "system": true, "noteable_id": 11, "noteable_type": "Epic", "project_id": 5, "noteable_iid": 11, "resolvable": false, "confidential": false, "internal": false, "imported": false, "imported_from": "none" } curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/epics/11/notes/1" ### Create an epic note Creates a note for a specified epic. Epic notes are comments users can post to an epic. If you create a note where the body only contains an emoji reaction, GitLab returns this object. POST /groups/:id/epics/:epic_id/notes Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `epic_id` | integer | yes | The ID of an epic | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `confidential` | boolean | no | **Deprecated**: Scheduled to be removed in GitLab 16.0 and is renamed to `internal`. The confidential flag of a note. Default is `false`. | | `internal` | boolean | no | The internal flag of a note. Overrides `confidential` when both parameters are submitted. Default is `false`. | curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/epics/11/notes?body=note" ### Update an epic note Updates a specified note of an epic. PUT /groups/:id/epics/:epic_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `epic_id` | integer | yes | The ID of an epic | | `note_id` | integer | yes | The ID of a note | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `confidential` | boolean | no | **Deprecated**: Scheduled to be removed in GitLab 16.0. The confidential flag of a note. Default is false. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/epics/11/notes/1?body=note" ### Delete an epic note Deletes an existing note of an epic. DELETE /groups/:id/epics/:epic_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `epic_id` | integer | yes | The ID of an epic | | `note_id` | integer | yes | The ID of a note | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/epics/52/notes/1659" Project wikis ------------- ### List all project wiki notes Lists all notes for a specified project wiki page. Project wiki notes are comments users can post to a wiki page. The wiki page notes API uses the wiki page meta ID instead of wiki page slug. If you use the page’s slug, GitLab returns a 404 error. You can retrieve the meta ID from the [project wikis API](https://docs.gitlab.com/api/wikis/) . GET /projects/:id/wiki_pages/:wiki_page_meta_id/notes GET /projects/:id/wiki_pages/:wiki_page_meta_id/notes?sort=asc&order_by=updated_at Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `sort` | string | no | Return wiki page notes sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return wiki page notes ordered by `created_at` or `updated_at` fields. Default is `created_at` | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/wiki_pages/35/notes" ### Retrieve a wiki page note Retrieves a single note for a specified wiki page. GET /projects/:id/wiki_pages/:wiki_page_meta_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `note_id` | integer | yes | The ID of a note | { "author": { "id": 1, "username": "pipin", "email": "admin@example.com", "name": "Pip", "state": "active", "created_at": "2013-09-30T13:46:01Z" }, "body": "foobar", "commands_changes": {}, "confidential": false, "created_at": "2025-03-11T11:36:32.222Z", "id": 1218, "imported": false, "imported_from": "none", "internal": false, "noteable_id": 35, "noteable_iid": null, "noteable_type": "WikiPage::Meta", "project_id": 5, "resolvable": false, "system": false, "type": null, "updated_at": "2025-03-11T11:36:32.222Z" } curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/wiki_pages/35/notes/1218" ### Create a wiki page note Creates a new note for a single wiki page. Wiki page notes are comments users can post to a wiki page. POST /projects/:id/wiki_pages/:wiki_page_meta_id/notes Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/wiki_pages/35/notes?body=note" ### Update a wiki page note Updates an existing note on a wiki page. PUT /projects/:id/wiki_pages/:wiki_page_meta_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `note_id` | integer | yes | The ID of a note | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/wiki_pages/35/notes/1218?body=note" ### Delete a wiki page note Deletes a note from a wiki page. DELETE /projects/:id/wiki_pages/:wiki_page_meta_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `note_id` | integer | yes | The ID of a note | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/wiki_pages/35/notes/1218" Group wikis ----------- * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated ### List group wiki notes Lists all notes for a specified group wiki page. Group wiki notes are comments users can post to a wiki page. The wiki page notes API uses the wiki page meta ID instead of wiki page slug. If you use the page’s slug, GitLab returns a 404 error. You can retrieve the meta ID from the [group wikis API](https://docs.gitlab.com/api/group_wikis/) . GET /groups/:id/wiki_pages/:wiki_page_meta_id/notes GET /groups/:id/wiki_pages/:wiki_page_meta_id/notes?sort=asc&order_by=updated_at | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `sort` | string | no | Return wiki page notes sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return wiki page notes ordered by `created_at` or `updated_at` fields. Default is `created_at` | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/wiki_pages/35/notes" ### Retrieve a wiki page note Retrieves a specified note for a wiki page. GET /groups/:id/wiki_pages/:wiki_page_meta_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `note_id` | integer | yes | The ID of a note | { "author": { "id": 1, "username": "pipin", "email": "admin@example.com", "name": "Pip", "state": "active", "created_at": "2013-09-30T13:46:01Z" }, "body": "foobar", "commands_changes": {}, "confidential": false, "created_at": "2025-03-11T11:36:32.222Z", "id": 1218, "imported": false, "imported_from": "none", "internal": false, "noteable_id": 35, "noteable_iid": null, "noteable_type": "WikiPage::Meta", "project_id": null, "resolvable": false, "system": false, "type": null, "updated_at": "2025-03-11T11:36:32.222Z" } curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/wiki_pages/35/notes/1218" ### Create a wiki page note Creates a note for a specified wiki page. Wiki page notes are comments users can post to a wiki page. POST /groups/:id/wiki_pages/:wiki_page_meta_id/notes Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | curl --request POST --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/wiki_pages/35/notes?body=note" ### Update a wiki page note Updates a specified note on a wiki page. PUT /groups/:id/wiki_pages/:wiki_page_meta_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `note_id` | integer | yes | The ID of a note | | `body` | string | yes | The content of a note. Limited to 1,000,000 characters. | curl --request PUT --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/wiki_pages/35/notes/1218?body=note" ### Delete a wiki page note Deletes a note from a wiki page. DELETE /groups/:id/wiki_pages/:wiki_page_meta_id/notes/:note_id Parameters: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group | | `wiki_page_meta_id` | integer | yes | The ID of a wiki page meta | | `note_id` | integer | yes | The ID of a note | curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/groups/5/wiki_pages/35/notes/1218" --- # Merge requests API | GitLab Docs * * * Merge requests API ================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * `reference` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354) in GitLab 12.7. * `merged_by` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/350534) in GitLab 14.7. * `merge_status` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/3169#note_1162532204) in favor of `detailed_merge_status` in GitLab 15.6. * `with_merge_status_recheck` [changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115948) in GitLab 15.11 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `restrict_merge_status_recheck` to be ignored for requests from users with insufficient permissions. Disabled by default. * `approvals_before_merge` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119503) in GitLab 16.0. * `prepared_at` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122001) in GitLab 16.1. * `merge_after` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165092) in GitLab 17.5. * `security_policy_violations` [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/473704) in GitLab 18.4. Feature flag `policy_mergability_check` removed. Use this API to manage [merge requests](https://docs.gitlab.com/user/project/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](https://docs.gitlab.com/api/rest/deprecations/) in API v5 in favor of the [merge request approvals API](https://docs.gitlab.com/api/merge_request_approvals/) . 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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `approved_by_ids` | integer array | No | Returns the 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. Premium and Ultimate only. | | `approver_ids` | integer array | No | Returns merge requests which have specified all the users with the given `id` as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. Premium and Ultimate only. | | `assignee_id` | integer | No | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. | | `author_id` | integer | No | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. | | `author_username` | string | No | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. | | `created_after` | datetime | No | Returns merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | No | Returns merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `deployed_after` | datetime | No | Returns merge requests deployed after the given date/time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `deployed_before` | datetime | No | Returns merge requests deployed before the given date/time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `environment` | string | No | Returns merge requests deployed to the given environment. | | `in` | string | No | Change the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description`. | | `labels` | string | No | Returns 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_id` | integer | No | Returns the merge requests merged by the user with the given user `id`. Mutually exclusive with `merge_user_username`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140002)
in GitLab 17.0. | | `merge_user_username` | string | No | Returns the merge requests merged by the user with the given `username`. Mutually exclusive with `merge_user_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140002)
in GitLab 17.0. | | `milestone` | string | No | Returns merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. | | `my_reaction_emoji` | string | No | Returns 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_archived` | boolean | No | If `true`, returns merge requests from non-archived projects only. Default is `false`. | | `not` | Hash | No | Returns 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_by` | string | No | Returns requests ordered by `created_at`, `title`, `merged_at` ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147052)
in GitLab 17.2), or `updated_at` fields. Default is `created_at`. | | `render_html` | boolean | No | If `true`, the response includes rendered HTML fields `title_html` and `description_html`. | | `reviewer_id` | integer | No | Returns merge requests which have the user as a [reviewer](https://docs.gitlab.com/user/project/merge_requests/reviews/)
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_username` | string | No | Returns merge requests which have the user as a [reviewer](https://docs.gitlab.com/user/project/merge_requests/reviews/)
with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. | | `scope` | string | No | Returns merge requests for the given scope: `created_by_me`, `assigned_to_me`, `reviews_for_me`, or `all`. Defaults to `created_by_me`. `reviews_for_me` returns merge requests where the current user is assigned as a reviewer. | | `search` | string | No | Search merge requests against their `title` and `description`. | | `sort` | string | No | Returns requests sorted in `asc` or `desc` order. Default is `desc`. | | `source_branch` | string | No | Returns merge requests with the given source branch. | | `state` | string | No | Returns all merge requests or just those that are `opened`, `closed`, `locked`, or `merged`. | | `target_branch` | string | No | Returns merge requests with the given target branch. | | `updated_after` | datetime | No | Returns merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `updated_before` | datetime | No | Returns merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `view` | string | No | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. | | `with_labels_details` | boolean | No | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. | | `with_merge_status_recheck` | boolean | No | If `true`, this projection requests (but does not guarantee) an asynchronous recalculation of the `merge_status` field. Enable the `restrict_merge_status_recheck` [feature flag](https://docs.gitlab.com/administration/feature_flags/)
to ignore this attribute when requested by users without the Developer, Maintainer, or Owner role. | | `wip` | string | No | Filter merge requests against their `wip` status. Use `yes` to return only draft merge requests, `no` to return non-draft merge requests. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . If `view` is set to `simple`, returns a subset of fields. Otherwise, response attributes include: | Attribute | Type | Description | | --- | --- | --- | | `allow_collaboration` | boolean | If `true`, this fork allows collaboration from members who can merge to the target branch. Used only for merge requests from forks. | | `allow_maintainer_to_push` | boolean | Deprecated. Use `allow_collaboration` instead. | | `approvals_before_merge` | integer | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097)
in GitLab 16.0. To configure approval rules, see the [merge request approvals API](https://docs.gitlab.com/api/merge_request_approvals/)
instead. GitLab Premium and Ultimate only. | | `assignee[]` | object | Deprecated. Use `assignees` instead. | | `assignees[]` | array | Users assigned to the merge request. | | `assignees.avatar_url` | string | Full URL to the assignee’s avatar image. | | `assignees.id` | integer | The unique ID of the assignee. | | `assignees.locked` | boolean | If `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.name` | string | Display name of the assignee. Might be redacted, based on current user’s permissions. | | `assignees.public_email` | string | The public email address of the assignee. | | `assignees.state` | string | Current state of the assignee’s user account. Possible values: `active`, `blocked`, or `deactivated`. | | `assignees.username` | string | Username of the merge request assignee. | | `assignees.web_url` | string | Full URL to the assignee’s profile page. | | `author[]` | object | Object with information about the user who created the merge request. | | `author.avatar_url` | string | Full URL to the author’s avatar image. | | `author.id` | integer | The unique ID of the user who created the merge request. | | `author.locked` | boolean | If `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.name` | string | Display name of the author. Might be redacted, based on current user’s permissions. | | `author.public_email` | string | The public email address of the author. | | `author.state` | string | Current state of the user account. Possible values: `active`, `blocked`, or `deactivated`. | | `author.username` | string | Username of the merge request author. | | `author.web_url` | string | Full URL to the author’s profile page. | | `blocking_discussions_resolved` | boolean | If `true`, all discussion threads in the merge request must be resolved before merging. | | `closed_at` | dateTime | Timestamp of when the merge request was closed. | | `closed_by[]` | object | Object with information about the user who closed the merge request. If `null`, the merge request is open. | | `closed_by.avatar_url` | string | Full URL to the closing user’s avatar image. | | `closed_by.id` | integer | The unique ID of the user who closed the merge request. | | `closed_by.locked` | boolean | If `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.name` | string | Display name of the closing user. Might be redacted, based on current user’s permissions. | | `closed_by.public_email` | string | The public email address of the closing user. | | `closed_by.state` | string | Current state of the closing user’s account. Possible values: `active`, `blocked`, or `deactivated`. | | `closed_by.username` | string | Username of the user who closed the merge request. | | `closed_by.web_url` | string | Full URL to the closing user’s profile page. | | `created_at` | dateTime | Timestamp of when the merge request was created. | | `description` | string | Description of the merge request. Contains Markdown rendered as HTML for caching. | | `description_html` | string | If `render_html` is set, the rendered HTML version of the description. | | `detailed_merge_status` | string | Detailed merge status information. See [merge status](https://docs.gitlab.com/api/merge_requests/#merge-status)
for a list of potential values. | | `discussion_locked` | boolean | If `true`, discussions are locked. Only project members can add, edit or resolve comments in locked discussions. | | `downvotes` | integer | Number of downvotes for the merge request. | | `draft` | boolean | If `true`, the merge request is marked in a `draft` state. | | `force_remove_source_branch` | boolean | If `true`, the project settings force the deletion of the source branch after merge. | | `has_conflicts` | boolean | If `true`, the merge request has conflicts and cannot merge. Dependent on the `merge_status` property. Returns `false` unless `merge_status` is `cannot_be_merged`. | | `id` | integer | The unique ID of the merge request. | | `iid` | integer | The internal ID of the merge request in the project. | | `imported` | boolean | If `true`, the merge request was imported. | | `imported_from` | string | Source of import, such as `Bitbucket`. | | `labels[]` | array | Array of label assigned to the merge request. If `with_labels_details` is `true`, returns an array for each label. | | `labels.archived` | boolean | If `with_labels_details` is `true`, the label is archived. | | `labels.color` | string | If `with_labels_details` is `true`, the background color of the label. | | `labels.description` | string | If `with_labels_details` is `true`, the description text of the label. If `null`, the label has no description. | | `labels.description_html`. | string | If `with_labels_details` is `true`, the HTML-rendered description of the label. If `null`, the label has no description. | | `labels.id` | integer | If `with_labels_details` is `true`, the unique ID of the label. | | `labels.name` | string | If `with_labels_details` is `true`, the name of the label. | | `labels.text_color` | string | If `with_labels_details` is `true`, the text color for the label. | | `merge_after` | dateTime | If set, timestamp after which the merge request can be merged. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/510992)
in GitLab 17.8. | | `merge_commit_sha` | string | If set, the SHA of the merge request commit. Returns `null` until merged. | | `merge_status` | string | Status 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](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes)
. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/3169#note_1162532204)
in GitLab 15.6. | | `merge_user` | object | Object with information about the user who merged the merge request, set it to auto-merge, or `null`. | | `merge_when_pipeline_succeeds` | boolean | If `true`, the merge request is set to auto-merge. | | `merged_at` | dateTime | Timestamp of when the merge request merged. | | `merged_by[]` | object | Deprecated. Use `merge_user` instead. | | `milestone[]` | object | Object with information about the milestone assigned to the merge request. | | `milestone.created_at` | dateTime | Timestamp when the milestone was created. | | `milestone.description` | string | Description text of the milestone. If `null`, the milestone has no description. | | `milestone.due_date` | date | Due date for the milestone. If `null`, the milestone has no due date. | | `milestone.expired` | boolean | If `true`, the milestone has expired. | | `milestone.group_id` | integer | ID of the group the milestone belongs to. Included only if the milestone is a group milestone. | | `milestone.id` | integer | Unique ID of the milestone. | | `milestone.iid` | integer | Internal ID of the milestone in the project or group. | | `milestone.project_id` | integer | ID of the project the milestone belongs to. Included only if the milestone is a project milestone. | | `milestone.start_date` | date | Start date for the milestone. If `null`, the milestone has no start date | | `milestone.state` | string | Current state of the milestone, such as `active` or `closed`. | | `milestone.title` | string | Name of the milestone. | | `milestone.updated_at` | dateTime | Timestamp when the milestone was last updated. | | `milestone.web_url` | string | Full web URL to view the milestone. | | `prepared_at` | dateTime | Timestamp of when the merge request was prepared. This field populates one time, only after all the [preparation steps](https://docs.gitlab.com/api/merge_requests/#preparation-steps)
complete, and is not updated if more changes are added. | | `project_id` | integer | The ID of the project containing the merge request. | | `reference` | string | Deprecated. Use `references` instead. | | `references[]` | object | Object with all internal references of the merge request. | | `references.full` | string | Complete 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.relative` | string | Reference 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.short` | string | Shortest possible reference to a merge request, like `!123`. When fetched from the merge request’s project, identical to `references.relative`. | | `reviewers[]` | array | Reviewers of the merge request. | | `reviewers.avatar_url` | string | Full URL to the reviewer’s avatar image. | | `reviewers.id` | integer | The unique ID of the reviewer. | | `reviewers.locked` | boolean | If `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.name` | string | Display name of the reviewer. Might be redacted, based on current user’s permissions. | | `reviewers.public_email` | string | The public email address of the reviewer. | | `reviewers.state` | string | Current state of the reviewer’s user account. Possible values: `active`, `blocked`, or `deactivated`. | | `reviewers.username` | string | Username of the merge request reviewer. | | `reviewers.web_url` | string | Full URL to the reviewer’s profile page. | | `sha` | string | SHA of the head commit in the source branch. | | `should_remove_source_branch` | boolean | If `true`, the source branch is removed after merge. | | `source_branch` | string | Name of the source branch. | | `source_project_id` | integer | ID of the source project. | | `squash` | boolean | If `true`, squash commits when merging. | | `squash_commit_sha` | string | If set, the SHA of the squash commit. Empty until merged. | | `squash_on_merge` | boolean | If `true`, commits are squashed on merge. | | `state` | string | The current state of the merge request. Possible values: `opened`, `closed`, `merged`, or `locked`. | | `target_branch` | string | Name of the target branch. | | `target_project_id` | integer | ID of the target project. | | `task_completion_status[]` | object | Object with information on the task list completion status. | | `task_completion_status.completed_count` | integer | Number 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.count` | integer | Total 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[]` | object | Object with information on time tracking for this merge request. | | `time_stats.human_time_estimate` | string | Human-readable format of `time_stats.time_estimate`, like `3h 30m`. | | `time_stats.human_total_time_spent` | string | Human-readable format of `time_stats.total_time_spent`, like `3h 30m`. | | `time_stats.time_estimate` | integer | Estimated time to complete the merge request, in seconds. | | `time_stats.total_time_spent` | integer | Total time spent working on the merge request, in seconds. | | `title` | string | The merge request title. | | `title_html` | string | If `render_html` is `true`, the rendered HTML version of the title. | | `updated_at` | dateTime | Timestamp of when the merge request was last updated. | | `upvotes` | integer | Number of upvotes for the merge request. | | `user_notes_count` | integer | Number of user comments. | | `web_url` | string | Web URL to view the merge request. | | `work_in_progress` | boolean | Deprecated. 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: [\ {\ "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": {\ "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](https://docs.gitlab.com/api/merge_requests/#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: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `approved_by_ids` | integer array | No | Returns 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. Premium and Ultimate only. | | `approver_ids` | integer array | No | Returns merge requests which have specified all the users with the given `id` as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. Premium and Ultimate only. | | `assignee_id` | integer | No | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. | | `author_id` | integer | No | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. | | `author_username` | string | No | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. | | `created_after` | datetime | No | Returns merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | No | Returns merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `environment` | string | No | Returns merge requests deployed to the given environment. | | `iids[]` | integer array | No | Returns the request having the given `iid`. | | `labels` | string | No | Returns 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_id` | integer | No | Returns merge requests merged by the user with the given user `id`. Mutually exclusive with `merge_user_username`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140002)
in GitLab 17.0. | | `merge_user_username` | string | No | Returns merge requests merged by the user with the given `username`. Mutually exclusive with `merge_user_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140002)
in GitLab 17.0. | | `milestone` | string | No | Returns merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. | | `my_reaction_emoji` | string | No | Returns 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. | | `not` | Hash | No | Returns 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_by` | string | No | Returns requests ordered by `created_at`, `title` or `updated_at` fields. Default is `created_at`. | | `reviewer_id` | integer | No | Returns merge requests which have the user as a [reviewer](https://docs.gitlab.com/user/project/merge_requests/reviews/)
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_username` | string | No | Returns merge requests which have the user as a [reviewer](https://docs.gitlab.com/user/project/merge_requests/reviews/)
with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. | | `scope` | string | No | Returns 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. | | `search` | string | No | Search merge requests against their `title` and `description`. | | `sort` | string | No | Returns requests sorted in `asc` or `desc` order. Default is `desc`. | | `source_branch` | string | No | Returns merge requests with the given source branch. | | `state` | string | No | Returns all merge requests (`all`) or just those that are `opened`, `closed`, `locked`, or `merged`. | | `target_branch` | string | No | Returns merge requests with the given target branch. | | `updated_after` | datetime | No | Returns merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `updated_before` | datetime | No | Returns merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `view` | string | No | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. | | `wip` | string | No | Filter merge requests against their `wip` status. `yes` to return only draft merge requests, `no` to return non-draft merge requests. | | `with_labels_details` | boolean | No | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. | | `with_merge_status_recheck` | boolean | No | If `true`, this projection requests (but does not guarantee) an asynchronous recalculation of the `merge_status` field. Enable the `restrict_merge_status_recheck` [feature flag](https://docs.gitlab.com/administration/feature_flags/)
to ignore this attribute when requested by users without the Developer, Maintainer, or Owner role. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `[].id` | integer | ID of the merge request. | | `[].iid` | integer | Internal ID of the merge request. | | `[].approvals_before_merge` | integer | Number of approvals required before this merge request can merge. To configure approval rules, see [Merge request approvals API](https://docs.gitlab.com/api/merge_request_approvals/)
. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097)
in GitLab 16.0. Premium and Ultimate only. | | `[].assignee` | object | First assignee of the merge request. | | `[].assignees` | array | Assignees of the merge request. | | `[].author` | object | User who created this merge request. | | `[].blocking_discussions_resolved` | boolean | Indicates if all discussions are resolved only if all are required before merge request can be merged. | | `[].closed_at` | datetime | Timestamp of when the merge request was closed. | | `[].closed_by` | object | User who closed this merge request. | | `[].created_at` | datetime | Timestamp of when the merge request was created. | | `[].description` | string | Description of the merge request. | | `[].detailed_merge_status` | string | Detailed merge status of the merge request. See [merge status](https://docs.gitlab.com/api/merge_requests/#merge-status)
for a list of potential values. | | `[].discussion_locked` | boolean | Indicates if comments on the merge request are locked to members only. | | `[].downvotes` | integer | Number of downvotes for the merge request. | | `[].draft` | boolean | Indicates if the merge request is a draft. | | `[].force_remove_source_branch` | boolean | Indicates if the project settings lead to source branch deletion after merge. | | `[].has_conflicts` | boolean | Indicates if merge request has conflicts and cannot merge. Dependent on the `merge_status` property. Returns `false` unless `merge_status` is `cannot_be_merged`. | | `[].labels` | array | Labels of the merge request. | | `[].merge_commit_sha` | string | SHA of the merge request commit. Returns `null` until merged. | | `[].merge_status` | string | Status of the merge request. Can be `unchecked`, `checking`, `can_be_merged`, `cannot_be_merged`, or `cannot_be_merged_recheck`. Affects the `has_conflicts` property. For important notes on response data, see [Single merge request response notes](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes)
. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/3169#note_1162532204)
in GitLab 15.6. Use `detailed_merge_status` instead. | | `[].merge_user` | object | User who merged this merge request, the user who set it to auto-merge, or `null`. | | `[].merge_when_pipeline_succeeds` | boolean | Indicates if the merge request is set to auto-merge. | | `[].merged_at` | datetime | Timestamp of when the merge request was merged. | | `[].merged_by` | object | User who merged this merge request or set it to auto-merge. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/350534)
in GitLab 14.7, and scheduled for removal in [API version 5](https://gitlab.com/groups/gitlab-org/-/epics/8115)
. Use `merge_user` instead. | | `[].milestone` | object | Milestone of the merge request. | | `[].prepared_at` | datetime | Timestamp of when the merge request was prepared. This field is populated one time, only after all the [preparation steps](https://docs.gitlab.com/api/merge_requests/#preparation-steps)
are completed, and is not updated if more changes are added. | | `[].project_id` | integer | ID of the project where the merge request resides. Always equal to `target_project_id`. | | `[].reference` | string | Internal reference of the merge request. Returned in shortened format by default. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354)
in GitLab 12.7, and scheduled for removal in [API version 5](https://gitlab.com/groups/gitlab-org/-/epics/8115)
. Use `references` instead. | | `[].references` | object | Internal references of the merge request. Includes `short`, `relative`, and `full` references. `references.relative` is relative to the merge request’s group or project. When fetched from the merge request’s project, `relative` and `short` formats are identical. When requested across groups or projects, `relative` and `full` formats are identical. | | `[].reviewers` | array | Reviewers of the merge request. | | `[].sha` | string | Diff head SHA of the merge request. | | `[].should_remove_source_branch` | boolean | Indicates if the source branch of the merge request should be deleted after merge. | | `[].source_branch` | string | Source branch of the merge request. | | `[].source_project_id` | integer | ID of the merge request source project. Equal to `target_project_id`, unless the merge request originates from a fork. | | `[].squash` | boolean | If `true`, squash all commits into a single commit on merge. [Project settings](https://docs.gitlab.com/user/project/merge_requests/squash_and_merge/#configure-squash-options-for-a-project)
might override this value. Use `squash_on_merge` instead to take project squash options into account. | | `[].squash_commit_sha` | string | SHA of the squash commit. Empty until merged. | | `[].squash_on_merge` | boolean | Indicates whether to squash the merge request when merging. | | `[].state` | string | State of the merge request. Can be `opened`, `closed`, `merged`, `locked`. | | `[].target_branch` | string | Target branch of the merge request. | | `[].target_project_id` | integer | ID of the merge request target project. | | `[].task_completion_status` | object | Completion status of tasks. Includes `count` and `completed_count`. | | `[].time_stats` | object | Time tracking stats of the merge request. Includes `time_estimate`, `total_time_spent`, `human_time_estimate`, and `human_total_time_spent`. | | `[].title` | string | Title of the merge request. | | `[].updated_at` | datetime | Timestamp of when the merge request was updated. | | `[].upvotes` | integer | Number of upvotes for the merge request. | | `[].user_notes_count` | integer | User notes count of the merge request. | | `[].web_url` | string | Web URL of the merge request. | | `[].work_in_progress` | boolean | Deprecated: Use `draft` instead. Indicates if the merge request is a draft. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests" Example response: [\ {\ "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",\ "locked": false,\ "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",\ "locked": false,\ "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": {\ "id": 1,\ "name": "Administrator",\ "username": "admin",\ "state": "active",\ "locked": false,\ "avatar_url": null,\ "web_url" : "https://gitlab.example.com/admin"\ },\ "assignee": {\ "id": 1,\ "name": "Administrator",\ "username": "admin",\ "state": "active",\ "locked": false,\ "avatar_url": null,\ "web_url" : "https://gitlab.example.com/admin"\ },\ "assignees": [{\ "name": "Miss Monserrate Beier",\ "username": "axel.block",\ "id": 12,\ "state": "active",\ "locked": false,\ "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,\ "web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",\ "reference": "!1",\ "references": {\ "short": "!1",\ "relative": "!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,\ "squash_on_merge": false,\ "task_completion_status":{\ "count":0,\ "completed_count":0\ },\ "has_conflicts": false,\ "blocking_discussions_resolved": true,\ "approvals_before_merge": 2\ }\ ] For important notes on response data, see [merge requests list response notes](https://docs.gitlab.com/api/merge_requests/#merge-requests-list-response-notes) . List group merge requests ------------------------- List all merge requests for a group and its subgroups. GET /groups/:id/merge_requests GET /groups/:id/merge_requests?state=opened GET /groups/:id/merge_requests?state=all GET /groups/:id/merge_requests?milestone=release GET /groups/:id/merge_requests?labels=bug,reproduced GET /groups/:id/merge_requests?my_reaction_emoji=star Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the group. | | `approved` | string | No | If `yes`, returns only approved merge requests. `no` returns only non-approved merge requests. | | `approved_by_ids` | integer array | No | Returns the 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. Premium and Ultimate only. | | `approved_by_usernames` | string array | No | Returns the 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. Premium and Ultimate only. | | `approver_ids` | integer array | No | Returns merge requests which have specified all the users with the given `id` as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. Premium and Ultimate only. | | `assignee_id` | integer or string | No | Returns 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[]` | array | No | Returns merge requests assigned to the given usernames. Mutually exclusive with `assignee_id`. | | `author_id` | integer | No | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. | | `author_username` | string | No | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. | | `created_after` | datetime | No | Returns merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | No | Returns merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `deployed_after` | datetime | No | Returns merge requests deployed after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `deployed_before` | datetime | No | Returns merge requests deployed before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `environment` | string | No | Returns merge requests deployed to the given environment. | | `in` | string | No | If set, modifies the scope of the search attribute. Can be `title`, `description`, or a string joining them with a comma, like `"title,description"` | | `labels` | string | No | Returns 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_id` | integer | No | Returns merge requests merged by the user with the given user `id`. Mutually exclusive with `merge_user_username`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140002)
in GitLab 17.0. | | `merge_user_username` | string | No | Returns merge requests merged by the user with the given `username`. Mutually exclusive with `merge_user_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140002)
in GitLab 17.0. | | `milestone` | string | No | Returns merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. | | `my_reaction_emoji` | string | No | Returns 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_archived` | boolean | No | If `true`, returns merge requests from non-archived projects only. Default is `true`. | | `not` | hash | No | Returns merge requests that do not match the parameters supplied. Can be: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `reviewer_id`, `reviewer_username`, `my_reaction_emoji`. | | `order_by` | string | No | Returns merge requests ordered by `created_at`, `label_priority`, `merged_at`, `milestone_due`, `popularity`, `priority`, `title`, or `updated_at` fields. Default is `created_at`. | | `page` | integer | No | Returns the current page number. Defaults to `1`. | | `per_page` | integer | No | Number of items per page to return. Defaults to `20`. | | `reviewer_id` | integer or string | No | Returns merge requests which have the user as a [reviewer](https://docs.gitlab.com/user/project/merge_requests/reviews/)
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_username` | string | No | Returns merge requests which have the user as a [reviewer](https://docs.gitlab.com/user/project/merge_requests/reviews/)
with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. | | `scope` | string | No | Returns merge requests for the given scope: `created_by_me`, `assigned_to_me`, `reviews_for_me`, or `all`. Defaults to `created_by_me`. `reviews_for_me` returns merge requests where the current user is assigned as a reviewer. | | `search` | string | No | Search merge requests against their `title` and `description`. | | `source_branch` | string | No | Returns merge requests with the given source branch. | | `source_project_id` | integer | No | Returns merge requests with the given source project ID. | | `sort` | string | No | Returns merge requests sorted in `asc` or `desc` order. Default is `desc`. | | `state` | string | No | Returns all merge requests or just those that are `opened`, `closed`, `locked`, or `merged`. Defaults to `all`. | | `target_branch` | string | No | Returns merge requests with the given target branch. | | `updated_after` | datetime | No | Returns merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `updated_before` | datetime | No | Returns merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `view` | string | No | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. | | `with_labels_details` | boolean | No | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. | | `with_merge_status_recheck` | boolean | No | If `true`, requests (but does not guarantee) an asynchronous recalculation of the `merge_status` field. Enable the `restrict_merge_status_recheck` [feature flag](https://docs.gitlab.com/administration/feature_flags/)
to ignore this attribute when requested by users without the Developer, Maintainer, or Owner role. | | `wip` | string | No | Filter merge requests against their `wip` status. Use `yes` to return only draft merge requests, `no` to return non-draft merge requests. | In the response, `group_id` represents the ID of the group containing the project where the merge request resides. If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . If `view` is set to `simple`, returns a subset of fields. Otherwise, response attributes include: | Attribute | Type | Description | | --- | --- | --- | | `allow_collaboration` | boolean | If `true`, this fork allows collaboration from members who can merge to the target branch. Used only for merge requests from forks. | | `allow_maintainer_to_push` | boolean | Deprecated. Use `allow_collaboration` instead. | | `approvals_before_merge` | integer | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097)
in GitLab 16.0. To configure approval rules, see the [merge request approvals API](https://docs.gitlab.com/api/merge_request_approvals/)
instead. GitLab Premium and Ultimate only. | | `assignee[]` | object | Deprecated. Use `assignees` instead. | | `assignees[]` | array | Users assigned to the merge request. | | `assignees.avatar_url` | string | Full URL to the assignee’s avatar image. | | `assignees.id` | integer | The unique ID of the assignee. | | `assignees.locked` | boolean | If `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.name` | string | Display name of the assignee. Might be redacted, based on current user’s permissions. | | `assignees.public_email` | string | The public email address of the assignee. | | `assignees.state` | string | Current state of the assignee’s user account. Possible values: `active`, `blocked`, or `deactivated`. | | `assignees.username` | string | Username of the merge request assignee. | | `assignees.web_url` | string | Full URL to the assignee’s profile page. | | `author[]` | object | Object with information about the user who created the merge request. | | `author.avatar_url` | string | Full URL to the author’s avatar image. | | `author.id` | integer | The unique ID of the user who created the merge request. | | `author.locked` | boolean | If `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.name` | string | Display name of the author. Might be redacted, based on current user’s permissions. | | `author.public_email` | string | The public email address of the author. | | `author.state` | string | Current state of the user account. Possible values: `active`, `blocked`, or `deactivated`. | | `author.username` | string | Username of the merge request author. | | `author.web_url` | string | Full URL to the author’s profile page. | | `blocking_discussions_resolved` | boolean | If `true`, all discussion threads in the merge request must be resolved before merging. | | `closed_at` | dateTime | Timestamp of when the merge request was closed. | | `closed_by[]` | object | Object with information about the user who closed the merge request. If `null`, the merge request is open. | | `closed_by.avatar_url` | string | Full URL to the closing user’s avatar image. | | `closed_by.id` | integer | The unique ID of the user who closed the merge request. | | `closed_by.locked` | boolean | If `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.name` | string | Display name of the closing user. Might be redacted, based on current user’s permissions. | | `closed_by.public_email` | string | The public email address of the closing user. | | `closed_by.state` | string | Current state of the closing user’s account. Possible values: `active`, `blocked`, or `deactivated`. | | `closed_by.username` | string | Username of the user who closed the merge request. | | `closed_by.web_url` | string | Full URL to the closing user’s profile page. | | `created_at` | dateTime | Timestamp of when the merge request was created. | | `description` | string | Description of the merge request. Contains Markdown rendered as HTML for caching. | | `detailed_merge_status` | string | Detailed merge status information. See [merge status](https://docs.gitlab.com/api/merge_requests/#merge-status)
for a list of potential values. | | `discussion_locked` | boolean | If `true`, discussions are locked. Only project members can add, edit or resolve comments in locked discussions. | | `downvotes` | integer | Number of downvotes for the merge request. | | `draft` | boolean | If `true`, the merge request is marked in a `draft` state. | | `force_remove_source_branch` | boolean | If `true`, the project settings force the deletion of the source branch after merge. | | `has_conflicts` | boolean | If `true`, the merge request has conflicts and cannot merge. Dependent on the `merge_status` property. Returns `false` unless `merge_status` is `cannot_be_merged`. | | `id` | integer | The unique ID of the merge request. | | `iid` | integer | The internal ID of the merge request in the project. | | `imported` | boolean | If `true`, the merge request was imported. | | `imported_from` | string | Source of import, such as `Bitbucket`. | | `labels[]` | array | Array of label assigned to the merge request. If `with_labels_details` is `true`, returns an array for each label. | | `labels.archived` | boolean | If `with_labels_details` is `true`, the label is archived. | | `labels.color` | string | If `with_labels_details` is `true`, the background color of the label. | | `labels.description` | string | If `with_labels_details` is `true`, the description text of the label. If `null`, the label has no description. | | `labels.description_html` | string | If `with_labels_details` is `true`, the HTML-rendered description of the label. If `null`, the label has no description. | | `labels.id` | integer | If `with_labels_details` is `true`, the unique ID of the label. | | `labels.name` | string | If `with_labels_details` is `true`, the name of the label. | | `labels.text_color` | string | If `with_labels_details` is `true`, the text color for the label. | | `merge_after` | dateTime | If set, timestamp after which the merge request can be merged. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/510992)
in GitLab 17.8. | | `merge_commit_sha` | string | If set, the SHA of the merge request commit. Returns `null` until merged. | | `merge_status` | string | Status 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](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes)
. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/3169#note_1162532204)
in GitLab 15.6. | | `merge_user` | object | Object with information about the user who merged the merge request, set it to auto-merge, or `null`. | | `merge_when_pipeline_succeeds` | boolean | If `true`, the merge request is set to auto-merge. | | `merged_at` | dateTime | Timestamp of when the merge request merged. | | `merged_by[]` | object | Deprecated. Use `merge_user` instead. | | `milestone[]` | object | Object with information about the milestone assigned to the merge request. | | `milestone.created_at` | dateTime | Timestamp when the milestone was created. | | `milestone.description` | string | Description text of the milestone. If `null`, the milestone has no description. | | `milestone.due_date` | date | Due date for the milestone. If `null`, the milestone has no due date. | | `milestone.expired` | boolean | If `true`, the milestone has expired. | | `milestone.group_id` | integer | ID of the group the milestone belongs to. Included only if the milestone is a group milestone. | | `milestone.id` | integer | Unique ID of the milestone. | | `milestone.iid` | integer | Internal ID of the milestone in the project or group. | | `milestone.project_id` | integer | ID of the project the milestone belongs to. Included only if the milestone is a project milestone. | | `milestone.start_date` | date | Start date for the milestone. If `null`, the milestone has no start date | | `milestone.state` | string | Current state of the milestone, such as `active` or `closed`. | | `milestone.title` | string | Name of the milestone. | | `milestone.updated_at` | dateTime | Timestamp when the milestone was last updated. | | `milestone.web_url` | string | Full web URL to view the milestone. | | `prepared_at` | dateTime | Timestamp of when the merge request was prepared. This field populates one time, only after all the [preparation steps](https://docs.gitlab.com/api/merge_requests/#preparation-steps)
complete, and is not updated if more changes are added. | | `project_id` | integer | The ID of the project containing the merge request. | | `reference` | string | Deprecated. Use `references` instead. | | `references[]` | object | Object with all internal references of the merge request. | | `references.full` | string | Complete 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.relative` | string | Reference 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.short` | string | Shortest possible reference to a merge request, like `!123`. When fetched from the merge request’s project, identical to `references.relative`. | | `reviewers[]` | array | Reviewers of the merge request. | | `reviewers.avatar_url` | string | Full URL to the reviewer’s avatar image. | | `reviewers.id` | integer | The unique ID of the reviewer. | | `reviewers.locked` | boolean | If `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.name` | string | Display name of the reviewer. Might be redacted, based on current user’s permissions. | | `reviewers.public_email` | string | The public email address of the reviewer. | | `reviewers.state` | string | Current state of the reviewer’s user account. Possible values: `active`, `blocked`, or `deactivated`. | | `reviewers.username` | string | Username of the merge request reviewer. | | `reviewers.web_url` | string | Full URL to the reviewer’s profile page. | | `sha` | string | SHA of the head commit in the source branch. | | `should_remove_source_branch` | boolean | If `true`, the source branch is removed after merge. | | `source_branch` | string | Name of the source branch. | | `source_project_id` | integer | ID of the source project. | | `squash` | boolean | If `true`, squash commits when merging. | | `squash_commit_sha` | string | If set, the SHA of the squash commit. Empty until merged. | | `squash_on_merge` | boolean | If `true`, commits are squashed on merge. | | `state` | string | The current state of the merge request. Possible values: `opened`, `closed`, `merged`, or `locked`. | | `target_branch` | string | Name of the target branch. | | `target_project_id` | integer | ID of the target project. | | `task_completion_status[]` | object | Object with information on the task list completion status. | | `task_completion_status.completed_count` | integer | Number 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.count` | integer | Total 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[]` | object | Object with information on time tracking for this merge request. | | `time_stats.human_time_estimate` | string | Human-readable format of `time_stats.time_estimate`, like `3h 30m`. | | `time_stats.human_total_time_spent` | string | Human-readable format of `time_stats.total_time_spent`, like `3h 30m`. | | `time_stats.time_estimate` | integer | Estimated time to complete the merge request, in seconds. | | `time_stats.total_time_spent` | integer | Total time spent working on the merge request, in seconds. | | `title` | string | The merge request title. | | `updated_at` | dateTime | Timestamp of when the merge request was last updated. | | `upvotes` | integer | Number of upvotes for the merge request. | | `user_notes_count` | integer | Number of user comments. | | `web_url` | string | Web URL to view the merge request. | | `work_in_progress` | boolean | Deprecated. Use `draft` instead. | Other possible responses: * `401 Unauthorized` if the access token is invalid. * `404 Not Found` if the project or merge request is not found. * `422 Unprocessable Entity` if validation failed. * `429 Too Many Requests` if using the `search` parameter, and the request has been rate-limited. Example response: [\ {\ "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": {\ "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-10-22",\ "start_date": "2018-09-08",\ "web_url": "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,\ "web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",\ "references": {\ "short": "!1",\ "relative": "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\ },\ "has_conflicts": false,\ "blocking_discussions_resolved": true\ }\ ] For important notes on response data, see [merge requests list response notes](https://docs.gitlab.com/api/merge_requests/#merge-requests-list-response-notes) . Retrieve a merge request ------------------------ Retrieve information about a merge request. GET /projects/:id/merge_requests/:merge_request_iid Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `include_diverged_commits_count` | boolean | No | If `true`, response includes the commits behind the target branch. | | `include_rebase_in_progress` | boolean | No | If `true`, response includes whether a rebase operation is in progress. | | `render_html` | boolean | No | If `true`, response includes rendered HTML for title and description. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) . Other possible responses: * `401 Unauthorized` if the access token is invalid. * `403 Forbidden` if access is denied. * `404 Not Found` if the project or merge request is not found. * `408 Request Timeout` if the database query times out. * `409 Conflict` if a resource lock conflict exists. * `422 Unprocessable Entity` if validation failed. * `429 Too Many Requests` if using the `search` parameter, and the request has been rate-limited. ### Response | Attribute | Type | Description | | --- | --- | --- | | `allow_collaboration` | boolean | If `true`, this fork allows collaboration from members who can merge to the target branch. Used only for merge requests from forks. | | `allow_maintainer_to_push` | boolean | Deprecated. Use `allow_collaboration` instead. | | `approvals_before_merge` | integer | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097)
in GitLab 16.0. To configure approval rules, see the [merge request approvals API](https://docs.gitlab.com/api/merge_request_approvals/)
instead. GitLab Premium and Ultimate only. | | `assignee[]` | object | Deprecated. Use `assignees` instead. | | `assignees[]` | array | Users assigned to the merge request. | | `assignees.avatar_url` | string | Full URL to the assignee’s avatar image. | | `assignees.id` | integer | The unique ID of the assignee. | | `assignees.locked` | boolean | If `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.name` | string | Display name of the assignee. Might be redacted, based on current user’s permissions. | | `assignees.public_email` | string | The public email address of the assignee. | | `assignees.state` | string | Current state of the assignee’s user account. Possible values: `active`, `blocked`, or `deactivated`. | | `assignees.username` | string | Username of the merge request assignee. | | `assignees.web_url` | string | Full URL to the assignee’s profile page. | | `author[]` | object | Object with information about the user who created the merge request. | | `author.avatar_url` | string | Full URL to the author’s avatar image. | | `author.id` | integer | The unique ID of the user who created the merge request. | | `author.locked` | boolean | If `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.name` | string | Display name of the author. Might be redacted, based on current user’s permissions. | | `author.public_email` | string | The public email address of the author. | | `author.state` | string | Current state of the user account. Possible values: `active`, `blocked`, or `deactivated`. | | `author.username` | string | Username of the merge request author. | | `author.web_url` | string | Full URL to the author’s profile page. | | `blocking_discussions_resolved` | boolean | If `true`, all discussion threads in the merge request must be resolved before merging. | | `changes_count` | string | If set, the number of changes made on the merge request. Empty when the merge request is created. Populates asynchronously. A string, not an integer. When a merge request has too many changes to display and store, the value is capped at 1000 and returns the string `"1000+"`. See [empty API fields for new merge requests](https://docs.gitlab.com/api/merge_requests/#empty-api-fields-for-new-merge-requests)
. | | `closed_at` | dateTime | Timestamp of when the merge request was closed. | | `closed_by[]` | object | Object with information about the user who closed the merge request. If `null`, the merge request is open. | | `closed_by.avatar_url` | string | Full URL to the closing user’s avatar image. | | `closed_by.id` | integer | The unique ID of the user who closed the merge request. | | `closed_by.locked` | boolean | If `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.name` | string | Display name of the closing user. Might be redacted, based on current user’s permissions. | | `closed_by.public_email` | string | The public email address of the closing user. | | `closed_by.state` | string | Current state of the closing user’s account. Possible values: `active`, `blocked`, or `deactivated`. | | `closed_by.username` | string | Username of the user who closed the merge request. | | `closed_by.web_url` | string | Full URL to the closing user’s profile page. | | `created_at` | datetime | Timestamp of when the merge request was created. | | `description` | string | Description of the merge request. Contains Markdown rendered as HTML for caching. | | `detailed_merge_status` | string | Detailed merge status information. See [merge status](https://docs.gitlab.com/api/merge_requests/#merge-status)
for a list of potential values. | | `diff_refs[]` | object | Object with references of the base, head, and start SHAs for this merge request. Corresponds to the latest diff version of the merge request. Empty when the merge request is created, and populates asynchronously. See [empty API fields for new merge requests](https://docs.gitlab.com/api/merge_requests/#empty-api-fields-for-new-merge-requests)
. | | `diff_refs.base_sha` | string | SHA of the merge base commit where the source and target branches diverged. | | `diff_refs.start_sha` | string | SHA of the target branch commit. The starting point for the diff. Usually the same as `base_sha`. | | `diff_refs.head_sha` | string | SHA of the head commit in the source branch. The latest commit in the merge request. | | `discussion_locked` | boolean | If `true`, discussions are locked. Only project members can add, edit or resolve comments in locked discussions. | | `diverged_commits_count` | integer | If set, contains the number of commits the source branch is behind the target branch. | | `downvotes` | integer | Number of downvotes for the merge request. | | `draft` | boolean | If `true`, the merge request is marked in a `draft` state. | | `first_contribution` | boolean | If `true`, the author’s first contribution to this project. | | `first_deployed_to_production_at` | datetime | Timestamp of when the first deployment finished. | | `force_remove_source_branch` | boolean | If `true`, the project settings force the deletion of the source branch after merge. | | `has_conflicts` | boolean | If `true`, the merge request has conflicts and cannot merge. Dependent on the `merge_status` property. Returns `false` unless `merge_status` is `cannot_be_merged`. | | `head_pipeline[]` | object | Pipeline that runs on the HEAD commit of the merge request’s source branch. Use instead of `pipeline`, because it contains more complete information. Exposed only if the current user can view pipelines for this project. | | `head_pipeline.before_sha` | string | SHA of the commit before this pipeline. | | `head_pipeline.committed_at` | dateTime | Timestamp of when the commit was made. | | `head_pipeline.coverage` | number | Test coverage percentage, like `98.29`. | | `head_pipeline.created_at` | dateTime | Timestamp of when the pipeline was created. | | `head_pipeline.detailed_status[]` | object | Object containing fields with the detailed status of this pipeline. | | `head_pipeline.detailed_status.action[]` | object | If set, object containing available actions for this pipeline. | | `head_pipeline.detailed_status.action.button_title` | string | Button title for the action. | | `head_pipeline.detailed_status.action.confirmation_message` | string | Confirmation message for the action. | | `head_pipeline.detailed_status.action.icon` | string | Icon for the action. | | `head_pipeline.detailed_status.action.method` | string | HTTP method for the action, like `POST`. | | `head_pipeline.detailed_status.action.path` | string | Path for the action, like `"/namespace1/project1/-/jobs/2/cancel"`. | | `head_pipeline.detailed_status.action.title` | string | Title for the action. | | `head_pipeline.detailed_status.details_path` | string | Path to detailed view, like `"/test-group/test-project/-/pipelines/287"`. | | `head_pipeline.detailed_status.favicon` | string | Path to status favicon. | | `head_pipeline.detailed_status.group` | string | Status group, like `success`. | | `head_pipeline.detailed_status.has_details` | boolean | If set, a detailed view is available. | | `head_pipeline.detailed_status.icon` | string | Status icon name, like `"status_success"`. | | `head_pipeline.detailed_status.illustration.content` | string | Content text for the illustration, like `"This job depends on upstream jobs that need to succeed in order for this job to be triggered"`. | | `head_pipeline.detailed_status.illustration.image` | string | Path to illustration image. | | `head_pipeline.detailed_status.illustration.size` | string | Size of the illustration. | | `head_pipeline.detailed_status.illustration.title` | string | Title for the illustration, like `"This job has not been triggered yet"`. | | `head_pipeline.detailed_status.label` | string | Status label for the pipeline, like `"passed"`. | | `head_pipeline.detailed_status.text` | string | Status text for the pipeline, like `"passed"`. | | `head_pipeline.detailed_status.tooltip` | string | Tooltip text for the pipeline, like `"passed"`. | | `head_pipeline.duration` | integer | Time spent running the pipeline, in seconds. | | `head_pipeline.finished_at` | dateTime | Timestamp of when the pipeline finished. | | `head_pipeline.id` | integer | Unique numeric identifier of the pipeline. Foreign key to the `ci_pipelines` table. | | `head_pipeline.iid` | integer | Internal numeric ID of the pipeline. | | `head_pipeline.project_id` | integer | Numeric ID of the project containing the pipeline. | | `head_pipeline.queued_duration` | integer | Time spent enqueued, in seconds. | | `head_pipeline.ref` | string | Name of the Git reference (branch or tag) the pipeline runs on. | | `head_pipeline.sha` | string | SHA of the commit that triggered the pipeline. | | `head_pipeline.source` | string | How the pipeline was triggered. For example `push`, `merge_request_event`, or `api` | | `head_pipeline.started_at` | dateTime | Timestamp of when the pipeline started running. | | `head_pipeline.status` | string | Current status of the pipeline. Possible values: `success`, `failed`, `running`, `pending` | | `head_pipeline.tag` | boolean | If `true`, this pipeline is running on a Git tag. | | `head_pipeline.updated_at` | dateTime | Timestamp of when the pipeline was last updated. | | `head_pipeline.user[]` | object | Object containing information about the user who triggered the pipeline. | | `head_pipeline.user.avatar_url` | string | Full URL to user’s avatar image. | | `head_pipeline.user.id` | integer | The unique ID of the user who triggered the pipeline. | | `head_pipeline.user.locked` | boolean | If `true`, the user account that triggered the pipeline is locked due to failed authentication attempts, and they cannot sign in until the lock expires or an administrator unlocks the account. | | `head_pipeline.user.name` | string | Display name of the user who triggered the pipeline. Might be redacted, based on current user’s permissions. | | `head_pipeline.user.public_email` | string | The public email address of the user who triggered the pipeline. | | `head_pipeline.user.state` | string | Current state of the account of the user who triggered the pipeline. Possible values: `active`, `blocked`, or `deactivated`. | | `head_pipeline.user.username` | string | Username of the user who triggered the pipeline. | | `head_pipeline.user.web_url` | string | Full URL to the profile page of the user that triggered the pipeline. | | `head_pipeline.web_url` | string | Full URL to the pipeline page. | | `head_pipeline.yaml_errors` | string | Any YAML configuration errors. For example, `widgets:build: needs 'widgets:test'`) | | `id` | integer | ID of the merge request. | | `iid` | integer | Internal ID of the merge request. | | `imported` | boolean | If `true`, the merge request was imported. | | `imported_from` | string | Source of import, such as `Bitbucket`. | | `labels[]` | array | Array of label assigned to the merge request. If `with_labels_details` is `true`, returns an array for each label. | | `labels.archived` | boolean | If `with_labels_details` is `true`, the label is archived. | | `labels.color` | string | If `with_labels_details` is `true`, the background color of the label. | | `labels.description` | string | If `with_labels_details` is `true`, the description text of the label. If `null`, the label has no description. | | `labels.description_html` | string | If `with_labels_details` is `true`, the HTML-rendered description of the label. If `null`, the label has no description. | | `labels.id` | integer | If `with_labels_details` is `true`, the unique ID of the label. | | `labels.name` | string | If `with_labels_details` is `true`, the name of the label. | | `labels.text_color` | string | If `with_labels_details` is `true`, the text color for the label. | | `latest_build_finished_at` | datetime | Timestamp of when the latest build for the merge request finished. | | `latest_build_started_at` | datetime | Timestamp of when the latest build for the merge request started. | | `merge_after` | dateTime | If set, timestamp after which the merge request can be merged. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/510992)
in GitLab 17.8. | | `merge_commit_sha` | string | If set, the SHA of the merge request commit. Returns `null` until merged. | | `merge_error` | string | If set, the error message shown when a merge fails. To check mergeability, use `detailed_merge_status` instead. | | `merge_status` | string | Status 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](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes)
. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/3169#note_1162532204)
in GitLab 15.6. | | `merge_user[]` | object | The user who merged this merge request, the user who set it to auto-merge, or `null`. | | `merge_when_pipeline_succeeds` | boolean | If `true`, the merge request is set to auto-merge. | | `merged_at` | dateTime | Timestamp of when the merge request merged. | | `merged_by[]` | object | User who merged this merge request or set it to auto-merge. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/350534)
in GitLab 14.7, and scheduled for removal in [API version 5](https://gitlab.com/groups/gitlab-org/-/epics/8115)
. Use `merge_user` instead. | | `milestone[]` | object | Object with information about the milestone assigned to the merge request. | | `milestone.created_at` | dateTime | Timestamp when the milestone was created. | | `milestone.description` | string | Description text of the milestone. If `null`, the milestone has no description. | | `milestone.due_date` | date | Due date for the milestone. If `null`, the milestone has no due date. | | `milestone.expired` | boolean | If `true`, the milestone has expired. | | `milestone.group_id` | integer | ID of the group the milestone belongs to. Included only if the milestone is a group milestone. | | `milestone.id` | integer | Unique ID of the milestone. | | `milestone.iid` | integer | Internal ID of the milestone in the project or group. | | `milestone.project_id` | integer | ID of the project the milestone belongs to. Included only if the milestone is a project milestone. | | `milestone.start_date` | date | Start date for the milestone. If `null`, the milestone has no start date | | `milestone.state` | string | Current state of the milestone, such as `active` or `closed`. | | `milestone.title` | string | Name of the milestone. | | `milestone.updated_at` | dateTime | Timestamp when the milestone was last updated. | | `milestone.web_url` | string | Full web URL to view the milestone. | | `pipeline[]` | object | Pipeline running on the branch HEAD of the merge request. Consider using `head_pipeline` instead, as it contains more information. | | `prepared_at` | dateTime | Timestamp of when the merge request was prepared. This field populates one time, only after all the [preparation steps](https://docs.gitlab.com/api/merge_requests/#preparation-steps)
complete, and is not updated if more changes are added. | | `project_id` | integer | The ID of the project containing the merge request. | | `rebase_in_progress` | boolean | If `true`, Sidekiq is running a rebase operation on this branch. | | `reference` | string | Deprecated. Use `references` instead. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354)
in GitLab 12.7, and scheduled for removal in [API version 5](https://gitlab.com/groups/gitlab-org/-/epics/8115)
. Use `references` instead. | | `references[]` | object | Object with all internal references of the merge request. | | `references.full` | string | Complete 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.relative` | string | Reference 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.short` | string | Shortest possible reference to a merge request, like `!123`. When fetched from the merge request’s project, identical to `references.relative`. | | `reviewers[]` | array | Reviewers of the merge request. | | `reviewers.avatar_url` | string | Full URL to the reviewer’s avatar image. | | `reviewers.id` | integer | The unique ID of the reviewer. | | `reviewers.locked` | boolean | If `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.name` | string | Display name of the reviewer. Might be redacted, based on current user’s permissions. | | `reviewers.public_email` | string | The public email address of the reviewer. | | `reviewers.state` | string | Current state of the reviewer’s user account. Possible values: `active`, `blocked`, or `deactivated`. | | `reviewers.username` | string | Username of the merge request reviewer. | | `reviewers.web_url` | string | Full URL to the reviewer’s profile page. | | `sha` | string | SHA of the head commit in the source branch. | | `should_remove_source_branch` | boolean | If `true`, the source branch is removed after merge. | | `source_branch` | string | Name of the source branch. | | `source_project_id` | integer | ID of the source project. | | `squash` | boolean | If `true`, squash commits when merging. | | `squash_commit_sha` | string | If set, the SHA of the squash commit. Empty until merged. | | `squash_on_merge` | boolean | If `true`, commits are squashed on merge. | | `state` | string | The current state of the merge request. Possible values: `opened`, `closed`, `merged`, or `locked`. | | `subscribed` | boolean | If `true`, the current authenticated user subscribes to this merge request. | | `target_branch` | string | Name of the target branch. | | `target_project_id` | integer | ID of the target project. | | `task_completion_status[]` | object | Object with information on the task list completion status. | | `task_completion_status.completed_count` | integer | Number 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.count` | integer | Total 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[]` | object | Object with information on time tracking for this merge request. | | `time_stats.human_time_estimate` | string | Human-readable format of `time_stats.time_estimate`, like `3h 30m`. | | `time_stats.human_total_time_spent` | string | Human-readable format of `time_stats.total_time_spent`, like `3h 30m`. | | `time_stats.time_estimate` | integer | Estimated time to complete the merge request, in seconds. | | `time_stats.total_time_spent` | integer | Total time spent working on the merge request, in seconds. | | `title` | string | The merge request title. | | `updated_at` | datetime | Timestamp of when the merge request was last updated. | | `upvotes` | integer | Number of upvotes for the merge request. | | `user[]` | object | Permissions of the user requested for the merge request. | | `user.can_merge` | boolean | If `true`, the current authenticated user can merge this merge request. | | `user_notes_count` | integer | Number of user comments. | | `web_url` | string | Web URL to view the merge request. | | `work_in_progress` | boolean | Deprecated. Use `draft` instead. | Example response: { "id": 155016530, "iid": 133, "project_id": 15513260, "title": "Manual job rules", "description": "", "state": "opened", "imported": false, "imported_from": "none", "created_at": "2022-05-13T07:26:38.402Z", "updated_at": "2022-05-14T03:38:31.354Z", "merged_by": null, // Deprecated and will be removed in API v5. Use `merge_user` instead. "merge_user": null, "merged_at": null, "merge_after": "2018-09-07T11:16:00.000Z", "prepared_at": "2018-09-04T11:16:17.520Z", "closed_by": null, "closed_at": null, "target_branch": "main", "source_branch": "manual-job-rules", "user_notes_count": 0, "upvotes": 0, "downvotes": 0, "author": { "id": 4155490, "username": "marcel.amirault", "name": "Marcel Amirault", "state": "active", "avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/4155490/avatar.png", "web_url": "https://gitlab.com/marcel.amirault" }, "assignees": [], "assignee": null, "reviewers": [], "source_project_id": 15513260, "target_project_id": 15513260, "labels": [], "draft": false, "work_in_progress": false, "milestone": null, "merge_when_pipeline_succeeds": false, "merge_status": "can_be_merged", "detailed_merge_status": "mergeable", "sha": "e82eb4a098e32c796079ca3915e07487fc4db24c", "merge_commit_sha": null, "squash_commit_sha": null, "discussion_locked": null, "should_remove_source_branch": null, "force_remove_source_branch": true, "reference": "!133", // Deprecated. Use `references` instead. "references": { "short": "!133", "relative": "!133", "full": "marcel.amirault/test-project!133" }, "web_url": "https://gitlab.com/marcel.amirault/test-project/-/merge_requests/133", "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 }, "has_conflicts": false, "blocking_discussions_resolved": true, "approvals_before_merge": null, // deprecated, use [Merge request approvals API](merge_request_approvals.md) "subscribed": true, "changes_count": "1", "latest_build_started_at": "2022-05-13T09:46:50.032Z", "latest_build_finished_at": null, "first_deployed_to_production_at": null, "pipeline": { // Use `head_pipeline` instead. "id": 538317940, "iid": 1877, "project_id": 15513260, "sha": "1604b0c46c395822e4e9478777f8e54ac99fe5b9", "ref": "refs/merge-requests/133/merge", "status": "failed", "source": "merge_request_event", "created_at": "2022-05-13T09:46:39.560Z", "updated_at": "2022-05-13T09:47:20.706Z", "web_url": "https://gitlab.com/marcel.amirault/test-project/-/pipelines/538317940" }, "head_pipeline": { "id": 538317940, "iid": 1877, "project_id": 15513260, "sha": "1604b0c46c395822e4e9478777f8e54ac99fe5b9", "ref": "refs/merge-requests/133/merge", "status": "failed", "source": "merge_request_event", "created_at": "2022-05-13T09:46:39.560Z", "updated_at": "2022-05-13T09:47:20.706Z", "web_url": "https://gitlab.com/marcel.amirault/test-project/-/pipelines/538317940", "before_sha": "1604b0c46c395822e4e9478777f8e54ac99fe5b9", "tag": false, "yaml_errors": null, "user": { "id": 4155490, "username": "marcel.amirault", "name": "Marcel Amirault", "state": "active", "avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/4155490/avatar.png", "web_url": "https://gitlab.com/marcel.amirault" }, "started_at": "2022-05-13T09:46:50.032Z", "finished_at": "2022-05-13T09:47:20.697Z", "committed_at": null, "duration": 30, "queued_duration": 10, "coverage": null, "detailed_status": { "icon": "status_failed", "text": "failed", "label": "failed", "group": "failed", "tooltip": "failed", "has_details": true, "details_path": "/marcel.amirault/test-project/-/pipelines/538317940", "illustration": null, "favicon": "/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png" }, "archived": false }, "diff_refs": { "base_sha": "1162f719d711319a2efb2a35566f3bfdadee8bab", "head_sha": "e82eb4a098e32c796079ca3915e07487fc4db24c", "start_sha": "1162f719d711319a2efb2a35566f3bfdadee8bab" }, "merge_error": null, "first_contribution": false, "user": { "can_merge": true }, "approvals_before_merge": { // Available for GitLab Premium and Ultimate tiers only "id": 1, "title": "test1", "approvals_before_merge": null }, } ### Single merge request response notes The mergeability (`merge_status`) of each merge request is checked asynchronously when a request is made to this endpoint. Poll this API endpoint to get the updated status. This affects the `has_conflicts` property, as it depends on the `merge_status`. It returns `false` unless `merge_status` is `cannot_be_merged`. ### Merge status Use `detailed_merge_status` instead of `merge_status` to account for all potential statuses. * The `detailed_merge_status` field can contain one of the following values related to the merge request: * `approvals_syncing`: The merge request’s approvals are syncing. * `checking`: Git is testing if a valid merge is possible. * `ci_must_pass`: A CI/CD pipeline must succeed before merge. * `ci_still_running`: A CI/CD pipeline is still running. * `commits_status`: Source branch should exist, and contain commits. * `conflict`: Conflicts exist between the source and target branches. * `discussions_not_resolved`: All discussions must be resolved before merge. * `draft_status`: Can’t merge because the merge request is a draft. * `jira_association_missing`: The title or description must reference a Jira issue. To configure, see [require associated Jira issue for merge requests to be merged](https://docs.gitlab.com/integration/jira/issues/#require-associated-jira-issue-for-merge-requests-to-be-merged) . * `mergeable`: The branch can merge cleanly into the target branch. * `merge_request_blocked`: Blocked by another merge request. * `merge_time`: May not be merged until after the specified time. * `need_rebase`: The merge request must be rebased. * `not_approved`: Approval is required before merge. * `not_open`: The merge request must be open before merge. * `preparing`: Merge request diff is being created. * `requested_changes`: The merge request has reviewers who have requested changes. * `security_policy_pipeline_check`: All pipelines for the latest commit must succeed before the merge request is merged when security policies are enforced. * `security_policy_violations`: All security policies must be satisfied. * `status_checks_must_pass`: All status checks must pass before merge. * `unchecked`: Git has not yet tested if a valid merge is possible. * `locked_paths`: Paths locked by other users must be unlocked before merging to default branch. * `locked_lfs_files`: LFS files locked by other users must be unlocked before merge. * `title_regex`: Checks whether the title matches the expected regex, if configured in project settings. ### Preparation steps The `prepared_at` field populates one time, only after these steps complete: * Create the diff. * Create the pipelines. * Check mergeability. * Link all Git LFS objects. * Send notifications. The `prepared_at` field does not update if more changes are added to the merge request. Retrieve merge request participants ----------------------------------- Retrieve participants for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/participants Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | Example response: [\ {\ "id": 1,\ "name": "John Doe1",\ "username": "user1",\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon",\ "web_url": "http://localhost/user1"\ },\ {\ "id": 2,\ "name": "John Doe2",\ "username": "user2",\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/10fc7f102be8de7657fb4d80898bbfe3?s=80&d=identicon",\ "web_url": "http://localhost/user2"\ }\ ] Retrieve merge request reviewers -------------------------------- Retrieve reviewers for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/reviewers Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | Example response: [\ {\ "user": {\ "id": 1,\ "name": "John Doe1",\ "username": "user1",\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon",\ "web_url": "http://localhost/user1"\ },\ "state": "unreviewed",\ "created_at": "2022-07-27T17:03:27.684Z"\ },\ {\ "user": {\ "id": 2,\ "name": "John Doe2",\ "username": "user2",\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/10fc7f102be8de7657fb4d80898bbfe3?s=80&d=identicon",\ "web_url": "http://localhost/user2"\ },\ "state": "reviewed",\ "created_at": "2022-07-27T17:03:27.684Z"\ }\ ] Retrieve merge request commits ------------------------------ Retrieve commits for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/commits Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | Internal ID of the merge request. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `commits` | object array | Commits in the merge request. | | `commits[].id` | string | ID of the commit. | | `commits[].short_id` | string | Short ID of the commit. | | `commits[].created_at` | datetime | Identical to the `committed_date` field. | | `commits[].parent_ids` | array | IDs of the parent commits. | | `commits[].title` | string | Commit title. | | `commits[].message` | string | Commit message. | | `commits[].author_name` | string | Commit author’s name. | | `commits[].author_email` | string | Commit author’s email address. | | `commits[].authored_date` | datetime | Commit authored date. | | `commits[].committer_name` | string | Name of the committer. | | `commits[].committer_email` | string | Email address of the committer. | | `commits[].committed_date` | datetime | Commit date. | | `commits[].trailers` | object | Git trailers parsed for the commit. Duplicate keys include the last value only. | | `commits[].extended_trailers` | object | Git trailers parsed for the commit. | | `commits[].web_url` | string | Web URL of the merge request. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/commits" Example response: [\ {\ "id": "ed899a2f4b50b4370feeea94676502b42383c746",\ "short_id": "ed899a2f4b5",\ "title": "Replace sanitize with escape once",\ "author_name": "Example User",\ "author_email": "user@example.com",\ "authored_date": "2012-09-20T11:50:22+03:00",\ "committer_name": "Example User",\ "committer_email": "user@example.com",\ "committed_date": "2012-09-20T11:50:22+03:00",\ "created_at": "2012-09-20T11:50:22+03:00",\ "message": "Replace sanitize with escape once",\ "trailers": {},\ "extended_trailers": {},\ "web_url": "https://gitlab.example.com/project/-/commit/ed899a2f4b50b4370feeea94676502b42383c746"\ },\ {\ "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6",\ "short_id": "6104942438c",\ "title": "Sanitize for network graph",\ "author_name": "Example User",\ "author_email": "user@example.com",\ "authored_date": "2012-09-20T09:06:12+03:00",\ "committer_name": "Example User",\ "committer_email": "user@example.com",\ "committed_date": "2012-09-20T09:06:12+03:00",\ "created_at": "2012-09-20T09:06:12+03:00",\ "message": "Sanitize for network graph",\ "trailers": {},\ "extended_trailers": {},\ "web_url": "https://gitlab.example.com/project/-/commit/6104942438c14ec7bd21c6cd5bd995272b3faff6"\ }\ ] Retrieve merge request dependencies ----------------------------------- Retrieve dependencies that must be resolved before a merge request can be merged. If the user does not have access to the blocking merge request, no `blocking_merge_request` attribute is returned. GET /projects/:id/merge_requests/:merge_request_iid/blocks Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/blocks" Example response: [\ {\ "id": 1,\ "blocking_merge_request": {\ "id": 145,\ "iid": 12,\ "project_id": 7,\ "title": "Interesting MR",\ "description": "Does interesting things.",\ "state": "opened",\ "created_at": "2024-07-05T21:29:11.172Z",\ "updated_at": "2024-07-05T21:29:11.172Z",\ "merged_by": null,\ "merge_user": null,\ "merged_at": null,\ "merge_after": "2018-09-07T11:16:00.000Z",\ "closed_by": null,\ "closed_at": null,\ "target_branch": "master",\ "source_branch": "v2.x",\ "user_notes_count": 0,\ "upvotes": 0,\ "downvotes": 0,\ "author": {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ },\ "assignees": [\ {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ }\ ],\ "assignee": {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ },\ "reviewers": [\ {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ },\ {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/root"\ }\ ],\ "source_project_id": 7,\ "target_project_id": 7,\ "labels": [],\ "draft": false,\ "imported": false,\ "imported_from": "none",\ "work_in_progress": false,\ "milestone": null,\ "merge_when_pipeline_succeeds": false,\ "merge_status": "unchecked",\ "detailed_merge_status": "unchecked",\ "sha": "ce7e4f2d0ce13cb07479bb39dc10ee3b861c08a6",\ "merge_commit_sha": null,\ "squash_commit_sha": null,\ "discussion_locked": null,\ "should_remove_source_branch": null,\ "force_remove_source_branch": true,\ "prepared_at": null,\ "reference": "!12",\ "references": {\ "short": "!12",\ "relative": "!12",\ "full": "my-group/my-project!12"\ },\ "web_url": "https://localhost/my-group/my-project/-/merge_requests/12",\ "time_stats": {\ "time_estimate": 0,\ "total_time_spent": 0,\ "human_time_estimate": null,\ "human_total_time_spent": null\ },\ "squash": false,\ "squash_on_merge": false,\ "task_completion_status": {\ "count": 0,\ "completed_count": 0\ },\ "has_conflicts": false,\ "blocking_discussions_resolved": true,\ "approvals_before_merge": null\ },\ "blocked_merge_request": {\ "id": 146,\ "iid": 13,\ "project_id": 7,\ "title": "Really cool MR",\ "description": "Adds some stuff",\ "state": "opened",\ "created_at": "2024-07-05T21:31:34.811Z",\ "updated_at": "2024-07-27T02:57:08.054Z",\ "merged_by": null,\ "merge_user": null,\ "merged_at": null,\ "merge_after": "2018-09-07T11:16:00.000Z",\ "closed_by": null,\ "closed_at": null,\ "target_branch": "master",\ "source_branch": "remove-from",\ "user_notes_count": 0,\ "upvotes": 1,\ "downvotes": 0,\ "author": {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ },\ "assignees": [\ {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhose/aiguy123"\ }\ ],\ "assignee": {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ },\ "reviewers": [\ {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/root"\ }\ ],\ "source_project_id": 7,\ "target_project_id": 7,\ "labels": [],\ "draft": false,\ "imported": false,\ "imported_from": "none",\ "work_in_progress": false,\ "milestone": {\ "id": 59,\ "iid": 6,\ "project_id": 7,\ "title": "Sprint 1718897375",\ "description": "Accusantium omnis iusto a animi.",\ "state": "active",\ "created_at": "2024-06-20T15:29:35.739Z",\ "updated_at": "2024-06-20T15:29:35.739Z",\ "due_date": null,\ "start_date": null,\ "expired": false,\ "web_url": "https://localhost/my-group/my-project/-/milestones/6"\ },\ "merge_when_pipeline_succeeds": false,\ "merge_status": "cannot_be_merged",\ "detailed_merge_status": "not_approved",\ "sha": "daa75b9b17918f51f43866ff533987fda71375ea",\ "merge_commit_sha": null,\ "squash_commit_sha": null,\ "discussion_locked": null,\ "should_remove_source_branch": null,\ "force_remove_source_branch": true,\ "prepared_at": "2024-07-11T18:50:46.215Z",\ "reference": "!13",\ "references": {\ "short": "!13",\ "relative": "!13",\ "full": "my-group/my-project!12"\ },\ "web_url": "https://localhost/my-group/my-project/-/merge_requests/13",\ "time_stats": {\ "time_estimate": 0,\ "total_time_spent": 0,\ "human_time_estimate": null,\ "human_total_time_spent": null\ },\ "squash": false,\ "squash_on_merge": false,\ "task_completion_status": {\ "count": 0,\ "completed_count": 0\ },\ "has_conflicts": true,\ "blocking_discussions_resolved": true,\ "approvals_before_merge": null\ },\ "project_id": 7\ }\ ] Delete a merge request dependency --------------------------------- Delete a merge request dependency. DELETE /projects/:id/merge_requests/:merge_request_iid/blocks/:block_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
owned by the authenticated user. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `block_id` | integer | Yes | The ID of the block. | Example request: curl --request DELETE --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/blocks/1" Returns: * `204 No Content` if the dependency is successfully deleted. * `403 Forbidden` if the user lacks permissions for updating the merge request. * `403 Forbidden` if the user lacks permissions for reading the blocking merge request. Create a merge request dependency --------------------------------- Create a merge request dependency. POST /projects/:id/merge_requests/:merge_request_iid/blocks Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
owned by the authenticated user. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request to be blocked. | | `blocking_merge_request_id` | integer | Conditional | The global ID of the blocking merge request. Required if `blocking_merge_request_iid` is not provided. | | `blocking_merge_request_iid` | integer | Conditional | The IID of the blocking merge request. Required if `blocking_merge_request_id` is not provided. | | `blocking_project_id` | integer or string | No | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
that contains the blocking merge request. Required when `blocking_merge_request_iid` refers to a merge request in a different project. Defaults to the current project. | Example request using IID (same project): curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/blocks?blocking_merge_request_iid=2" Example request using IID (cross-project): curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/blocks?blocking_merge_request_iid=5&blocking_project_id=2" Example request using global ID (legacy method): curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/blocks?blocking_merge_request_id=12345" Returns: * `201 Created` if the dependency is successfully created. * `400 Bad request` if the blocking merge request fails to save. * `403 Forbidden` if the user lacks permissions for reading the blocking merge request. * `404 Not found` if the blocking merge request is not found. * `409 Conflict` if the block already exists. Example response: { "id": 1, "blocking_merge_request": { "id": 145, "iid": 12, "project_id": 7, "title": "Interesting MR", "description": "Does interesting things.", "state": "opened", "created_at": "2024-07-05T21:29:11.172Z", "updated_at": "2024-07-05T21:29:11.172Z", "merged_by": null, "merge_user": null, "merged_at": null, "merge_after": "2018-09-07T11:16:00.000Z", "closed_by": null, "closed_at": null, "target_branch": "master", "source_branch": "v2.x", "user_notes_count": 0, "upvotes": 0, "downvotes": 0, "author": { "id": 2, "username": "aiguy123", "name": "AI GUY", "state": "active", "locked": false, "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon", "web_url": "https://localhost/aiguy123" }, "assignees": [\ {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ }\ ], "assignee": { "id": 2, "username": "aiguy123", "name": "AI GUY", "state": "active", "locked": false, "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon", "web_url": "https://localhost/aiguy123" }, "reviewers": [\ {\ "id": 2,\ "username": "aiguy123",\ "name": "AI GUY",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/aiguy123"\ },\ {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",\ "web_url": "https://localhost/root"\ }\ ], "source_project_id": 7, "target_project_id": 7, "labels": [], "draft": false, "imported": false, "imported_from": "none", "work_in_progress": false, "milestone": null, "merge_when_pipeline_succeeds": false, "merge_status": "unchecked", "detailed_merge_status": "unchecked", "sha": "ce7e4f2d0ce13cb07479bb39dc10ee3b861c08a6", "merge_commit_sha": null, "squash_commit_sha": null, "discussion_locked": null, "should_remove_source_branch": null, "force_remove_source_branch": true, "prepared_at": null, "reference": "!12", "references": { "short": "!12", "relative": "!12", "full": "my-group/my-project!12" }, "web_url": "https://localhost/my-group/my-project/-/merge_requests/12", "time_stats": { "time_estimate": 0, "total_time_spent": 0, "human_time_estimate": null, "human_total_time_spent": null }, "squash": false, "squash_on_merge": false, "task_completion_status": { "count": 0, "completed_count": 0 }, "has_conflicts": false, "blocking_discussions_resolved": true, "approvals_before_merge": null }, "project_id": 7 } Retrieve blocked merge requests ------------------------------- Retrieve merge requests blocked by a merge request. GET /projects/:id/merge_requests/:merge_request_iid/blockees Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/blockees" Example response: [\ {\ "id": 18,\ "blocking_merge_request": {\ "id": 71,\ "iid": 10,\ "project_id": 7,\ "title": "At quaerat occaecati voluptate ex explicabo nisi.",\ "description": "Aliquid distinctio officia corrupti ad nemo natus ipsum culpa.",\ "state": "merged",\ "created_at": "2024-07-05T19:44:14.023Z",\ "updated_at": "2024-07-05T19:44:14.023Z",\ "merged_by": {\ "id": 40,\ "username": "i-user-0-1720208283",\ "name": "I User0",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/8325417f0f7919e3724957543b4414fdeca612cade1e4c0be45685fdaa2be0e2?s=80&d=identicon",\ "web_url": "http://127.0.0.1:3000/i-user-0-1720208283"\ },\ "merge_user": {\ "id": 40,\ "username": "i-user-0-1720208283",\ "name": "I User0",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/8325417f0f7919e3724957543b4414fdeca612cade1e4c0be45685fdaa2be0e2?s=80&d=identicon",\ "web_url": "http://127.0.0.1:3000/i-user-0-1720208283"\ },\ "merged_at": "2024-06-26T19:44:14.123Z",\ "closed_by": null,\ "closed_at": null,\ "target_branch": "master",\ "source_branch": "Brickwood-Brunefunc-417",\ "user_notes_count": 0,\ "upvotes": 0,\ "downvotes": 0,\ "author": {\ "id": 40,\ "username": "i-user-0-1720208283",\ "name": "I User0",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/8325417f0f7919e3724957543b4414fdeca612cade1e4c0be45685fdaa2be0e2?s=80&d=identicon",\ "web_url": "http://127.0.0.1:3000/i-user-0-1720208283"\ },\ "assignees": [],\ "assignee": null,\ "reviewers": [],\ "source_project_id": 7,\ "target_project_id": 7,\ "labels": [],\ "draft": false,\ "imported": false,\ "imported_from": "none",\ "work_in_progress": false,\ "milestone": null,\ "merge_when_pipeline_succeeds": false,\ "merge_status": "can_be_merged",\ "detailed_merge_status": "not_open",\ "merge_after": null,\ "sha": null,\ "merge_commit_sha": null,\ "squash_commit_sha": null,\ "discussion_locked": null,\ "should_remove_source_branch": null,\ "force_remove_source_branch": null,\ "prepared_at": null,\ "reference": "!10",\ "references": {\ "short": "!10",\ "relative": "!10",\ "full": "flightjs/Flight!10"\ },\ "web_url": "http://127.0.0.1:3000/flightjs/Flight/-/merge_requests/10",\ "time_stats": {\ "time_estimate": 0,\ "total_time_spent": 0,\ "human_time_estimate": null,\ "human_total_time_spent": null\ },\ "squash": false,\ "squash_on_merge": false,\ "task_completion_status": {\ "count": 0,\ "completed_count": 0\ },\ "has_conflicts": false,\ "blocking_discussions_resolved": true,\ "approvals_before_merge": null\ },\ "blocked_merge_request": {\ "id": 176,\ "iid": 14,\ "project_id": 7,\ "title": "second_mr",\ "description": "Signed-off-by: Lucas Zampieri ",\ "state": "opened",\ "created_at": "2024-07-08T19:12:29.089Z",\ "updated_at": "2024-08-27T19:27:17.045Z",\ "merged_by": null,\ "merge_user": null,\ "merged_at": null,\ "closed_by": null,\ "closed_at": null,\ "target_branch": "master",\ "source_branch": "second_mr",\ "user_notes_count": 0,\ "upvotes": 0,\ "downvotes": 0,\ "author": {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "locked": false,\ "avatar_url": "https://www.gravatar.com/avatar/fc3634394c590e212d964e8e0a34c4d9b8c17c992f4d6d145d75f9c21c1c3b6e?s=80&d=identicon",\ "web_url": "http://127.0.0.1:3000/root"\ },\ "assignees": [],\ "assignee": null,\ "reviewers": [],\ "source_project_id": 7,\ "target_project_id": 7,\ "labels": [],\ "draft": false,\ "imported": false,\ "imported_from": "none",\ "work_in_progress": false,\ "milestone": null,\ "merge_when_pipeline_succeeds": false,\ "merge_status": "cannot_be_merged",\ "detailed_merge_status": "commits_status",\ "merge_after": null,\ "sha": "3a576801e528db79a75fbfea463673054ff224fb",\ "merge_commit_sha": null,\ "squash_commit_sha": null,\ "discussion_locked": null,\ "should_remove_source_branch": null,\ "force_remove_source_branch": true,\ "prepared_at": null,\ "reference": "!14",\ "references": {\ "short": "!14",\ "relative": "!14",\ "full": "flightjs/Flight!14"\ },\ "web_url": "http://127.0.0.1:3000/flightjs/Flight/-/merge_requests/14",\ "time_stats": {\ "time_estimate": 0,\ "total_time_spent": 0,\ "human_time_estimate": null,\ "human_total_time_spent": null\ },\ "squash": false,\ "squash_on_merge": false,\ "task_completion_status": {\ "count": 0,\ "completed_count": 0\ },\ "has_conflicts": true,\ "blocking_discussions_resolved": true,\ "approvals_before_merge": null\ },\ "project_id": 7\ }\ ] Retrieve merge request changes ------------------------------ This endpoint was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/322117) in GitLab 15.7 and [is scheduled for removal](https://docs.gitlab.com/api/rest/deprecations/) in API v5. Use the [list merge request diffs](https://docs.gitlab.com/api/merge_requests/#list-merge-request-diffs) endpoint instead. Retrieve information about a merge request, including its files and changes. GET /projects/:id/merge_requests/:merge_request_iid/changes Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `access_raw_diffs` | boolean | No | Retrieve change diffs through Gitaly. | | `unidiff` | boolean | No | Present change diffs in the [unified diff](https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html)
format. Default is false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130610)
in GitLab 16.5. | Diffs associated with the set of changes have the same size limitations applied as other diffs returned by the API or viewed through the UI. When these limits impact the results, the `overflow` field contains a value of `true`. Retrieve the diff data without these limits by adding the `access_raw_diffs` parameter, which accesses diffs not from the database, but from Gitaly directly. This approach is generally slower and more resource-intensive, but isn’t subject to size limits placed on database-backed diffs. Limits inherent to Gitaly still apply. Example response: { "id": 21, "iid": 1, "project_id": 4, "title": "Blanditiis beatae suscipit hic assumenda et molestias nisi asperiores repellat et.", "state": "reopened", "created_at": "2015-02-02T19:49:39.159Z", "updated_at": "2015-02-02T20:08:49.959Z", "target_branch": "secret_token", "source_branch": "version-1-9", "upvotes": 0, "downvotes": 0, "author": { "name": "Chad Hamill", "username": "jarrett", "id": 5, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/b95567800f828948baf5f4160ebb2473?s=40&d=identicon", "web_url" : "https://gitlab.example.com/jarrett" }, "assignee": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon", "web_url" : "https://gitlab.example.com/root" }, "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": [{\ "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"\ }], "source_project_id": 4, "target_project_id": 4, "labels": [ ], "description": "Qui voluptatibus placeat ipsa alias quasi. Deleniti rem ut sint. Optio velit qui distinctio.", "draft": false, "work_in_progress": false, "milestone": { "id": 5, "iid": 1, "project_id": 4, "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": null }, "merge_when_pipeline_succeeds": true, "merge_status": "can_be_merged", "detailed_merge_status": "mergeable", "subscribed" : true, "sha": "8888888888888888888888888888888888888888", "merge_commit_sha": null, "squash_commit_sha": null, "user_notes_count": 1, "changes_count": "1", "should_remove_source_branch": true, "force_remove_source_branch": false, "squash": false, "web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1", "references": { "short": "!1", "relative": "!1", "full": "my-group/my-project!1" }, "discussion_locked": false, "time_stats": { "time_estimate": 0, "total_time_spent": 0, "human_time_estimate": null, "human_total_time_spent": null }, "task_completion_status":{ "count":0, "completed_count":0 }, "changes": [\ {\ "old_path": "VERSION",\ "new_path": "VERSION",\ "a_mode": "100644",\ "b_mode": "100644",\ "diff": "@@ -1 +1 @@\ -1.9.7\ +1.9.8",\ "new_file": false,\ "renamed_file": false,\ "deleted_file": false\ }\ ], "overflow": false } List merge request diffs ------------------------ History * `generated_file` [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141576) in GitLab 16.9 [with a flag](https://docs.gitlab.com/administration/feature_flags/) named `collapse_generated_diff_files`. Disabled by default. * [Enabled on GitLab.com and GitLab Self-Managed](https://gitlab.com/gitlab-org/gitlab/-/issues/432670) in GitLab 16.10. * `generated_file` [generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/148478) in GitLab 16.11. Feature flag `collapse_generated_diff_files` removed. * `collapsed` and `too_large` response attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/199633) in GitLab 18.4. List diffs of the files changed in a merge request. GET /projects/:id/merge_requests/:merge_request_iid/diffs Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `page` | integer | No | The page of results to return. Defaults to 1. | | `per_page` | integer | No | The number of results per page. Defaults to 20. | | `unidiff` | boolean | No | Present diffs in the [unified diff](https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html)
format. Default is false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130610)
in GitLab 16.5. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `a_mode` | string | Old file mode of the file. | | `b_mode` | string | New file mode of the file. | | `collapsed` | boolean | File diffs are excluded but can be fetched on request. | | `deleted_file` | boolean | File has been removed. | | `diff` | string | Diff representation of the changes made to the file. | | `generated_file` | boolean | File is [marked as generated](https://docs.gitlab.com/user/project/merge_requests/changes/#collapse-generated-files)
. | | `new_file` | boolean | File has been added. | | `new_path` | string | New path of the file. | | `old_path` | string | Old path of the file. | | `renamed_file` | boolean | File has been renamed. | | `too_large` | boolean | File diffs are excluded and cannot be retrieved. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/diffs?page=1&per_page=2" Example response: [\ {\ "old_path": "README",\ "new_path": "README",\ "a_mode": "100644",\ "b_mode": "100644",\ "diff": "@@ -1 +1 @@\ -Title\ +README",\ "collapsed": false,\ "too_large": false,\ "new_file": false,\ "renamed_file": false,\ "deleted_file": false,\ "generated_file": false\ },\ {\ "old_path": "VERSION",\ "new_path": "VERSION",\ "a_mode": "100644",\ "b_mode": "100644",\ "diff": "@@\ -1.9.7\ +1.9.8",\ "collapsed": false,\ "too_large": false,\ "new_file": false,\ "renamed_file": false,\ "deleted_file": false,\ "generated_file": false\ }\ ] This endpoint is subject to [merge requests diff limits](https://docs.gitlab.com/administration/instance_limits/#diff-limits) . Merge requests that exceed the diff limits return limited results. Show merge request raw diffs ---------------------------- Show raw diffs of the files changed in a merge request. GET /projects/:id/merge_requests/:merge_request_iid/raw_diffs Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and a raw diff response to use programmatically: Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/raw_diffs" Example response: diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 31525ad523553c8d7eff163db3e539058efd6d3a..f30e36d6fdf4cd4fa25f62e08ecdbf4a7b169681 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -944,6 +944,10 @@ def send_git_blob(repository, blob) body '' end + def send_git_diff(repository, diff_refs) + header(*Gitlab::Workhorse.send_git_diff(repository, diff_refs)) + end + def send_git_archive(repository, **kwargs) header(*Gitlab::Workhorse.send_git_archive(repository, **kwargs)) diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index e02d9eea1852f19fe5311acda6aa17465eeb422e..f32b38585398a18fea75c11d7b8ebb730eeb3fab 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -6,6 +6,8 @@ class MergeRequests < ::API::Base include PaginationParams include Helpers::Unidiff + helpers ::API::Helpers::HeadersHelpers + CONTEXT_COMMITS_POST_LIMIT = 20 before { authenticate_non_get! } This endpoint is subject to [merge requests diff limits](https://docs.gitlab.com/administration/instance_limits/#diff-limits) . Merge requests that exceed the diff limits return limited results. List merge request pipelines ---------------------------- List all pipelines for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/pipelines Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | To restrict the list of merge request pipelines, use the pagination parameters `page` and `per_page`. Example response: [\ {\ "id": 77,\ "sha": "959e04d7c7a30600c894bd3c0cd0e1ce7f42c11d",\ "ref": "main",\ "status": "success"\ }\ ] Create merge request pipeline ----------------------------- Create a new [pipeline for a merge request](https://docs.gitlab.com/ci/pipelines/merge_request_pipelines/) . A pipeline created from this endpoint doesn’t run a regular branch/tag pipeline. To create jobs, configure `.gitlab-ci.yml` with `only: [merge_requests]`. The new pipeline can be: * A detached merge request pipeline. * A [merged results pipeline](https://docs.gitlab.com/ci/pipelines/merged_results_pipelines/) if the [project setting is enabled](https://docs.gitlab.com/ci/pipelines/merged_results_pipelines/#enable-merged-results-pipelines) . POST /projects/:id/merge_requests/:merge_request_iid/pipelines Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | Example response: { "id": 2, "sha": "b83d6e391c22777fca1ed3012fce84f633d7fed0", "ref": "refs/merge-requests/1/head", "status": "pending", "web_url": "http://localhost/user1/project1/pipelines/2", "before_sha": "0000000000000000000000000000000000000000", "tag": false, "yaml_errors": null, "user": { "id": 1, "name": "John Doe1", "username": "user1", "state": "active", "avatar_url": "https://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon", "web_url": "http://example.com" }, "created_at": "2019-09-04T19:20:18.267Z", "updated_at": "2019-09-04T19:20:18.459Z", "started_at": null, "finished_at": null, "committed_at": null, "duration": null, "coverage": null, "detailed_status": { "icon": "status_pending", "text": "pending", "label": "pending", "group": "pending", "tooltip": "pending", "has_details": false, "details_path": "/user1/project1/pipelines/2", "illustration": null, "favicon": "/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png" }, "archived": false } Create a merge request ---------------------- Create a new merge request. POST /projects/:id/merge_requests | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths) | | `source_branch` | string | Yes | The source branch. | | `target_branch` | string | Yes | The target branch. | | `title` | string | Yes | Title of MR. | | `allow_collaboration` | boolean | No | Allow commits from members who can merge to the target branch. | | `approvals_before_merge` | integer | No | Number of approvals required before this merge request can merge (see below). To configure approval rules, see the [merge request approvals API](https://docs.gitlab.com/api/merge_request_approvals/)
. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097)
in GitLab 16.0. Premium and Ultimate only. | | `allow_maintainer_to_push` | boolean | No | Alias of `allow_collaboration`. | | `assignee_id` | integer | No | Assignee user ID. | | `assignee_ids` | integer array | No | The ID of the users to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. | | `description` | string | No | Description of the merge request. Limited to 1,048,576 characters. | | `labels` | string | No | Labels for the merge request, as a comma-separated list. If a label does not already exist, this creates a new project label and assigns it to the merge request. | | `merge_after` | string | No | Date after which the merge request can be merged. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/510992)
in GitLab 17.8. | | `milestone_id` | integer | No | The global ID of a milestone. | | `remove_source_branch` | boolean | No | Flag indicating if a merge request should remove the source branch when merging. | | `reviewer_ids` | integer array | No | The ID of the users added as a reviewer to the merge request. If set to `0` or left empty, no reviewers are added. | | `squash` | boolean | No | If `true`, squash all commits into a single commit on merge. When not provided, defaults to the [project’s squash option setting](https://docs.gitlab.com/user/project/merge_requests/squash_and_merge/#configure-squash-options-for-a-project)
. Project settings might override this value at merge time. | | `target_project_id` | integer | No | Numeric ID of the target project. | Example response: { "id": 1, "iid": 1, "project_id": 3, "title": "test1", "description": "fixed login page css paddings", "state": "merged", "imported": false, "imported_from": "none", "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": { "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" }, "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", "merge_error": null, "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": "!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, "subscribed": false, "changes_count": "1", "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, "latest_build_started_at": "2018-09-07T07:27:38.472Z", "latest_build_finished_at": "2018-09-07T08:07:06.012Z", "first_deployed_to_production_at": null, "pipeline": { "id": 29626725, "sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "ref": "patch-28", "status": "success", "web_url": "https://gitlab.example.com/my-group/my-project/pipelines/29626725" }, "diff_refs": { "base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00", "head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00" }, "diverged_commits_count": 2, "task_completion_status":{ "count":0, "completed_count":0 } } For important notes on response data, see [single merge request response notes](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes) . Update a merge request ---------------------- Update an existing merge request. PUT /projects/:id/merge_requests/:merge_request_iid | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The ID of a merge request. | | `add_labels` | string | No | Comma-separated label names to add to a merge request. If a label does not already exist, this creates a new project label and assigns it to the merge request. | | `allow_collaboration` | boolean | No | Allow commits from members who can merge to the target branch. | | `allow_maintainer_to_push` | boolean | No | Alias of `allow_collaboration`. | | `assignee_id` | integer | No | The ID of the user to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. | | `assignee_ids` | integer array | No | The ID of the users to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. | | `description` | string | No | Description of the merge request. Limited to 1,048,576 characters. | | `discussion_locked` | boolean | No | Flag indicating if the merge request’s discussion is locked. Only project members can add, edit or resolve comments to locked discussions. | | `labels` | string | No | Comma-separated label names for a merge request. Set to an empty string to unassign all labels. If a label does not already exist, this creates a new project label and assigns it to the merge request. | | `merge_after` | string | No | Date after which the merge request can be merged. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/510992)
in GitLab 17.8. | | `milestone_id` | integer | No | The global ID of a milestone to assign the merge request to. Set to `0` or provide an empty value to unassign a milestone. | | `remove_labels` | string | No | Comma-separated label names to remove from a merge request. | | `remove_source_branch` | boolean | No | Flag indicating if a merge request should remove the source branch when merging. | | `reviewer_ids` | integer array | No | The ID of the users set as a reviewer to the merge request. Set the value to `0` or provide an empty value to unset all reviewers. | | `squash` | boolean | No | If `true`, squash all commits into a single commit on merge. When not provided, defaults to the [project’s squash option setting](https://docs.gitlab.com/user/project/merge_requests/squash_and_merge/#configure-squash-options-for-a-project)
. If the project is configured to **Require** or **Do not allow** squashing, that setting takes precedence at merge time. | | `state_event` | string | No | New state (close/reopen). | | `target_branch` | string | No | The target branch. | | `title` | string | No | Title of MR. | Must include at least one non-required attribute. Example response: { "id": 1, "iid": 1, "project_id": 3, "title": "test1", "description": "fixed login page css paddings", "state": "merged", "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": { "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": [{\ "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"\ }], "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", "merge_error": null, "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": "!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, "subscribed": false, "changes_count": "1", "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, "latest_build_started_at": "2018-09-07T07:27:38.472Z", "latest_build_finished_at": "2018-09-07T08:07:06.012Z", "first_deployed_to_production_at": null, "pipeline": { "id": 29626725, "sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "ref": "patch-28", "status": "success", "web_url": "https://gitlab.example.com/my-group/my-project/pipelines/29626725" }, "diff_refs": { "base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00", "head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00" }, "diverged_commits_count": 2, "task_completion_status":{ "count":0, "completed_count":0 } } For important notes on response data, see [single merge request response notes](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes) . Delete a merge request ---------------------- Delete a merge request. Only administrators and project owners can delete merge requests. DELETE /projects/:id/merge_requests/:merge_request_iid | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/4/merge_requests/85" Merge a merge request --------------------- Accept and merge changes submitted with merge request using this API. PUT /projects/:id/merge_requests/:merge_request_iid/merge Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `auto_merge` | boolean | No | If `true`, the merge request merges when the pipeline succeeds. | | `merge_commit_message` | string | No | Custom merge commit message. | | `merge_when_pipeline_succeeds` | boolean | No | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/521291)
in GitLab 17.11. Use `auto_merge` instead. | | `sha` | string | No | If present, this SHA must match the HEAD of the source branch. Use to ensure that only reviewed commits are merged. | | `should_remove_source_branch` | boolean | No | If `true`, removes the source branch. | | `squash_commit_message` | string | No | Custom squash commit message. | | `squash` | boolean | No | If `true`, squash all commits into a single commit on merge. | This API returns specific HTTP status codes on failure: | HTTP Status | Message | Reason | | --- | --- | --- | | `401` | `401 Unauthorized` | This user does not have permission to accept this merge request. | | `405` | `405 Method Not Allowed` | The merge request cannot merge. | | `409` | `SHA does not match HEAD of source branch` | The provided `sha` parameter does not match the HEAD of the source. | | `422` | `Branch cannot be merged` | The merge request failed to merge. | For important notes on response data, see [single merge request response notes](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes) . Example response: { "id": 1, "iid": 1, "project_id": 3, "title": "test1", "description": "fixed login page css paddings", "state": "merged", "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": { "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": [{\ "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"\ }], "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", "merge_error": null, "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": "!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, "subscribed": false, "changes_count": "1", "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, "latest_build_started_at": "2018-09-07T07:27:38.472Z", "latest_build_finished_at": "2018-09-07T08:07:06.012Z", "first_deployed_to_production_at": null, "pipeline": { "id": 29626725, "sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "ref": "patch-28", "status": "success", "web_url": "https://gitlab.example.com/my-group/my-project/pipelines/29626725" }, "diff_refs": { "base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00", "head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00" }, "diverged_commits_count": 2, "task_completion_status":{ "count":0, "completed_count":0 } } Merge to default merge ref path ------------------------------- Merge the changes between the merge request source and target branches into `refs/merge-requests/:iid/merge` ref, of the target project repository, if possible. This ref has the state the target branch would have if a regular merge action was taken. This action isn’t a regular merge action, because it doesn’t change the merge request target branch state in any manner. This ref (`refs/merge-requests/:iid/merge`) isn’t necessarily overwritten when submitting requests to this API, though it makes sure the ref has the latest possible state. GET /projects/:id/merge_requests/:merge_request_iid/merge_ref Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | This API returns specific HTTP status codes: | HTTP Status | Message | Reason | | --- | --- | --- | | `200` | _(none)_ | Success. Returns the HEAD commit of `refs/merge-requests/:iid/merge`. | | `400` | `Merge request is not mergeable` | The merge request has conflicts. | | `400` | `Merge ref cannot be updated` | | | `400` | `Unsupported operation` | The GitLab database is in read-only mode. | Example response: { "commit_id": "854a3a7a17acbcc0bbbea170986df1eb60435f34" } Cancel merge when pipeline succeeds ----------------------------------- POST /projects/:id/merge_requests/:merge_request_iid/cancel_merge_when_pipeline_succeeds Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | This API returns specific HTTP status codes: | HTTP Status | Message | Reason | | --- | --- | --- | | `201` | _(none)_ | Success, or the merge request has already merged. | | `406` | `Can't cancel the automatic merge` | The merge request is closed. | For important notes on response data, see [single merge request response notes](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes) . Example response: { "id": 1, "iid": 1, "project_id": 3, "title": "test1", "description": "fixed login page css paddings", "state": "merged", "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": { "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": [{\ "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"\ }], "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": false, "merge_status": "can_be_merged", "detailed_merge_status": "not_open", "merge_error": null, "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": "!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, "subscribed": false, "changes_count": "1", "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, "latest_build_started_at": "2018-09-07T07:27:38.472Z", "latest_build_finished_at": "2018-09-07T08:07:06.012Z", "first_deployed_to_production_at": null, "pipeline": { "id": 29626725, "sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "ref": "patch-28", "status": "success", "web_url": "https://gitlab.example.com/my-group/my-project/pipelines/29626725" }, "diff_refs": { "base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00", "head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00" }, "diverged_commits_count": 2, "task_completion_status":{ "count":0, "completed_count":0 } } Rebase a merge request ---------------------- Automatically rebase the `source_branch` of the merge request against its `target_branch`. PUT /projects/:id/merge_requests/:merge_request_iid/rebase | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `skip_ci` | boolean | No | Set to `true` to skip creating a CI pipeline. | curl --request PUT \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/76/merge_requests/1/rebase" This API returns specific HTTP status codes: | HTTP Status | Message | Reason | | --- | --- | --- | | `202` | _(no message)_ | Successfully enqueued. | | `403` | `Cannot push to source branch` | You don’t have permission to push to the merge request’s source branch. | | `403` | `Source branch does not exist` | You don’t have permission to push to the merge request’s source branch. | | `403` | `Source branch is protected from force push` | You don’t have permission to push to the merge request’s source branch. | | `409` | `Failed to enqueue the rebase operation` | A long-lived transaction might have blocked your request. | If the request is added to the queue successfully, the response contains: { "rebase_in_progress": true } You can poll the [retrieve a merge request](https://docs.gitlab.com/api/merge_requests/#retrieve-a-merge-request) endpoint with the `include_rebase_in_progress` parameter to check the status of the asynchronous request. If the rebase operation is ongoing, the response includes the following: { "rebase_in_progress": true, "merge_error": null } After the rebase operation has completed successfully, the response includes the following: { "rebase_in_progress": false, "merge_error": null } If the rebase operation fails, the response includes the following: { "rebase_in_progress": false, "merge_error": "Rebase failed. Please rebase locally" } Comments on merge requests -------------------------- The [notes](https://docs.gitlab.com/api/notes/) resource creates comments. List issues that close on merge ------------------------------- List issues that would close when a merge request is merged. GET /projects/:id/merge_requests/:merge_request_iid/closes_issues Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | Internal ID of the merge request. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes when you use the GitLab issue tracker: | Attribute | Type | Description | | --- | --- | --- | | `[].assignee` | object | First assignee of the issue. | | `[].assignees` | array | Assignees of the issue. | | `[].author` | object | User who created this issue. | | `[].blocking_issues_count` | integer | Count of issues this issue is blocking. | | `[].closed_at` | datetime | Timestamp of when the issue was closed. | | `[].closed_by` | object | User who closed this issue. | | `[].confidential` | boolean | Indicates if the issue is confidential. | | `[].created_at` | datetime | Timestamp of when the issue was created. | | `[].description` | string | Description of the issue. | | `[].discussion_locked` | boolean | Indicates if comments on the issue are locked to members only. | | `[].downvotes` | integer | Number of downvotes the issue has received. | | `[].due_date` | datetime | Due date of the issue. | | `[].id` | integer | ID of the issue. | | `[].iid` | integer | Internal ID of the issue. | | `[].issue_type` | string | Type of the issue. Can be `issue`, `incident`, `test_case`, `requirement`, `task`. | | `[].labels` | array | Labels of the issue. | | `[].merge_requests_count` | integer | Number of merge requests that close the issue on merge. | | `[].milestone` | object | Milestone of the issue. | | `[].project_id` | integer | ID of the issue project. | | `[].state` | string | State of the issue. Can be `opened` or `closed`. | | `[].task_completion_status` | object | Includes `count` and `completed_count`. | | `[].time_stats` | object | Time statistics for the issue. Includes `time_estimate`, `total_time_spent`, `human_time_estimate`, and `human_total_time_spent`. | | `[].title` | string | Title of the issue. | | `[].type` | string | Type of the issue. Same as `issue_type`, but uppercase. | | `[].updated_at` | datetime | Timestamp of when the issue was updated. | | `[].upvotes` | integer | Number of upvotes the issue has received. | | `[].user_notes_count` | integer | User notes count of the issue. | | `[].web_url` | string | Web URL of the issue. | | `[].weight` | integer | Weight of the issue. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes when you use an external issue tracker, like Jira: | Attribute | Type | Description | | --- | --- | --- | | `[].id` | integer | ID of the issue. | | `[].title` | string | Title of the issue. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/76/merge_requests/1/closes_issues" Example response when you use the GitLab issue tracker: [\ {\ "id": 76,\ "iid": 6,\ "project_id": 1,\ "title": "Consequatur vero maxime deserunt laboriosam est voluptas dolorem.",\ "description": "Ratione dolores corrupti mollitia soluta quia.",\ "state": "opened",\ "created_at": "2024-09-06T10:58:49.002Z",\ "updated_at": "2024-09-06T11:01:40.710Z",\ "closed_at": null,\ "closed_by": null,\ "labels": [\ "label"\ ],\ "milestone": {\ "project_id": 1,\ "description": "Ducimus nam enim ex consequatur cumque ratione.",\ "state": "closed",\ "due_date": null,\ "iid": 2,\ "created_at": "2016-01-04T15:31:39.996Z",\ "title": "v4.0",\ "id": 17,\ "updated_at": "2016-01-04T15:31:39.996Z"\ },\ "assignees": [\ {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "locked": false,\ "avatar_url": null,\ "web_url": "https://gitlab.example.com/root"\ }\ ],\ "author": {\ "id": 18,\ "username": "eileen.lowe",\ "name": "Alexandra Bashirian",\ "state": "active",\ "locked": false,\ "avatar_url": null,\ "web_url": "https://gitlab.example.com/eileen.lowe"\ },\ "type": "ISSUE",\ "assignee": {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "locked": false,\ "avatar_url": null,\ "web_url": "https://gitlab.example.com/root"\ },\ "user_notes_count": 1,\ "merge_requests_count": 1,\ "upvotes": 0,\ "downvotes": 0,\ "due_date": null,\ "confidential": false,\ "discussion_locked": null,\ "issue_type": "issue",\ "web_url": "https://gitlab.example.com/my-group/my-project/-/issues/6",\ "time_stats": {\ "time_estimate": 0,\ "total_time_spent": 0,\ "human_time_estimate": null,\ "human_total_time_spent": null\ },\ "task_completion_status": {\ "count": 0,\ "completed_count": 0\ },\ "weight": null,\ "blocking_issues_count": 0\ }\ ] Example response when you use an external issue tracker, like Jira: [\ {\ "id" : "PROJECT-123",\ "title" : "Title of this issue"\ }\ ] List issues related to the merge request ---------------------------------------- List issues related to a merge request from its title, description, commit messages, comments, and discussions. GET /projects/:id/merge_requests/:merge_request_iid/related_issues | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/76/merge_requests/1/related_issues" Example response when you use the GitLab issue tracker: [\ {\ "state" : "opened",\ "description" : "Ratione dolores corrupti mollitia soluta quia.",\ "author" : {\ "state" : "active",\ "id" : 18,\ "web_url" : "https://gitlab.example.com/eileen.lowe",\ "name" : "Alexandra Bashirian",\ "avatar_url" : null,\ "username" : "eileen.lowe"\ },\ "milestone" : {\ "project_id" : 1,\ "description" : "Ducimus nam enim ex consequatur cumque ratione.",\ "state" : "closed",\ "due_date" : null,\ "iid" : 2,\ "created_at" : "2016-01-04T15:31:39.996Z",\ "title" : "v4.0",\ "id" : 17,\ "updated_at" : "2016-01-04T15:31:39.996Z"\ },\ "project_id" : 1,\ "assignee" : {\ "state" : "active",\ "id" : 1,\ "name" : "Administrator",\ "web_url" : "https://gitlab.example.com/root",\ "avatar_url" : null,\ "username" : "root"\ },\ "updated_at" : "2016-01-04T15:31:51.081Z",\ "id" : 76,\ "title" : "Consequatur vero maxime deserunt laboriosam est voluptas dolorem.",\ "created_at" : "2016-01-04T15:31:51.081Z",\ "iid" : 6,\ "labels" : [],\ "user_notes_count": 1,\ "changes_count": "1"\ }\ ] Example response when you use an external issue tracker, like Jira: [\ {\ "id" : "PROJECT-123",\ "title" : "Title of this issue"\ }\ ] Subscribe to a merge request ---------------------------- Subscribes the authenticated user to a merge request to receive notification. POST /projects/:id/merge_requests/:merge_request_iid/subscribe | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | If the user is already subscribed to the merge request, the endpoint returns the status code `HTTP 304 Not Modified`. curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/17/subscribe" Example response: { "id": 1, "iid": 1, "project_id": 3, "title": "test1", "description": "fixed login page css paddings", "state": "merged", "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": { "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": [{\ "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"\ }], "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": "!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, "subscribed": false, "changes_count": "1", "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, "latest_build_started_at": "2018-09-07T07:27:38.472Z", "latest_build_finished_at": "2018-09-07T08:07:06.012Z", "first_deployed_to_production_at": null, "pipeline": { "id": 29626725, "sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "ref": "patch-28", "status": "success", "web_url": "https://gitlab.example.com/my-group/my-project/pipelines/29626725" }, "diff_refs": { "base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00", "head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00" }, "diverged_commits_count": 2, "task_completion_status":{ "count":0, "completed_count":0 } } For important notes on response data, see [single merge request response notes](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes) . Unsubscribe from a merge request -------------------------------- Unsubscribes the authenticated user from a merge request to not receive notifications from that merge request. POST /projects/:id/merge_requests/:merge_request_iid/unsubscribe | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/17/unsubscribe" If the user is not subscribed to the merge request, the endpoint returns the status code `HTTP 304 Not Modified`. Example response: { "id": 1, "iid": 1, "project_id": 3, "title": "test1", "description": "fixed login page css paddings", "state": "merged", "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": { "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": [{\ "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"\ }], "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": "!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, "subscribed": false, "changes_count": "1", "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, "latest_build_started_at": "2018-09-07T07:27:38.472Z", "latest_build_finished_at": "2018-09-07T08:07:06.012Z", "first_deployed_to_production_at": null, "pipeline": { "id": 29626725, "sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "ref": "patch-28", "status": "success", "web_url": "https://gitlab.example.com/my-group/my-project/pipelines/29626725" }, "diff_refs": { "base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00", "head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f", "start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00" }, "diverged_commits_count": 2, "task_completion_status":{ "count":0, "completed_count":0 } } For important notes on response data, see [single merge request response notes](https://docs.gitlab.com/api/merge_requests/#single-merge-request-response-notes) . Create a to-do item ------------------- Manually creates a to-do item for the current user on a merge request. If a to-do item already exists for the user on that merge request, this endpoint returns status code `HTTP 304 Not Modified`. POST /projects/:id/merge_requests/:merge_request_iid/todo | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/27/todo" Example response: { "id": 113, "project": { "id": 3, "name": "GitLab CI/CD", "name_with_namespace": "GitLab Org / GitLab CI/CD", "path": "gitlab-ci", "path_with_namespace": "gitlab-org/gitlab-ci" }, "author": { "name": "Administrator", "username": "root", "id": 1, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "https://gitlab.example.com/root" }, "action_name": "marked", "target_type": "MergeRequest", "target": { "id": 27, "iid": 7, "project_id": 3, "title": "Et voluptas laudantium minus nihil recusandae ut accusamus earum aut non.", "description": "Veniam sunt nihil modi earum cumque illum delectus. Nihil ad quis distinctio quia. Autem eligendi at quibusdam repellendus.", "state": "merged", "created_at": "2016-06-17T07:48:04.330Z", "updated_at": "2016-07-01T11:14:15.537Z", "target_branch": "allow_regex_for_project_skip_ref", "source_branch": "backup", "upvotes": 0, "downvotes": 0, "author": { "name": "Jarret O'Keefe", "username": "francisca", "id": 14, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/a7fa515d53450023c83d62986d0658a8?s=80&d=identicon", "web_url": "https://gitlab.example.com/francisca", "discussion_locked": false }, "assignee": { "name": "Dr. Gabrielle Strosin", "username": "barrett.krajcik", "id": 4, "state": "active", "avatar_url": "http://www.gravatar.com/avatar/733005fcd7e6df12d2d8580171ccb966?s=80&d=identicon", "web_url": "https://gitlab.example.com/barrett.krajcik" }, "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": [{\ "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"\ }], "source_project_id": 3, "target_project_id": 3, "labels": [], "draft": false, "work_in_progress": false, "milestone": { "id": 27, "iid": 2, "project_id": 3, "title": "v1.0", "description": "Quis ea accusantium animi hic fuga assumenda.", "state": "active", "created_at": "2016-06-17T07:47:33.840Z", "updated_at": "2016-06-17T07:47:33.840Z", "due_date": null }, "merge_when_pipeline_succeeds": false, "merge_status": "unchecked", "detailed_merge_status": "not_open", "subscribed": true, "sha": "8888888888888888888888888888888888888888", "merge_commit_sha": null, "squash_commit_sha": null, "user_notes_count": 7, "changes_count": "1", "should_remove_source_branch": true, "force_remove_source_branch": false, "squash": false, "web_url": "http://example.com/my-group/my-project/merge_requests/1", "references": { "short": "!1", "relative": "!1", "full": "my-group/my-project!1" } }, "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ci/merge_requests/7", "body": "Et voluptas laudantium minus nihil recusandae ut accusamus earum aut non.", "state": "pending", "created_at": "2016-07-01T11:14:15.530Z" } Retrieve merge request diff versions ------------------------------------ Retrieve diff versions for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/versions | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | String | Yes | The ID of the project. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | For an explanation of the SHAs in the response, see [SHAs in the API response](https://docs.gitlab.com/api/merge_requests/#shas-in-the-api-response) . curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/versions" Example response: [{\ "id": 110,\ "head_commit_sha": "33e2ee8579fda5bc36accc9c6fbd0b4fefda9e30",\ "base_commit_sha": "eeb57dffe83deb686a60a71c16c32f71046868fd",\ "start_commit_sha": "eeb57dffe83deb686a60a71c16c32f71046868fd",\ "created_at": "2016-07-26T14:44:48.926Z",\ "merge_request_id": 105,\ "state": "collected",\ "real_size": "1",\ "patch_id_sha": "d504412d5b6e6739647e752aff8e468dde093f2f"\ }, {\ "id": 108,\ "head_commit_sha": "3eed087b29835c48015768f839d76e5ea8f07a24",\ "base_commit_sha": "eeb57dffe83deb686a60a71c16c32f71046868fd",\ "start_commit_sha": "eeb57dffe83deb686a60a71c16c32f71046868fd",\ "created_at": "2016-07-25T14:21:33.028Z",\ "merge_request_id": 105,\ "state": "collected",\ "real_size": "1",\ "patch_id_sha": "72c30d1f0115fc1d2bb0b29b24dc2982cbcdfd32"\ }] ### SHAs in the API response | SHA field | Purpose | | --- | --- | | `base_commit_sha` | The merge-base commit SHA between the source branch and the target branches. | | `head_commit_sha` | The HEAD commit of the source branch. | | `start_commit_sha` | The HEAD commit SHA of the target branch when this version of the diff was created. | Retrieve a merge request diff version ------------------------------------- History * `collapsed` and `too_large` response attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/199633) in GitLab 18.4. Retrieve a specific diff version for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/versions/:version_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | String | Yes | ID of the project. | | `merge_request_iid` | integer | Yes | Internal ID of the merge request. | | `version_id` | integer | Yes | ID of the merge request diff version. | | `unidiff` | boolean | No | Present diffs in the [unified diff](https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html)
format. Default is false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130610)
in GitLab 16.5. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `id` | integer | ID of the merge request diff version. | | `base_commit_sha` | string | Merge-base commit SHA between the source branch and the target branches. | | `commits` | object array | Commits in the merge request diff. | | `commits[].id` | string | ID of the commit. | | `commits[].short_id` | string | Short ID of the commit. | | `commits[].created_at` | datetime | Identical to the `committed_date` field. | | `commits[].parent_ids` | array | IDs of the parent commits. | | `commits[].title` | string | Commit title. | | `commits[].message` | string | Commit message. | | `commits[].author_name` | string | Commit author’s name. | | `commits[].author_email` | string | Commit author’s email address. | | `commits[].authored_date` | datetime | Commit authored date. | | `commits[].committer_name` | string | Name of the committer. | | `commits[].committer_email` | string | Email address of the committer. | | `commits[].committed_date` | datetime | Commit date. | | `commits[].trailers` | object | Git trailers parsed for the commit. Duplicate keys include the last value only. | | `commits[].extended_trailers` | object | Git trailers parsed for the commit. | | `commits[].web_url` | string | Web URL of the merge request. | | `created_at` | datetime | Creation date and time of the merge request. | | `diffs` | object array | Diffs in the merge request diff version. | | `diffs[].a_mode` | string | Old file mode of the file. | | `diffs[].b_mode` | string | New file mode of the file. | | `diffs[].collapsed` | boolean | File diffs are excluded but can be fetched on request. | | `diffs[].deleted_file` | boolean | File has been removed. | | `diffs[].diff` | string | Content of the diff. | | `diffs[].generated_file` | boolean | File is [marked as generated](https://docs.gitlab.com/user/project/merge_requests/changes/#collapse-generated-files)
. | | `diffs[].new_file` | boolean | File has been added. | | `diffs[].new_path` | string | New path of the file. | | `diffs[].old_path` | string | Old path of the file. | | `diffs[].renamed_file` | boolean | File has been renamed. | | `diffs[].too_large` | boolean | File diffs are excluded and cannot be retrieved. | | `head_commit_sha` | string | HEAD commit of the source branch. | | `merge_request_id` | integer | ID of the merge request. | | `patch_id_sha` | string | [Patch ID](https://git-scm.com/docs/git-patch-id)
for the merge request diff. | | `real_size` | string | Number of changes in the merge request diff. | | `start_commit_sha` | string | HEAD commit SHA of the target branch when this version of the diff was created. | | `state` | string | State of the merge request diff. Can be `collected`, `overflow`, `without_files`. Deprecated values: `timeout`, `overflow_commits_safe_size`, `overflow_diff_files_limit`, `overflow_diff_lines_limit`. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/versions/1" Example response: { "id": 110, "head_commit_sha": "33e2ee8579fda5bc36accc9c6fbd0b4fefda9e30", "base_commit_sha": "eeb57dffe83deb686a60a71c16c32f71046868fd", "start_commit_sha": "eeb57dffe83deb686a60a71c16c32f71046868fd", "created_at": "2016-07-26T14:44:48.926Z", "merge_request_id": 105, "state": "collected", "real_size": "1", "patch_id_sha": "d504412d5b6e6739647e752aff8e468dde093f2f", "commits": [{\ "id": "33e2ee8579fda5bc36accc9c6fbd0b4fefda9e30",\ "short_id": "33e2ee85",\ "parent_ids": [],\ "title": "Change year to 2018",\ "author_name": "Administrator",\ "author_email": "admin@example.com",\ "authored_date": "2016-07-26T17:44:29.000+03:00",\ "committer_name": "Administrator",\ "committer_email": "admin@example.com",\ "committed_date": "2016-07-26T17:44:29.000+03:00",\ "created_at": "2016-07-26T17:44:29.000+03:00",\ "message": "Change year to 2018",\ "trailers": {},\ "extended_trailers": {},\ "web_url": "https://gitlab.example.com/project/-/commit/33e2ee8579fda5bc36accc9c6fbd0b4fefda9e30"\ }, {\ "id": "aa24655de48b36335556ac8a3cd8bb521f977cbd",\ "short_id": "aa24655d",\ "parent_ids": [],\ "title": "Update LICENSE",\ "author_name": "Administrator",\ "author_email": "admin@example.com",\ "authored_date": "2016-07-25T17:21:53.000+03:00",\ "committer_name": "Administrator",\ "committer_email": "admin@example.com",\ "committed_date": "2016-07-25T17:21:53.000+03:00",\ "created_at": "2016-07-25T17:21:53.000+03:00",\ "message": "Update LICENSE",\ "trailers": {},\ "extended_trailers": {},\ "web_url": "https://gitlab.example.com/project/-/commit/aa24655de48b36335556ac8a3cd8bb521f977cbd"\ }, {\ "id": "3eed087b29835c48015768f839d76e5ea8f07a24",\ "short_id": "3eed087b",\ "parent_ids": [],\ "title": "Add license",\ "author_name": "Administrator",\ "author_email": "admin@example.com",\ "authored_date": "2016-07-25T17:21:20.000+03:00",\ "committer_name": "Administrator",\ "committer_email": "admin@example.com",\ "committed_date": "2016-07-25T17:21:20.000+03:00",\ "created_at": "2016-07-25T17:21:20.000+03:00",\ "message": "Add license",\ "trailers": {},\ "extended_trailers": {},\ "web_url": "https://gitlab.example.com/project/-/commit/3eed087b29835c48015768f839d76e5ea8f07a24"\ }], "diffs": [{\ "old_path": "LICENSE",\ "new_path": "LICENSE",\ "a_mode": "0",\ "b_mode": "100644",\ "diff": "@@ -0,0 +1,21 @@\n+The MIT License (MIT)\n+\n+Copyright (c) 2018 Administrator\n+\n+Permission is hereby granted, free of charge, to any person obtaining a copy\n+of this software and associated documentation files (the \"Software\"), to deal\n+in the Software without restriction, including without limitation the rights\n+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n+copies of the Software, and to permit persons to whom the Software is\n+furnished to do so, subject to the following conditions:\n+\n+The above copyright notice and this permission notice shall be included in all\n+copies or substantial portions of the Software.\n+\n+THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n+SOFTWARE.\n",\ "collapsed": false,\ "too_large": false,\ "new_file": true,\ "renamed_file": false,\ "deleted_file": false,\ "generated_file": false\ }] } Set a time estimate for a merge request --------------------------------------- Sets an estimated time of work for this merge request. POST /projects/:id/merge_requests/:merge_request_iid/time_estimate | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `duration` | string | Yes | The duration in human format, such as `3h30m`. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/time_estimate?duration=3h30m" Example response: { "human_time_estimate": "3h 30m", "human_total_time_spent": null, "time_estimate": 12600, "total_time_spent": 0 } Reset the time estimate for a merge request ------------------------------------------- Resets the estimated time for this merge request to 0 seconds. POST /projects/:id/merge_requests/:merge_request_iid/reset_time_estimate | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of a project’s merge request. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/reset_time_estimate" Example response: { "human_time_estimate": null, "human_total_time_spent": null, "time_estimate": 0, "total_time_spent": 0 } Add spent time for a merge request ---------------------------------- Adds spent time for this merge request. POST /projects/:id/merge_requests/:merge_request_iid/add_spent_time | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | | `duration` | string | Yes | The duration in human format, such as `3h30m` | | `summary` | string | No | A summary of how the time was spent. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/add_spent_time?duration=1h" Example response: { "human_time_estimate": null, "human_total_time_spent": "1h", "time_estimate": 0, "total_time_spent": 3600 } Reset spent time for a merge request ------------------------------------ Resets the total spent time for this merge request to 0 seconds. POST /projects/:id/merge_requests/:merge_request_iid/reset_spent_time | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of a project’s merge request. | curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/reset_spent_time" Example response: { "human_time_estimate": null, "human_total_time_spent": null, "time_estimate": 0, "total_time_spent": 0 } Retrieve time tracking statistics --------------------------------- Retrieve time tracking statistics for a merge request. GET /projects/:id/merge_requests/:merge_request_iid/time_stats | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | The ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `merge_request_iid` | integer | Yes | The internal ID of the merge request. | curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/time_stats" Example response: { "human_time_estimate": "2h", "human_total_time_spent": "1h", "time_estimate": 7200, "total_time_spent": 3600 } Approvals --------- For approvals, see [merge request approvals](https://docs.gitlab.com/api/merge_request_approvals/) . List merge request state events ------------------------------- To track which state was set, who did it, and when it happened, see the [resource state events API](https://docs.gitlab.com/api/resource_state_events/#merge-requests) . Troubleshooting --------------- ### Empty API fields for new merge requests When you create a merge request, the `diff_refs` and `changes_count` fields are initially empty. These fields populate asynchronously after you create the merge request. For more information, see [issue 386562](https://gitlab.com/gitlab-org/gitlab/-/issues/386562) , and the [related discussion](https://forum.gitlab.com/t/diff-refs-empty-after-mr-is-created/78975) in the GitLab forums. --- # GraphQL examples | GitLab Docs * * * GraphQL examples ================ GraphQL examples are available for you to test and modify. * [Audit event streaming for instances](https://docs.gitlab.com/api/graphql/audit_event_streaming_instances/) * [Audit event streaming for groups](https://docs.gitlab.com/api/graphql/audit_event_streaming_groups/) * [Set up an audit report](https://docs.gitlab.com/api/graphql/audit_report/) * [Identify issue boards](https://docs.gitlab.com/api/graphql/sample_issue_boards/) * [List branch rules for a project](https://docs.gitlab.com/api/graphql/branch_rules/) * [Query users](https://docs.gitlab.com/api/graphql/users_example/) * [Use custom emoji](https://docs.gitlab.com/api/graphql/custom_emoji/) * [Migrate epic APIs to work items](https://docs.gitlab.com/api/graphql/epic_work_items_api_migration_guide/) * [Retrieve GitLab Duo and SDLC trend data](https://docs.gitlab.com/api/graphql/duo_and_sdlc_trends/) --- # Tags API | GitLab Docs * * * Tags API ======== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [Git tags](https://docs.gitlab.com/user/project/repository/tags/) . This API also returns X.509 signature information from signed tags. List all project repository tags -------------------------------- History * `created_at` response attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/451011) in GitLab 16.11. Lists all repository tags from a project, sorted by update date and time in descending order. If the repository is publicly accessible, authentication (`--header "PRIVATE-TOKEN: "`) is not required. GET /projects/:id/repository/tags Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path](https://docs.gitlab.com/api/rest/#namespaced-paths)
of the project. | | `order_by` | string | No | Return tags ordered by `name`, `updated`, or `version`. `version` sorts by semantic version number. Default is `updated`. | | `page` | integer | No | Current page number for pagination. Default is `1`. | | `page_token` | string | No | Name of tag to start the pagination from. Used for keyset pagination. | | `search` | string | No | Return a list of tags matching the search criteria. You can use `^term` and `term$` to find tags that begin and end with `term`. No other regular expressions are supported. | | `sort` | string | No | Return tags sorted in `asc` or `desc` order. Default is `desc`. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `commit` | object | Commit information associated with the tag. | | `commit.author_email` | string | Email address of the commit author. | | `commit.author_name` | string | Name of the commit author. | | `commit.authored_date` | string | Date when the commit was authored in ISO 8601 format. | | `commit.committed_date` | string | Date when the commit was committed in ISO 8601 format. | | `commit.committer_email` | string | Email address of the committer. | | `commit.committer_name` | string | Name of the committer. | | `commit.created_at` | string | Date when the commit was created in ISO 8601 format. | | `commit.id` | string | Full SHA of the commit. | | `commit.message` | string | Commit message. | | `commit.parent_ids` | array | Array of parent commit SHAs. | | `commit.short_id` | string | Short SHA of the commit. | | `commit.title` | string | Title of the commit. | | `created_at` | string | Date when the tag was created in ISO 8601 format. | | `message` | string | Tag message. | | `name` | string | Name of the tag. | | `protected` | boolean | If `true`, the tag is protected. | | `release` | object | Release information associated with the tag. | | `release.description` | string | Description of the release. | | `release.tag_name` | string | Tag name of the release. | | `target` | string | SHA that the tag points to. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/repository/tags" Example response: [\ {\ "commit": {\ "id": "2695effb5807a22ff3d138d593fd856244e155e7",\ "short_id": "2695effb",\ "title": "Initial commit",\ "created_at": "2017-07-26T11:08:53.000+02:00",\ "parent_ids": [\ "2a4b78934375d7f53875269ffd4f45fd83a84ebe"\ ],\ "message": "Initial commit",\ "author_name": "John Smith",\ "author_email": "john@example.com",\ "authored_date": "2012-05-28T04:42:42-07:00",\ "committer_name": "Jack Smith",\ "committer_email": "jack@example.com",\ "committed_date": "2012-05-28T04:42:42-07:00"\ },\ "release": {\ "tag_name": "1.0.0",\ "description": "Amazing release. Wow"\ },\ "name": "v1.0.0",\ "target": "2695effb5807a22ff3d138d593fd856244e155e7",\ "message": null,\ "protected": true,\ "created_at": "2017-07-26T11:08:53.000+02:00"\ }\ ] Retrieve a single repository tag -------------------------------- History * `created_at` response attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/451011) in GitLab 16.11. Retrieves a repository tag with the specified name. This endpoint can be accessed without authentication if the repository is publicly accessible. GET /projects/:id/repository/tags/:tag_name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | Yes | Name of a tag. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `commit` | object | Commit information associated with the tag. | | `commit.author_email` | string | Email address of the commit author. | | `commit.author_name` | string | Name of the commit author. | | `commit.authored_date` | string | Date when the commit was authored in ISO 8601 format. | | `commit.committed_date` | string | Date when the commit was committed in ISO 8601 format. | | `commit.committer_email` | string | Email address of the committer. | | `commit.committer_name` | string | Name of the committer. | | `commit.created_at` | string | Date when the commit was created in ISO 8601 format. | | `commit.id` | string | Full SHA of the commit. | | `commit.message` | string | Commit message. | | `commit.parent_ids` | array | Array of parent commit SHAs. | | `commit.short_id` | string | Short SHA of the commit. | | `commit.title` | string | Title of the commit. | | `created_at` | string | Date when the tag was created in ISO 8601 format. | | `message` | string | Tag message. | | `name` | string | Name of the tag. | | `protected` | boolean | If `true`, the tag is protected. | | `release` | object | Release information associated with the tag. | | `target` | string | SHA that the tag points to. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/repository/tags/v1.0.0" Example response: { "name": "v5.0.0", "message": null, "target": "60a8ff033665e1207714d6670fcd7b65304ec02f", "commit": { "id": "60a8ff033665e1207714d6670fcd7b65304ec02f", "short_id": "60a8ff03", "title": "Initial commit", "created_at": "2017-07-26T11:08:53.000+02:00", "parent_ids": [\ "f61c062ff8bcbdb00e0a1b3317a91aed6ceee06b"\ ], "message": "v5.0.0\n", "author_name": "Arthur Verschaeve", "author_email": "contact@arthurverschaeve.be", "authored_date": "2015-02-01T21:56:31.000+01:00", "committer_name": "Arthur Verschaeve", "committer_email": "contact@arthurverschaeve.be", "committed_date": "2015-02-01T21:56:31.000+01:00" }, "release": null, "protected": false, "created_at": "2017-07-26T11:08:53.000+02:00" } Create a new tag ---------------- History * `created_at` response attribute [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/451011) in GitLab 16.11. Creates a new tag in the repository that points to the supplied reference. POST /projects/:id/repository/tags Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `ref` | string | Yes | Create a tag from a commit SHA, another tag name, or branch name. | | `tag_name` | string | Yes | Name of a tag. | | `message` | string | No | Create an annotated tag. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `commit` | object | Commit information associated with the tag. | | `commit.author_email` | string | Email address of the commit author. | | `commit.author_name` | string | Name of the commit author. | | `commit.authored_date` | string | Date when the commit was authored in ISO 8601 format. | | `commit.committed_date` | string | Date when the commit was committed in ISO 8601 format. | | `commit.committer_email` | string | Email address of the committer. | | `commit.committer_name` | string | Name of the committer. | | `commit.created_at` | string | Date when the commit was created in ISO 8601 format. | | `commit.id` | string | Full SHA of the commit. | | `commit.message` | string | Commit message. | | `commit.parent_ids` | array | Array of parent commit SHAs. | | `commit.short_id` | string | Short SHA of the commit. | | `commit.title` | string | Title of the commit. | | `created_at` | string | Date when the tag was created in ISO 8601 format. | | `message` | string | Tag message. | | `name` | string | Name of the tag. | | `protected` | boolean | If `true`, the tag is protected. | | `release` | object | Release information associated with the tag. | | `target` | string | SHA that the tag points to. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/5/repository/tags?tag_name=test&ref=main" Example response: { "commit": { "id": "2695effb5807a22ff3d138d593fd856244e155e7", "short_id": "2695effb", "title": "Initial commit", "created_at": "2017-07-26T11:08:53.000+02:00", "parent_ids": [\ "2a4b78934375d7f53875269ffd4f45fd83a84ebe"\ ], "message": "Initial commit", "author_name": "John Smith", "author_email": "john@example.com", "authored_date": "2012-05-28T04:42:42-07:00", "committer_name": "Jack Smith", "committer_email": "jack@example.com", "committed_date": "2012-05-28T04:42:42-07:00" }, "release": null, "name": "v1.0.0", "target": "2695effb5807a22ff3d138d593fd856244e155e7", "message": null, "protected": false, "created_at": null } The type of tag created determines the contents of `created_at`, `target` and `message`: * For annotated tags: * `created_at` contains the timestamp of tag creation. * `message` contains the annotation. * `target` contains the tag object’s ID. * For lightweight tags: * `created_at` is null. * `message` is null. * `target` contains the commit ID. Errors return status code `405` with an explanatory error message. Delete a tag ------------ Deletes a repository tag with the specified name. DELETE /projects/:id/repository/tags/:tag_name Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | Yes | Name of a tag. | Retrieve X.509 signature of a tag --------------------------------- Retrieves the [X.509 signature from a tag](https://docs.gitlab.com/user/project/repository/signed_commits/x509/) , if it is signed. Unsigned tags return a `404 Not Found` response. GET /projects/:id/repository/tags/:tag_name/signature Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer or string | Yes | ID or [URL-encoded path of the project](https://docs.gitlab.com/api/rest/#namespaced-paths)
. | | `tag_name` | string | Yes | Name of a tag. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `signature_type` | string | Type of signature (`X509`). | | `verification_status` | string | Verification status of the signature. | | `x509_certificate` | object | X.509 certificate information. | | `x509_certificate.certificate_status` | string | Status of the certificate. | | `x509_certificate.email` | string | Email address from the certificate. | | `x509_certificate.id` | integer | ID of the certificate. | | `x509_certificate.serial_number` | integer | Serial number of the certificate. | | `x509_certificate.subject` | string | Subject of the certificate. | | `x509_certificate.subject_key_identifier` | string | Subject key identifier of the certificate. | | `x509_certificate.x509_issuer` | object | Issuer information of the certificate. | | `x509_certificate.x509_issuer.crl_url` | string | Certificate revocation list URL. | | `x509_certificate.x509_issuer.id` | integer | ID of the issuer. | | `x509_certificate.x509_issuer.subject` | string | Subject of the issuer. | | `x509_certificate.x509_issuer.subject_key_identifier` | string | Subject key identifier of the issuer. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/projects/1/repository/tags/v1.1.1/signature" Example response if tag is X.509 signed: { "signature_type": "X509", "verification_status": "unverified", "x509_certificate": { "id": 1, "subject": "CN=gitlab@example.org,OU=Example,O=World", "subject_key_identifier": "BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC", "email": "gitlab@example.org", "serial_number": 278969561018901340486471282831158785578, "certificate_status": "good", "x509_issuer": { "id": 1, "subject": "CN=PKI,OU=Example,O=World", "subject_key_identifier": "AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB", "crl_url": "http://example.com/pki.crl" } } } Example response if tag is unsigned: { "message": "404 GPG Signature Not Found" } --- # Snippets API | GitLab Docs * * * Snippets API ============ * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated Use this API to manage [snippets](https://docs.gitlab.com/user/snippets/) . Related APIs exist for [project snippets](https://docs.gitlab.com/api/project_snippets/) and [moving snippets between storages](https://docs.gitlab.com/api/snippet_repository_storage_moves/) . List all snippets for current user ---------------------------------- Get a list of the current user’s snippets. GET /snippets Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `created_after` | datetime | No | Return snippets created after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | No | Return snippets created before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `page` | integer | No | Page to retrieve. | | `per_page` | integer | No | Number of snippets to return per page. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author` | object | User object representing snippet author. | | `created_at` | string | Date and time when snippet was created. | | `description` | string | Description of snippet. | | `file_name` | string | Name of snippet file. | | `id` | integer | ID of snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of import. | | `project_id` | integer | ID of associated project. For personal snippets, `null`. | | `raw_url` | string | URL to raw snippet content. | | `title` | string | Title of snippet. | | `updated_at` | string | Date and time when snippet was last updated. | | `visibility` | string | Visibility level of snippet. | | `web_url` | string | URL to snippet in GitLab UI. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets" Example response: [\ {\ "id": 42,\ "title": "Voluptatem iure ut qui aut et consequatur quaerat.",\ "file_name": "mclaughlin.rb",\ "description": null,\ "visibility": "internal",\ "imported": false,\ "imported_from": "none",\ "author": {\ "id": 22,\ "name": "User 0",\ "username": "user0",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/52e4ce24a915fb7e51e1ad3b57f4b00a?s=80&d=identicon",\ "web_url": "http://example.com/user0"\ },\ "updated_at": "2018-09-18T01:12:26.383Z",\ "created_at": "2018-09-18T01:12:26.383Z",\ "project_id": null,\ "web_url": "http://example.com/snippets/42",\ "raw_url": "http://example.com/snippets/42/raw"\ },\ {\ "id": 41,\ "title": "Ut praesentium non et atque.",\ "file_name": "ondrickaemard.rb",\ "description": null,\ "visibility": "internal",\ "imported": false,\ "imported_from": "none",\ "author": {\ "id": 22,\ "name": "User 0",\ "username": "user0",\ "state": "active",\ "avatar_url": "https://www.gravatar.com/avatar/52e4ce24a915fb7e51e1ad3b57f4b00a?s=80&d=identicon",\ "web_url": "http://example.com/user0"\ },\ "updated_at": "2018-09-18T01:12:26.360Z",\ "created_at": "2018-09-18T01:12:26.360Z",\ "project_id": 1,\ "web_url": "http://example.com/gitlab-org/gitlab-test/snippets/41",\ "raw_url": "http://example.com/gitlab-org/gitlab-test/snippets/41/raw"\ }\ ] Retrieve a snippet ------------------ Retrieves a specified snippet. GET /snippets/:id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | ID of snippet to retrieve. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author` | object | User object representing snippet author. | | `created_at` | string | Date and time when snippet was created. | | `description` | string | Description of snippet. | | `expires_at` | string | Date and time when snippet expires. | | `file_name` | string | Name of snippet file. | | `http_url_to_repo` | string | HTTP URL to snippet repository. | | `id` | integer | ID of snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of import. | | `project_id` | integer | ID of associated project. For personal snippets, `null`. | | `raw_url` | string | URL to raw snippet content. | | `ssh_url_to_repo` | string | SSH URL to snippet repository. | | `title` | string | Title of snippet. | | `updated_at` | string | Date and time when snippet was last updated. | | `visibility` | string | Visibility level of snippet. | | `web_url` | string | URL to snippet in GitLab UI. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/1" Example response: { "id": 1, "title": "test", "file_name": "add.rb", "description": "Ruby test snippet", "visibility": "private", "imported": false, "imported_from": "none", "author": { "id": 1, "username": "john_smith", "email": "john@example.com", "name": "John Smith", "state": "active", "created_at": "2012-05-23T08:00:58Z" }, "expires_at": null, "updated_at": "2012-06-28T10:52:04Z", "created_at": "2012-06-28T10:52:04Z", "project_id": null, "web_url": "http://example.com/snippets/1", "raw_url": "http://example.com/snippets/1/raw" } Single snippet contents ----------------------- Get a single snippet’s raw contents. GET /snippets/:id/raw Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | ID of snippet to retrieve. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the raw content of the snippet. Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/1/raw" Example response: Hello World snippet Snippet repository file content ------------------------------- Returns the raw file content as plain text. GET /snippets/:id/files/:ref/:file_path/raw Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `file_path` | string | Yes | URL-encoded path to file. | | `id` | integer | Yes | ID of snippet to retrieve. | | `ref` | string | Yes | Reference to a tag, branch or commit. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the raw file content. Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/1/files/main/snippet%2Erb/raw" Example response: Hello World snippet Create a snippet ---------------- Creates a new snippet. User must have permission to create new snippets. POST /snippets Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `files:content` | string | Yes | Content of snippet file. | | `files:file_path` | string | Yes | File path of snippet file. | | `title` | string | Yes | Title of a snippet. | | `content` | string | No | Deprecated: Use `files` instead. Content of a snippet. | | `description` | string | No | Description of a snippet. | | `file_name` | string | No | Deprecated: Use `files` instead. Name of a snippet file. | | `files` | array of hashes | No | An array of snippet files. | | `visibility` | string | No | Visibility level for the snippet. Possible values: `public`, `private`, and `internal`. On GitLab.com, the `internal` value is not available. | If successful, returns [`201 Created`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author` | object | User object representing snippet author. | | `created_at` | string | Date and time when snippet was created. | | `description` | string | Description of snippet. | | `expires_at` | string | Date and time when snippet expires. | | `file_name` | string | Name of snippet file. | | `files` | array | Array of snippet files. | | `http_url_to_repo` | string | HTTP URL to snippet repository. | | `id` | integer | ID of snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of import. | | `project_id` | integer | ID of associated project. For personal snippets, `null`. | | `raw_url` | string | URL to raw snippet content. | | `ssh_url_to_repo` | string | SSH URL to snippet repository. | | `title` | string | Title of snippet. | | `updated_at` | string | Date and time when snippet was last updated. | | `visibility` | string | Visibility level of snippet. | | `web_url` | string | URL to snippet in GitLab UI. | Example request: curl --request POST "https://gitlab.example.com/api/v4/snippets" \ --header 'Content-Type: application/json' \ --header "PRIVATE-TOKEN: " \ -d @snippet.json `snippet.json` used in the previous example request: { "title": "This is a snippet", "description": "Hello World snippet", "visibility": "internal", "files": [\ {\ "content": "Hello world",\ "file_path": "test.txt"\ }\ ] } Example response: { "id": 1, "title": "This is a snippet", "description": "Hello World snippet", "visibility": "internal", "imported": false, "imported_from": "none", "author": { "id": 1, "username": "john_smith", "email": "john@example.com", "name": "John Smith", "state": "active", "created_at": "2012-05-23T08:00:58Z" }, "expires_at": null, "updated_at": "2012-06-28T10:52:04Z", "created_at": "2012-06-28T10:52:04Z", "project_id": null, "web_url": "http://example.com/snippets/1", "raw_url": "http://example.com/snippets/1/raw", "ssh_url_to_repo": "ssh://git@gitlab.example.com:snippets/1.git", "http_url_to_repo": "https://gitlab.example.com/snippets/1.git", "file_name": "test.txt", "files": [\ {\ "path": "text.txt",\ "raw_url": "https://gitlab.example.com/-/snippets/1/raw/main/renamed.md"\ }\ ] } Update snippet -------------- Update an existing snippet. User must have permission to change an existing snippet. PUT /snippets/:id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | ID of snippet to update. | | `files:action` | string | Yes | Type of action to perform on file, one of: `create`, `update`, `delete`, `move`. | | `content` | string | No | Deprecated: Use `files` instead. Content of a snippet. | | `description` | string | No | Description of a snippet. | | `file_name` | string | No | Deprecated: Use `files` instead. Name of a snippet file. | | `files` | array of hashes | Conditionally | An array of snippet files. Required when updating snippets with multiple files. | | `files:content` | string | No | Content of snippet file. | | `files:file_path` | string | No | File path of snippet file. | | `files:previous_path` | string | No | Previous path of snippet file. | | `title` | string | No | Title of a snippet. | | `visibility` | string | No | Visibility level for the snippet. Possible values: `public`, `private`, and `internal`. On GitLab.com, the `internal` value is not available. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author` | object | User object representing snippet author. | | `created_at` | string | Date and time when snippet was created. | | `description` | string | Description of snippet. | | `expires_at` | string | Date and time when snippet expires. | | `file_name` | string | Name of snippet file. | | `files` | array | Array of snippet files. | | `http_url_to_repo` | string | HTTP URL to snippet repository. | | `id` | integer | ID of snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of import. | | `project_id` | integer | ID of associated project. For personal snippets, `null`. | | `raw_url` | string | URL to raw snippet content. | | `ssh_url_to_repo` | string | SSH URL to snippet repository. | | `title` | string | Title of snippet. | | `updated_at` | string | Date and time when snippet was last updated. | | `visibility` | string | Visibility level of snippet. | | `web_url` | string | URL to snippet in GitLab UI. | Example request: curl --request PUT "https://gitlab.example.com/api/v4/snippets/1" \ --header 'Content-Type: application/json' \ --header "PRIVATE-TOKEN: " \ -d @snippet.json `snippet.json` used in the previous example request: { "title": "foo", "files": [\ {\ "action": "move",\ "previous_path": "test.txt",\ "file_path": "renamed.md"\ }\ ] } Example response: { "id": 1, "title": "test", "description": "description of snippet", "visibility": "internal", "imported": false, "imported_from": "none", "author": { "id": 1, "username": "john_smith", "email": "john@example.com", "name": "John Smith", "state": "active", "created_at": "2012-05-23T08:00:58Z" }, "expires_at": null, "updated_at": "2012-06-28T10:52:04Z", "created_at": "2012-06-28T10:52:04Z", "project_id": null, "web_url": "http://example.com/snippets/1", "raw_url": "http://example.com/snippets/1/raw", "ssh_url_to_repo": "ssh://git@gitlab.example.com:snippets/1.git", "http_url_to_repo": "https://gitlab.example.com/snippets/1.git", "file_name": "renamed.md", "files": [\ {\ "path": "renamed.md",\ "raw_url": "https://gitlab.example.com/-/snippets/1/raw/main/renamed.md"\ }\ ] } Delete snippet -------------- Delete an existing snippet. DELETE /snippets/:id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | ID of snippet to delete. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/1" The following are possible return codes: | Code | Description | | --- | --- | | `204` | Delete was successful. No data is returned. | | `404` | Snippet wasn’t found. | List all public snippets ------------------------ List all public snippets. GET /snippets/public Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `created_after` | datetime | No | Return snippets created after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | No | Return snippets created before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `page` | integer | No | Page to retrieve. | | `per_page` | integer | No | Number of snippets to return per page. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author` | object | User object representing snippet author. | | `created_at` | string | Date and time when snippet was created. | | `description` | string | Description of snippet. | | `file_name` | string | Name of snippet file. | | `id` | integer | ID of snippet. | | `project_id` | integer | ID of associated project. For personal snippets, `null`. | | `raw_url` | string | URL to raw snippet content. | | `title` | string | Title of snippet. | | `updated_at` | string | Date and time when snippet was last updated. | | `visibility` | string | Visibility level of snippet. | | `web_url` | string | URL to snippet in GitLab UI. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/public?per_page=2&page=1" Example response: [\ {\ "author": {\ "avatar_url": "http://www.gravatar.com/avatar/edaf55a9e363ea263e3b981d09e0f7f7?s=80&d=identicon",\ "id": 12,\ "name": "Libby Rolfson",\ "state": "active",\ "username": "elton_wehner",\ "web_url": "http://example.com/elton_wehner"\ },\ "created_at": "2016-11-25T16:53:34.504Z",\ "file_name": "oconnerrice.rb",\ "id": 49,\ "title": "Ratione cupiditate et laborum temporibus.",\ "updated_at": "2016-11-25T16:53:34.504Z",\ "project_id": null,\ "web_url": "http://example.com/snippets/49",\ "raw_url": "http://example.com/snippets/49/raw"\ },\ {\ "author": {\ "avatar_url": "http://www.gravatar.com/avatar/36583b28626de71061e6e5a77972c3bd?s=80&d=identicon",\ "id": 16,\ "name": "Llewellyn Flatley",\ "state": "active",\ "username": "adaline",\ "web_url": "http://example.com/adaline"\ },\ "created_at": "2016-11-25T16:53:34.479Z",\ "file_name": "muellershields.rb",\ "id": 48,\ "title": "Minus similique nesciunt vel fugiat qui ullam sunt.",\ "updated_at": "2016-11-25T16:53:34.479Z",\ "project_id": null,\ "web_url": "http://example.com/snippets/48",\ "raw_url": "http://example.com/snippets/49/raw",\ "visibility": "public"\ }\ ] List all snippets ----------------- History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/419640) in GitLab 16.3. List all snippets the current user has access to. Users with the Administrator or Auditor access levels can see all snippets (both personal and project). GET /snippets/all Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `created_after` | datetime | No | Return snippets created after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | No | Return snippets created before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `page` | integer | No | Page to retrieve. | | `per_page` | integer | No | Number of snippets to return per page. | | `repository_storage` | string | No | Filter by repository storage used by snippet _(administrators only)_. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/419640)
in GitLab 16.3. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `author` | object | User object representing snippet author. | | `created_at` | string | Date and time when snippet was created. | | `description` | string | Description of snippet. | | `file_name` | string | Name of snippet file. | | `files` | array | Array of snippet files. | | `id` | integer | ID of snippet. | | `imported` | boolean | If `true`, the snippet was imported. | | `imported_from` | string | Source of import. | | `project_id` | integer | ID of associated project. For personal snippets, `null`. | | `raw_url` | string | URL to raw snippet content. | | `repository_storage` | string | Repository storage used by snippet. | | `title` | string | Title of snippet. | | `updated_at` | string | Date and time when snippet was last updated. | | `visibility` | string | Visibility level of snippet. | | `web_url` | string | URL to snippet in GitLab UI. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/all?per_page=2&page=1" Example response: [\ {\ "id": 113,\ "title": "Internal Project Snippet",\ "description": null,\ "visibility": "internal",\ "imported": false,\ "imported_from": "none",\ "author": {\ "id": 17,\ "username": "tim_kreiger",\ "name": "Tim Kreiger",\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/edaf55a9e363ea263e3b981d09e0f7f7?s=80&d=identicon",\ "web_url": "http://example.com/tim_kreiger"\ },\ "created_at": "2023-08-03T10:21:02.480Z",\ "updated_at": "2023-08-03T10:21:02.480Z",\ "project_id": 35,\ "web_url": "http://example.com/tim_kreiger/internal_project/-/snippets/113",\ "raw_url": "http://example.com/tim_kreiger/internal_project/-/snippets/113/raw",\ "file_name": "",\ "files": [],\ "repository_storage": "default"\ },\ {\ "id": 112,\ "title": "Private Personal Snippet",\ "description": null,\ "visibility": "private",\ "imported": false,\ "imported_from": "none",\ "author": {\ "id": 1,\ "username": "root",\ "name": "Administrator",\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/edaf55a9e363ea263e3b981d09e0f7f7?s=80&d=identicon",\ "web_url": "http://example.com/root"\ },\ "created_at": "2023-08-03T10:20:59.994Z",\ "updated_at": "2023-08-03T10:20:59.994Z",\ "project_id": null,\ "web_url": "http://example.com/-/snippets/112",\ "raw_url": "http://example.com/-/snippets/112/raw",\ "file_name": "",\ "files": [],\ "repository_storage": "default"\ },\ {\ "id": 111,\ "title": "Public Personal Snippet",\ "description": null,\ "visibility": "public",\ "imported": false,\ "imported_from": "none",\ "author": {\ "id": 17,\ "username": "tim_kreiger",\ "name": "Tim Kreiger",\ "state": "active",\ "avatar_url": "http://www.gravatar.com/avatar/edaf55a9e363ea263e3b981d09e0f7f7?s=80&d=identicon",\ "web_url": "http://example.com/tim_kreiger"\ },\ "created_at": "2023-08-03T10:21:01.312Z",\ "updated_at": "2023-08-03T10:21:01.312Z",\ "project_id": null,\ "web_url": "http://example.com/-/snippets/111",\ "raw_url": "http://example.com/-/snippets/111/raw",\ "file_name": "",\ "files": [],\ "repository_storage": "default"\ }\ ] Get user agent details ---------------------- Available only for administrators. GET /snippets/:id/user_agent_detail Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | ID of snippet. | If successful, returns [`200 OK`](https://docs.gitlab.com/api/rest/troubleshooting/#status-codes) and the following response attributes: | Attribute | Type | Description | | --- | --- | --- | | `akismet_submitted` | boolean | If `true`, the details were submitted to Akismet. | | `ip_address` | string | IP address used to create snippet. | | `user_agent` | string | User agent string used to create snippet. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/1/user_agent_detail" Example response: { "user_agent": "AppleWebKit/537.36", "ip_address": "127.0.0.1", "akismet_submitted": false } --- # Snippet repository storage moves API | GitLab Docs * * * Snippet repository storage moves API ==================================== * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated Use this API to manage [snippet repository storage moves](https://docs.gitlab.com/administration/operations/moving_repositories/) . This API can help you, for example, [migrate to Gitaly Cluster (Praefect)](https://docs.gitlab.com/administration/gitaly/praefect/#migrate-to-gitaly-cluster-praefect) . As snippet repository storage moves are processed, they transition through different states. Values of `state` are: * `initial`: The record has been created but the background job has not yet been scheduled. * `scheduled`: The background job has been scheduled. * `started`: The snippet repository is being copied to the destination storage. * `replicated`: The snippet has been moved. * `failed`: The snippet repository failed to copy or the checksum did not match. * `finished`: The snippet has been moved and the repository on the source storage has been deleted. * `cleanup failed`: The snippet has been moved but the repository on the source storage could not be deleted. To ensure data integrity, snippets are put in a temporary read-only state for the duration of the move. During this time, users receive a `The repository is temporarily read-only. Please try again later.` message if they try to push new commits. This API requires you to [authenticate yourself](https://docs.gitlab.com/api/rest/authentication/) as an administrator. For other repository types see: * [Project repository storage moves API](https://docs.gitlab.com/api/project_repository_storage_moves/) . * [Group repository storage moves API](https://docs.gitlab.com/api/group_repository_storage_moves/) . List all snippet repository storage moves ----------------------------------------- Lists all snippet repository storage moves. GET /snippet_repository_storage_moves By default, `GET` requests return 20 results at a time because the API results are [paginated](https://docs.gitlab.com/api/rest/#pagination) . Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippet_repository_storage_moves" Example response: [\ {\ "id": 1,\ "created_at": "2020-05-07T04:27:17.234Z",\ "state": "scheduled",\ "source_storage_name": "default",\ "destination_storage_name": "storage2",\ "snippet": {\ "id": 65,\ "title": "Test Snippet",\ "description": null,\ "visibility": "internal",\ "updated_at": "2020-12-01T11:15:50.385Z",\ "created_at": "2020-12-01T11:15:50.385Z",\ "project_id": null,\ "web_url": "https://gitlab.example.com/-/snippets/65",\ "raw_url": "https://gitlab.example.com/-/snippets/65/raw",\ "ssh_url_to_repo": "ssh://user@gitlab.example.com/snippets/65.git",\ "http_url_to_repo": "https://gitlab.example.com/snippets/65.git"\ }\ }\ ] List all repository storage moves for a snippet ----------------------------------------------- Lists all repository storage moves for a specified snippet. GET /snippets/:snippet_id/repository_storage_moves By default, `GET` requests return 20 results at a time because the API results are [paginated](https://docs.gitlab.com/api/rest/#pagination) . Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `snippet_id` | integer | yes | ID of the snippet. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/1/repository_storage_moves" Example response: [\ {\ "id": 1,\ "created_at": "2020-05-07T04:27:17.234Z",\ "state": "scheduled",\ "source_storage_name": "default",\ "destination_storage_name": "storage2",\ "snippet": {\ "id": 65,\ "title": "Test Snippet",\ "description": null,\ "visibility": "internal",\ "updated_at": "2020-12-01T11:15:50.385Z",\ "created_at": "2020-12-01T11:15:50.385Z",\ "project_id": null,\ "web_url": "https://gitlab.example.com/-/snippets/65",\ "raw_url": "https://gitlab.example.com/-/snippets/65/raw",\ "ssh_url_to_repo": "ssh://user@gitlab.example.com/snippets/65.git",\ "http_url_to_repo": "https://gitlab.example.com/snippets/65.git"\ }\ }\ ] Retrieve a snippet repository storage move ------------------------------------------ Retrieves a specified snippet repository storage move. GET /snippet_repository_storage_moves/:repository_storage_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `repository_storage_id` | integer | yes | ID of the snippet repository storage move. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippet_repository_storage_moves/1" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "snippet": { "id": 65, "title": "Test Snippet", "description": null, "visibility": "internal", "updated_at": "2020-12-01T11:15:50.385Z", "created_at": "2020-12-01T11:15:50.385Z", "project_id": null, "web_url": "https://gitlab.example.com/-/snippets/65", "raw_url": "https://gitlab.example.com/-/snippets/65/raw", "ssh_url_to_repo": "ssh://user@gitlab.example.com/snippets/65.git", "http_url_to_repo": "https://gitlab.example.com/snippets/65.git" } } Retrieve a repository storage move for a snippet ------------------------------------------------ Retrieves a repository storage move for a specified snippet. GET /snippets/:snippet_id/repository_storage_moves/:repository_storage_id Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `snippet_id` | integer | yes | ID of the snippet. | | `repository_storage_id` | integer | yes | ID of the snippet repository storage move. | Example request: curl --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/snippets/1/repository_storage_moves/1" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "snippet": { "id": 65, "title": "Test Snippet", "description": null, "visibility": "internal", "updated_at": "2020-12-01T11:15:50.385Z", "created_at": "2020-12-01T11:15:50.385Z", "project_id": null, "web_url": "https://gitlab.example.com/-/snippets/65", "raw_url": "https://gitlab.example.com/-/snippets/65/raw", "ssh_url_to_repo": "ssh://user@gitlab.example.com/snippets/65.git", "http_url_to_repo": "https://gitlab.example.com/snippets/65.git" } } Schedule a repository storage move for a snippet ------------------------------------------------ Schedules a repository storage move for a specified snippet. POST /snippets/:snippet_id/repository_storage_moves Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `snippet_id` | integer | yes | ID of the snippet. | | `destination_storage_name` | string | no | Name of the destination storage shard. The storage is selected [automatically based on storage weights](https://docs.gitlab.com/administration/repository_storage_paths/#configure-where-new-repositories-are-stored)
if not provided. | Example request: curl --request POST --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"destination_storage_name":"storage2"}' \ --url "https://gitlab.example.com/api/v4/snippets/1/repository_storage_moves" Example response: { "id": 1, "created_at": "2020-05-07T04:27:17.234Z", "state": "scheduled", "source_storage_name": "default", "destination_storage_name": "storage2", "snippet": { "id": 65, "title": "Test Snippet", "description": null, "visibility": "internal", "updated_at": "2020-12-01T11:15:50.385Z", "created_at": "2020-12-01T11:15:50.385Z", "project_id": null, "web_url": "https://gitlab.example.com/-/snippets/65", "raw_url": "https://gitlab.example.com/-/snippets/65/raw", "ssh_url_to_repo": "ssh://user@gitlab.example.com/snippets/65.git", "http_url_to_repo": "https://gitlab.example.com/snippets/65.git" } } Schedule repository storage moves for all snippets on a storage shard --------------------------------------------------------------------- Schedules repository storage moves for each snippet repository stored on the source storage shard. This endpoint migrates all snippets at once. POST /snippet_repository_storage_moves Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `source_storage_name` | string | yes | Name of the source storage shard. | | `destination_storage_name` | string | no | Name of the destination storage shard. The storage is selected [automatically based on storage weights](https://docs.gitlab.com/administration/repository_storage_paths/#configure-where-new-repositories-are-stored)
if not provided. | Example request: curl --request POST --header "PRIVATE-TOKEN: " \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"default"}' \ --url "https://gitlab.example.com/api/v4/snippet_repository_storage_moves" Example response: { "message": "202 Accepted" } Related topics -------------- * [Moving repositories managed by GitLab](https://docs.gitlab.com/administration/operations/moving_repositories/) --- # System hooks API | GitLab Docs * * * System hooks API ================ * Tier: Free, Premium, Ultimate * Offering: GitLab Self-Managed Use this API to manage [system hooks](https://docs.gitlab.com/administration/system_hooks/) . System hooks are different from [group webhooks](https://docs.gitlab.com/api/group_webhooks/) that impact all projects and subgroups in a group, and [project webhooks](https://docs.gitlab.com/api/project_webhooks/) that are limited to a single project. Prerequisites: * You must be an administrator. List all system hooks --------------------- Lists all system hooks. GET /hooks Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/hooks" Example response: [\ {\ "id":1,\ "url":"https://gitlab.example.com/hook",\ "name": "Hook name",\ "description": "Hook description",\ "created_at":"2016-10-31T12:32:15.192Z",\ "push_events":true,\ "tag_push_events":false,\ "merge_requests_events": true,\ "repository_update_events": true,\ "enable_ssl_verification":true,\ "url_variables": []\ }\ ] Retrieve system hook -------------------- Retrieves a system hook by its ID. GET /hooks/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of the hook. | Example request: curl --request GET \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/hooks/1" Example response: { "id": 1, "url": "https://gitlab.example.com/hook", "name": "Hook name", "description": "Hook description", "created_at": "2016-10-31T12:32:15.192Z", "push_events": true, "tag_push_events": false, "merge_requests_events": true, "repository_update_events": true, "enable_ssl_verification": true, "url_variables": [] } Add new system hook ------------------- Adds a new system hook. POST /hooks | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | Yes | The hook URL. | | `branch_filter_strategy` | string | No | Filter push events by branch. Possible values are `wildcard` (default), `regex`, and `all_branches`. | | `description` | string | No | Description of the hook. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887)
in GitLab 17.1.) | | `enable_ssl_verification` | boolean | No | Do SSL verification when triggering the hook. | | `merge_requests_events` | boolean | No | Trigger hook on merge request events. | | `name` | string | No | Name of the hook. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460887)
in GitLab 17.1.) | | `push_events` | boolean | No | When true, the hook fires on push events. | | `push_events_branch_filter` | string | No | Trigger hook on push events for matching branches only. | | `repository_update_events` | boolean | No | Trigger hook on repository update events. | | `tag_push_events` | boolean | No | When true, the hook fires on new tags being pushed. | | `token` | string | No | Secret token to validate received payloads. Not returned in the response. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/hooks?url=https://gitlab.example.com/hook" Example response: [\ {\ "id":1,\ "url":"https://gitlab.example.com/hook",\ "name": "Hook name",\ "description": "Hook description",\ "created_at":"2016-10-31T12:32:15.192Z",\ "push_events":true,\ "tag_push_events":false,\ "merge_requests_events": true,\ "repository_update_events": true,\ "enable_ssl_verification":true,\ "url_variables": []\ }\ ] Update system hook ------------------ Updates an existing system hook. PUT /hooks/:hook_id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | The ID of the system hook. | | `branch_filter_strategy` | string | No | Filter push events by branch. Possible values are `wildcard` (default), `regex`, and `all_branches`. | | `enable_ssl_verification` | boolean | No | Do SSL verification when triggering the hook. | | `merge_requests_events` | boolean | No | Trigger hook on merge request events. | | `push_events` | boolean | No | When true, the hook fires on push events. | | `push_events_branch_filter` | string | No | Trigger hook on push events for matching branches only. | | `repository_update_events` | boolean | No | Trigger hook on repository update events. | | `tag_push_events` | boolean | No | When true, the hook fires on new tags being pushed. | | `token` | string | No | Secret token to validate received payloads; this isn’t returned in the response. | | `url` | string | No | The hook URL. | Test system hook ---------------- Executes the system hook with mock data. POST /hooks/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of the hook. | Example request: curl --request POST \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/hooks/1" The response is always the mock data: { "project_id" : 1, "owner_email" : "example@gitlabhq.com", "owner_name" : "Someone", "name" : "Ruby", "path" : "ruby", "event_name" : "project_create" } Delete system hook ------------------ Deletes a system hook. DELETE /hooks/:id | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `id` | integer | Yes | The ID of the hook. | Example request: curl --request DELETE \ --header "PRIVATE-TOKEN: " \ --url "https://gitlab.example.com/api/v4/hooks/2" Set a URL variable ------------------ PUT /hooks/:hook_id/url_variables/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the system hook. | | `key` | string | Yes | Key of the URL variable. | | `value` | string | Yes | Value of the URL variable. | On success, this endpoint returns the response code `204 No Content`. Delete a URL variable --------------------- DELETE /hooks/:hook_id/url_variables/:key Supported attributes: | Attribute | Type | Required | Description | | --- | --- | --- | --- | | `hook_id` | integer | Yes | ID of the system hook. | | `key` | string | Yes | Key of the URL variable. | On success, this endpoint returns the response code `204 No Content`. --- # Group integrations API | GitLab Docs * * * Group integrations API ====================== * Tier: Free, Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/328496) in GitLab 17.9. Use this API to manage [integrations](https://docs.gitlab.com/user/project/integrations/) for a group and its subgroups. Prerequisites: * You must have the Maintainer or Owner role for the group. List all active integrations ---------------------------- Get a list of all active group integrations. The `vulnerability_events` field is only available for GitLab Enterprise Edition. GET /groups/:id/integrations Example response: [\ {\ "id": 75,\ "title": "Jenkins CI",\ "slug": "jenkins",\ "created_at": "2019-11-20T11:20:25.297Z",\ "updated_at": "2019-11-20T12:24:37.498Z",\ "active": true,\ "commit_events": true,\ "push_events": true,\ "issues_events": true,\ "alert_events": true,\ "confidential_issues_events": true,\ "merge_requests_events": true,\ "tag_push_events": false,\ "deployment_events": false,\ "note_events": true,\ "confidential_note_events": true,\ "pipeline_events": true,\ "wiki_page_events": true,\ "job_events": true,\ "comment_on_event_enabled": true,\ "inherited": false,\ "vulnerability_events": true\ },\ {\ "id": 76,\ "title": "Alerts endpoint",\ "slug": "alerts",\ "created_at": "2019-11-20T11:20:25.297Z",\ "updated_at": "2019-11-20T12:24:37.498Z",\ "active": true,\ "commit_events": true,\ "push_events": true,\ "issues_events": true,\ "alert_events": true,\ "confidential_issues_events": true,\ "merge_requests_events": true,\ "tag_push_events": true,\ "deployment_events": false,\ "note_events": true,\ "confidential_note_events": true,\ "pipeline_events": true,\ "wiki_page_events": true,\ "job_events": true,\ "comment_on_event_enabled": true,\ "inherited": false,\ "vulnerability_events": true\ }\ ] Asana ----- ### Set up Asana Set up the Asana integration for a group. PUT /groups/:id/integrations/asana Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `api_key` | string | yes | User API token. The user must have access to the task. All comments are attributed to this user. | | `restrict_to_branch` | string | no | Comma-separated list of branches to be automatically inspected. Leave blank to include all branches. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Asana Disable the Asana integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/asana ### Get Asana settings Get the Asana integration settings for a group. GET /groups/:id/integrations/asana Assembla -------- ### Set up Assembla Set up the Assembla integration for a group. PUT /groups/:id/integrations/assembla Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The authentication token. | | `subdomain` | string | no | The subdomain setting. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Assembla Disable the Assembla integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/assembla ### Get Assembla settings Get the Assembla integration settings for a group. GET /groups/:id/integrations/assembla Atlassian Bamboo ---------------- ### Set up Atlassian Bamboo Set up the Atlassian Bamboo integration for a group. You must configure automatic revision labeling and a repository trigger in Bamboo. PUT /groups/:id/integrations/bamboo Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `bamboo_url` | string | yes | Bamboo root URL (for example, `https://bamboo.example.com`). | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `build_key` | string | yes | Bamboo build plan key (for example, `KEY`). | | `username` | string | yes | User with API access to the Bamboo server. | | `password` | string | yes | Password of the user. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Atlassian Bamboo Disable the Atlassian Bamboo integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/bamboo ### Get Atlassian Bamboo settings Get the Atlassian Bamboo integration settings for a group. GET /groups/:id/integrations/bamboo Bugzilla -------- ### Set up Bugzilla Set up the Bugzilla integration for a group. PUT /groups/:id/integrations/bugzilla Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Bugzilla Disable the Bugzilla integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/bugzilla ### Get Bugzilla settings Get the Bugzilla integration settings for a group. GET /groups/:id/integrations/bugzilla Buildkite --------- ### Set up Buildkite Set up the Buildkite integration for a group. PUT /groups/:id/integrations/buildkite Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | Buildkite project GitLab token. | | `project_url` | string | yes | Pipeline URL (for example, `https://buildkite.com/example/pipeline`). | | `enable_ssl_verification` | boolean | no | **Deprecated**: This parameter has no effect because SSL verification is always enabled. | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Buildkite Disable the Buildkite integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/buildkite ### Get Buildkite settings Get the Buildkite integration settings for a group. GET /groups/:id/integrations/buildkite Campfire Classic ---------------- You can integrate with Campfire Classic. However, Campfire Classic is an old product that is [no longer sold](https://gitlab.com/gitlab-org/gitlab/-/issues/329337) by Basecamp. ### Set up Campfire Classic Set up the Campfire Classic integration for a group. PUT /groups/:id/integrations/campfire Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | API authentication token from Campfire Classic. To get the token, sign in to Campfire Classic and select **My info**. | | `subdomain` | string | no | `.campfirenow.com` subdomain when you’re signed in. | | `room` | string | no | ID portion of the Campfire Classic room URL. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Campfire Classic Disable the Campfire Classic integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/campfire ### Get Campfire Classic settings Get the Campfire Classic integration settings for a group. GET /groups/:id/integrations/campfire ClickUp ------- ### Set up ClickUp Set up the ClickUp integration for a group. PUT /groups/:id/integrations/clickup Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable ClickUp Disable the ClickUp integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/clickup ### Get ClickUp settings Get the ClickUp integration settings for a group. GET /groups/:id/integrations/clickup Confluence Workspace -------------------- ### Set up Confluence Workspace Set up the Confluence Workspace integration for a group. PUT /groups/:id/integrations/confluence Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `confluence_url` | string | yes | URL of the Confluence Workspace hosted on `atlassian.net`. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Confluence Workspace Disable the Confluence Workspace integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/confluence ### Get Confluence Workspace settings Get the Confluence Workspace integration settings for a group. GET /groups/:id/integrations/confluence Custom issue tracker -------------------- ### Set up a custom issue tracker Set up a custom issue tracker for a group. PUT /groups/:id/integrations/custom-issue-tracker Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable a custom issue tracker Disable a custom issue tracker for a group. Integration settings are reset. DELETE /groups/:id/integrations/custom-issue-tracker ### Get custom issue tracker settings Get the custom issue tracker settings for a group. GET /groups/:id/integrations/custom-issue-tracker Datadog ------- ### Set up Datadog Set up the Datadog integration for a group. PUT /groups/:id/integrations/datadog Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `api_key` | string | yes | API key used for authentication with Datadog. | | `api_url` | string | no | (Advanced) The full URL for your Datadog site. | | `datadog_env` | string | no | For self-managed deployments, set the `env%` tag for all the data sent to Datadog. | | `datadog_service` | string | no | Tag all data from this GitLab instance in Datadog. Can be used when managing several self-managed deployments. | | `datadog_site` | string | no | The Datadog site to send data to. To send data to the EU site, use `datadoghq.eu`. | | `datadog_tags` | string | no | Custom tags in Datadog. Specify one tag per line in the format `key:value\nkey2:value2` | | `archive_trace_events` | boolean | no | When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Datadog Disable the Datadog integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/datadog ### Get Datadog settings Get the Datadog integration settings for a group. GET /groups/:id/integrations/datadog Diffblue Cover -------------- ### Set up Diffblue Cover Set up the Diffblue Cover integration for a group. PUT /groups/:id/integrations/diffblue-cover Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `diffblue_license_key` | string | yes | Diffblue Cover license key. | | `diffblue_access_token_name` | string | yes | Access token name used by Diffblue Cover in pipelines. | | `diffblue_access_token_secret` | string | yes | Access token secret used by Diffblue Cover in pipelines. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Diffblue Cover Disable the Diffblue Cover integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/diffblue-cover ### Get Diffblue Cover settings Get the Diffblue Cover integration settings for a group. GET /groups/:id/integrations/diffblue-cover Discord Notifications --------------------- ### Set up Discord Notifications Set up Discord Notifications for a group. PUT /groups/:id/integrations/discord Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | Discord webhook (for example, `https://discord.com/api/webhooks/...`). | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `confidential_issue_channel` | string | no | The webhook override to receive notifications for confidential issue events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `confidential_note_channel` | string | no | The webhook override to receive notifications for confidential note events. | | `deployment_events` | boolean | no | Enable notifications for deployment events. | | `deployment_channel` | string | no | The webhook override to receive notifications for deployment events. | | `group_confidential_mentions_events` | boolean | no | Enable notifications for group confidential mention events. | | `group_confidential_mentions_channel` | string | no | The webhook override to receive notifications for group confidential mention events. | | `group_mentions_events` | boolean | no | Enable notifications for group mention events. | | `group_mentions_channel` | string | no | The webhook override to receive notifications for group mention events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `issue_channel` | string | no | The webhook override to receive notifications for issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `merge_request_channel` | string | no | The webhook override to receive notifications for merge request events. | | `note_events` | boolean | no | Enable notifications for note events. | | `note_channel` | string | no | The webhook override to receive notifications for note events. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `pipeline_channel` | string | no | The webhook override to receive notifications for pipeline events. | | `push_events` | boolean | no | Enable notifications for push events. | | `push_channel` | string | no | The webhook override to receive notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `tag_push_channel` | string | no | The webhook override to receive notifications for tag push events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `wiki_page_channel` | string | no | The webhook override to receive notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Discord Notifications Disable Discord Notifications for a group. Integration settings are reset. DELETE /groups/:id/integrations/discord ### Get Discord Notifications settings Get the Discord Notifications settings for a group. GET /groups/:id/integrations/discord Drone ----- ### Set up Drone Set up the Drone integration for a group. PUT /groups/:id/integrations/drone-ci Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | Drone CI project specific token. | | `drone_url` | string | yes | `http://drone.example.com`. | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Drone Disable the Drone integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/drone-ci ### Get Drone settings Get the Drone integration settings for a group. GET /groups/:id/integrations/drone-ci Emails on push -------------- ### Set up emails on push Set up the emails on push integration for a group. PUT /groups/:id/integrations/emails-on-push Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `recipients` | string | yes | Emails separated by whitespace. | | `disable_diffs` | boolean | no | Disable code diffs. | | `send_from_committer_email` | boolean | no | Send from committer. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. Notifications are always fired for tag pushes. The default value is `all`. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable emails on push Disable the emails on push integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/emails-on-push ### Get emails on push settings Get the emails on push integration settings for a group. GET /groups/:id/integrations/emails-on-push Engineering Workflow Management (EWM) ------------------------------------- ### Set up EWM Set up the EWM integration for a group. PUT /groups/:id/integrations/ewm Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `project_url` | string | yes | URL of the project. | | `issues_url` | string | yes | URL of the issue. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable EWM Disable the EWM integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/ewm ### Get EWM settings Get the EWM integration settings for a group. GET /groups/:id/integrations/ewm External wiki ------------- ### Set up an external wiki Set up an external wiki for a group. PUT /groups/:id/integrations/external-wiki Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `external_wiki_url` | string | yes | URL of the external wiki. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable an external wiki Disable an external wiki for a group. Integration settings are reset. DELETE /groups/:id/integrations/external-wiki ### Get external wiki settings Get the external wiki settings for a group. GET /groups/:id/integrations/external-wiki GitGuardian ----------- * Tier: Premium, Ultimate * Offering: GitLab Self-Managed, GitLab Dedicated On GitLab Self-Managed, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](https://docs.gitlab.com/administration/feature_flags/) named `git_guardian_integration`. On GitLab.com, this feature is not available. On GitLab Dedicated, this feature is available. [GitGuardian](https://www.gitguardian.com/) is a cybersecurity service that detects sensitive data such as API keys and passwords in source code repositories. It scans Git repositories, alerts on policy violations, and helps organizations fix security issues before hackers can exploit them. You can configure GitLab to reject commits based on GitGuardian policies. For known issues and troubleshooting steps, see [GitGuardian troubleshooting](https://docs.gitlab.com/user/project/integrations/git_guardian/#troubleshooting) . ### Set up GitGuardian Set up the GitGuardian integration for a group. PUT /groups/:id/integrations/git-guardian Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | GitGuardian API token with `scan` scope. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable GitGuardian Disable the GitGuardian integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/git-guardian ### Get GitGuardian settings Get the GitGuardian integration settings for a group. GET /groups/:id/integrations/git-guardian GitHub ------ * Tier: Premium, Ultimate * Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated ### Set up GitHub Set up the GitHub integration for a group. PUT /groups/:id/integrations/github Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | GitHub API token with `repo:status` OAuth scope. | | `repository_url` | string | yes | GitHub repository URL. | | `static_context` | boolean | no | Append the hostname of your GitLab instance to the [status check name](https://docs.gitlab.com/user/project/integrations/github/#static-or-dynamic-status-check-names)
. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable GitHub Disable the GitHub integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/github ### Get GitHub settings Get the GitHub integration settings for a group. GET /groups/:id/integrations/github GitLab for Jira Cloud app ------------------------- The GitLab for Jira Cloud app integration is enabled or disabled automatically through [group linking and unlinking in Jira](https://docs.gitlab.com/integration/jira/connect-app/#configure-the-gitlab-for-jira-cloud-app) . You cannot enable or disable the integration with the GitLab integrations form or the API. ### Update integration for a group Use this API endpoint to update an integration you create with group linking in Jira. PUT /groups/:id/integrations/jira-cloud-app Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `jira_cloud_app_service_ids` | string | no | Jira Service Management Service IDs. Use commas (`,`) to separate multiple IDs. | | `jira_cloud_app_enable_deployment_gating` | boolean | no | Enables deployment gating for blocked GitLab deployments from Jira Service Management. | | `jira_cloud_app_deployment_gating_environments` | string | no | The environments (production, staging, testing, or development) to enable deployment gating. Required if deployment gating is enabled. Use commas (`,`) to separate multiple environments. | ### Get GitLab for Jira Cloud app settings Get the GitLab for Jira Cloud app integration settings for a group. GET /groups/:id/integrations/jira-cloud-app GitLab for Slack app -------------------- ### Set up GitLab for Slack app Update the GitLab for Slack app integration for a group. You cannot create a GitLab for Slack app through the API because the integration requires an OAuth 2.0 token that you cannot get from the GitLab API alone. Instead, you must [install the app](https://docs.gitlab.com/user/project/integrations/gitlab_slack_application/#install-the-gitlab-for-slack-app) from the GitLab UI. You can then use this API endpoint to update the integration. PUT /groups/:id/integrations/gitlab-slack-application Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channel` | string | no | Default channel to use if no other channel is configured. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `alert_events` | boolean | no | Enable notifications for alert events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `deployment_events` | boolean | no | Enable notifications for deployment events. | | `incidents_events` | boolean | no | Enable notifications for incident events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `vulnerability_events` | boolean | no | Enable notifications for vulnerability events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `labels_to_be_notified` | string | no | Labels to send notifications for. If not set, receive notifications for all events. | | `labels_to_be_notified_behavior` | string | no | Labels to be notified for. Valid options are `match_any` and `match_all`. Defaults to `match_any`. | | `push_channel` | string | no | Name of the channel to receive notifications for push events. | | `issue_channel` | string | no | Name of the channel to receive notifications for issue events. | | `confidential_issue_channel` | string | no | Name of the channel to receive notifications for confidential issue events. | | `merge_request_channel` | string | no | Name of the channel to receive notifications for merge request events. | | `note_channel` | string | no | Name of the channel to receive notifications for note events. | | `confidential_note_channel` | string | no | Name of the channel to receive notifications for confidential note events. | | `tag_push_channel` | string | no | Name of the channel to receive notifications for tag push events. | | `pipeline_channel` | string | no | Name of the channel to receive notifications for pipeline events. | | `wiki_page_channel` | string | no | Name of the channel to receive notifications for wiki page events. | | `deployment_channel` | string | no | Name of the channel to receive notifications for deployment events. | | `incident_channel` | string | no | Name of the channel to receive notifications for incident events. | | `vulnerability_channel` | string | no | Name of the channel to receive notifications for vulnerability events. | | `alert_channel` | string | no | Name of the channel to receive notifications for alert events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable GitLab for Slack app Disable the GitLab for Slack app integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/gitlab-slack-application ### Get GitLab for Slack app settings Get the GitLab for Slack app integration settings for a group. GET /groups/:id/integrations/gitlab-slack-application Google Chat ----------- ### Set up Google Chat Set up the Google Chat integration for a group. PUT /groups/:id/integrations/hangouts-chat Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Hangouts Chat webhook (for example, `https://chat.googleapis.com/v1/spaces...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Google Chat Disable the Google Chat integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/hangouts-chat ### Get Google Chat settings Get the Google Chat integration settings for a group. GET /groups/:id/integrations/hangouts-chat Google Artifact Management -------------------------- * Tier: Free, Premium, Ultimate * Offering: GitLab.com * Status: Beta This feature is in [beta](https://docs.gitlab.com/policy/development_stages_support/) . ### Set up Google Artifact Management Set up the Google Artifact Management integration for a group. PUT /groups/:id/integrations/google-cloud-platform-artifact-registry Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `artifact_registry_project_id` | string | yes | ID of the Google Cloud project. | | `artifact_registry_location` | string | yes | Location of the Artifact Registry repository. | | `artifact_registry_repositories` | string | yes | Repository of Artifact Registry. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Google Artifact Management Disable the Google Artifact Management integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/google-cloud-platform-artifact-registry ### Get Google Artifact Management settings Get the Google Artifact Management integration settings for a group. GET /groups/:id/integrations/google-cloud-platform-artifact-registry Google Cloud Identity and Access Management (IAM) ------------------------------------------------- * Tier: Free, Premium, Ultimate * Offering: GitLab.com * Status: Beta This feature is in [beta](https://docs.gitlab.com/policy/development_stages_support/) . ### Set up Google Cloud Identity and Access Management Set up the Google Cloud Identity and Access Management integration for a group. PUT /groups/:id/integrations/google-cloud-platform-workload-identity-federation Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `workload_identity_federation_project_id` | string | yes | Google Cloud project ID for the Workload Identity Federation. | | `workload_identity_federation_project_number` | integer | yes | Google Cloud project number for the Workload Identity Federation. | | `workload_identity_pool_id` | string | yes | ID of the workload identity pool. | | `workload_identity_pool_provider_id` | string | yes | ID of the workload identity pool provider. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Google Cloud Identity and Access Management Disable the Google Cloud Identity and Access Management integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/google-cloud-platform-workload-identity-federation ### Get Google Cloud Identity and Access Management Get the settings for the Google Cloud Identity and Access Management for a group. GET /groups/:id/integration/google-cloud-platform-workload-identity-federation Harbor ------ ### Set up Harbor Set up the Harbor integration for a group. PUT /groups/:id/integrations/harbor Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | The base URL to the Harbor instance linked to the GitLab project. For example, `https://demo.goharbor.io`. | | `project_name` | string | yes | The name of the project in the Harbor instance. For example, `testproject`. | | `username` | string | yes | The username created in the Harbor interface. | | `password` | string | yes | The password of the user. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Harbor Disable the Harbor integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/harbor ### Get Harbor settings Get the Harbor integration settings for a group. GET /groups/:id/integrations/harbor irker (IRC gateway) ------------------- ### Set up irker Set up the irker integration for a group. PUT /groups/:id/integrations/irker Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `recipients` | string | yes | Recipients or channels separated by whitespaces. | | `default_irc_uri` | string | no | `irc://irc.network.net:6697/`. | | `server_host` | string | no | localhost. | | `server_port` | integer | no | 6659. | | `colorize_messages` | boolean | no | Colorize messages. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable irker Disable the irker integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/irker ### Get irker settings Get the irker integration settings for a group. GET /groups/:id/integrations/irker JetBrains TeamCity ------------------ ### Set up JetBrains TeamCity Set up the JetBrains TeamCity integration for a group. The build configuration in TeamCity must use the build number format `%build.vcs.number%`. In the advanced settings for VCS root, configure monitoring for all branches so merge requests can build. PUT /groups/:id/integrations/teamcity Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `teamcity_url` | string | yes | TeamCity root URL (for example, `https://teamcity.example.com`). | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `build_type` | string | yes | Build configuration ID. | | `username` | string | yes | A user with permissions to trigger a manual build. | | `password` | string | yes | The password of the user. | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable JetBrains TeamCity Disable the JetBrains TeamCity integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/teamcity ### Get JetBrains TeamCity settings Get the JetBrains TeamCity integration settings for a group. GET /groups/:id/integrations/teamcity Jira ---- ### Set up Jira Set up the Jira integration for a group. PUT /groups/:id/integrations/jira Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | The URL to the Jira project which is being linked to this GitLab project (for example, `https://jira.example.com`). | | `api_url` | string | no | The base URL to the Jira instance API. Web URL value is used if not set (for example, `https://jira-api.example.com`). | | `username` | string | no | The email or username to be used with Jira. For Jira Cloud use an email, for Jira Data Center and Jira Server use a username. Required when using Basic authentication (`jira_auth_type` is `0`). | | `password` | string | yes | The Jira API token, password, or personal access token to be used with Jira. When your authentication method is basic (`jira_auth_type` is `0`), use an API token for Jira Cloud or a password for Jira Data Center or Jira Server. When your authentication method is a Jira personal access token (`jira_auth_type` is `1`), use the personal access token. | | `jira_auth_type` | integer | no | The authentication method to be used with Jira. `0` means Basic Authentication. `1` means Jira personal access token. Defaults to `0`. | | `jira_issue_prefix` | string | no | Prefix to match Jira issue keys. | | `jira_issue_regex` | string | no | Regular expression to match Jira issue keys. | | `jira_issue_transition_automatic` | boolean | no | Enable [automatic issue transitions](https://docs.gitlab.com/integration/jira/issues/#automatic-issue-transitions)
. Takes precedence over `jira_issue_transition_id` if enabled. Defaults to `false`. | | `jira_issue_transition_id` | string | no | The ID of one or more transitions for [custom issue transitions](https://docs.gitlab.com/integration/jira/issues/#custom-issue-transitions)
. Ignored if `jira_issue_transition_automatic` is enabled. Defaults to a blank string, which disables custom transitions. | | `commit_events` | boolean | no | Enable notifications for commit events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `comment_on_event_enabled` | boolean | no | Enable comments in Jira issues on each GitLab event (commit or merge request). | | `issues_enabled` | boolean | no | Enable viewing Jira issues in GitLab. | | `project_keys` | array of strings | no | Keys of Jira projects. When `issues_enabled` is `true`, this setting specifies which Jira projects to view issues from in GitLab. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Jira Disable the Jira integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/jira ### Get Jira settings Get the Jira integration settings for a group. GET /groups/:id/integrations/jira Linear ------ History * [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/198297) in GitLab 18.3. ### Set up Linear Set up the Linear integration for a group. PUT /groups/:id/integrations/linear Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `workspace_url` | string | yes | URL of the issue. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Linear Disable the Linear integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/linear ### Get Linear settings Get the Linear integration settings for a group. GET /groups/:id/integrations/linear Matrix notifications -------------------- ### Set up Matrix notifications Set up Matrix notifications for a group. PUT /groups/:id/integrations/matrix Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `hostname` | string | no | Custom hostname of the Matrix server. The default value is `https://matrix.org`. | | `token` | string | yes | The Matrix access token (for example, `syt-zyx57W2v1u123ew11`). | | `room` | string | yes | Unique identifier for the target room (in the format `!qPKKM111FFKKsfoCVy:matrix.org`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Matrix notifications Disable Matrix notifications for a group. Integration settings are reset. DELETE /groups/:id/integrations/matrix ### Get Matrix notifications settings Get the Matrix notifications settings for a group. GET /groups/:id/integrations/matrix Mattermost notifications ------------------------ ### Set up Mattermost notifications Set up Mattermost notifications for a group. PUT /groups/:id/integrations/mattermost Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | Mattermost notifications webhook (for example, `http://mattermost.example.com/hooks/...`). | | `username` | string | no | Mattermost notifications username. | | `channel` | string | no | Default channel to use if no other channel is configured. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `labels_to_be_notified` | string | no | Labels to send notifications for. Leave blank to receive notifications for all events. | | `labels_to_be_notified_behavior` | string | no | Labels to be notified for. Valid options are `match_any` and `match_all`. The default value is `match_any`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `push_channel` | string | no | The name of the channel to receive notifications for push events. | | `issue_channel` | string | no | The name of the channel to receive notifications for issue events. | | `confidential_issue_channel` | string | no | The name of the channel to receive notifications for confidential issue events. | | `merge_request_channel` | string | no | The name of the channel to receive notifications for merge request events. | | `note_channel` | string | no | The name of the channel to receive notifications for note events. | | `confidential_note_channel` | string | no | The name of the channel to receive notifications for confidential note events. | | `tag_push_channel` | string | no | The name of the channel to receive notifications for tag push events. | | `pipeline_channel` | string | no | The name of the channel to receive notifications for pipeline events. | | `wiki_page_channel` | string | no | The name of the channel to receive notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Mattermost notifications Disable Mattermost notifications for a group. Integration settings are reset. DELETE /groups/:id/integrations/mattermost ### Get Mattermost notifications settings Get the Mattermost notifications settings for a group. GET /groups/:id/integrations/mattermost Mattermost slash commands ------------------------- ### Set up Mattermost slash commands Set up Mattermost slash commands for a group. PUT /groups/:id/integrations/mattermost-slash-commands Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The Mattermost token. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Mattermost slash commands Disable Mattermost slash commands for a group. Integration settings are reset. DELETE /groups/:id/integrations/mattermost-slash-commands ### Get Mattermost slash commands settings Get the Mattermost slash commands settings for a group. GET /groups/:id/integrations/mattermost-slash-commands Microsoft Teams notifications ----------------------------- ### Set up Microsoft Teams notifications Set up Microsoft Teams notifications for a group. PUT /groups/:id/integrations/microsoft-teams Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Microsoft Teams webhook (for example, `https://outlook.office.com/webhook/...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Microsoft Teams notifications Disable Microsoft Teams notifications for a group. Integration settings are reset. DELETE /groups/:id/integrations/microsoft-teams ### Get Microsoft Teams notifications settings Get the Microsoft Teams notifications settings for a group. GET /groups/:id/integrations/microsoft-teams Mock CI ------- This integration is only available in a development environment. For an example Mock CI server, see [`gitlab-org/gitlab-mock-ci-service`](https://gitlab.com/gitlab-org/gitlab-mock-ci-service) . ### Set up Mock CI Set up the Mock CI integration for a group. PUT /groups/:id/integrations/mock-ci Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `mock_service_url` | string | yes | URL of the Mock CI integration. | | `enable_ssl_verification` | boolean | no | Enable SSL verification. Defaults to `true` (enabled). | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Mock CI Disable the Mock CI integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/mock-ci ### Get Mock CI settings Get the Mock CI integration settings for a group. GET /groups/:id/integrations/mock-ci Packagist --------- ### Set up Packagist Set up the Packagist integration for a group. PUT /groups/:id/integrations/packagist Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `username` | string | yes | The username of a Packagist account. | | `token` | string | yes | API token to the Packagist server. | | `server` | boolean | no | URL of the Packagist server. Leave blank for the default ``. | | `push_events` | boolean | no | Enable notifications for push events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Packagist Disable the Packagist integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/packagist ### Get Packagist settings Get the Packagist integration settings for a group. GET /groups/:id/integrations/packagist Phorge ------ ### Set up Phorge Set up the Phorge integration for a group. PUT /groups/:id/integrations/phorge Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Phorge Disable the Phorge integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/phorge ### Get Phorge settings Get the Phorge integration settings for a group. GET /groups/:id/integrations/phorge Pipeline status emails ---------------------- ### Set up pipeline status emails Set up pipeline status emails for a group. PUT /groups/:id/integrations/pipelines-email Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `recipients` | string | yes | Comma-separated list of recipient email addresses. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `notify_only_default_branch` | boolean | no | Send notifications for the default branch. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable pipeline status emails Disable pipeline status emails for a group. Integration settings are reset. DELETE /groups/:id/integrations/pipelines-email ### Get pipeline status emails settings Get the pipeline status emails settings for a group. GET /groups/:id/integrations/pipelines-email Pivotal Tracker --------------- ### Set up Pivotal Tracker Set up the Pivotal Tracker integration for a group. PUT /groups/:id/integrations/pivotaltracker Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The Pivotal Tracker token. | | `restrict_to_branch` | boolean | no | Comma-separated list of branches to automatically inspect. Leave blank to include all branches. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Pivotal Tracker Disable the Pivotal Tracker integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/pivotaltracker ### Get Pivotal Tracker settings Get the Pivotal Tracker integration settings for a group. GET /groups/:id/integrations/pivotaltracker Pumble ------ ### Set up Pumble Set up the Pumble integration for a group. PUT /groups/:id/integrations/pumble Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Pumble webhook (for example, `https://api.pumble.com/workspaces/x/...`). | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default is `default`. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `note_events` | boolean | no | Enable notifications for note events. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Pumble Disable the Pumble integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/pumble ### Get Pumble settings Get the Pumble integration settings for a group. GET /groups/:id/integrations/pumble Pushover -------- ### Set up Pushover Set up the Pushover integration for a group. PUT /groups/:id/integrations/pushover Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `api_key` | string | yes | Your application key. | | `user_key` | string | yes | Your user key. | | `priority` | string | yes | The priority. | | `device` | string | no | Leave blank for all active devices. | | `sound` | string | no | The sound of the notification. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Pushover Disable the Pushover integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/pushover ### Get Pushover settings Get the Pushover integration settings for a group. GET /groups/:id/integrations/pushover Redmine ------- ### Set up Redmine Set up the Redmine integration for a group. PUT /groups/:id/integrations/redmine Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `new_issue_url` | string | yes | URL of the new issue. | | `project_url` | string | yes | URL of the project. | | `issues_url` | string | yes | URL of the issue. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Redmine Disable the Redmine integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/redmine ### Get Redmine settings Get the Redmine integration settings for a group. GET /groups/:id/integrations/redmine Slack notifications ------------------- ### Set up Slack notifications Set up Slack notifications for a group. PUT /groups/:id/integrations/slack Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | Slack notifications webhook (for example, `https://hooks.slack.com/services/...`). | | `username` | string | no | Slack notifications username. | | `channel` | string | no | Default channel to use if no other channel is configured. | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `notify_only_default_branch` | boolean | no | **Deprecated**: This parameter has been replaced with `branches_to_be_notified`. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `labels_to_be_notified` | string | no | Labels to send notifications for. Leave blank to receive notifications for all events. | | `labels_to_be_notified_behavior` | string | no | Labels to be notified for. Valid options are `match_any` and `match_all`. The default value is `match_any`. | | `alert_channel` | string | no | The name of the channel to receive notifications for alert events. | | `alert_events` | boolean | no | Enable notifications for alert events. | | `commit_events` | boolean | no | Enable notifications for commit events. | | `confidential_issue_channel` | string | no | The name of the channel to receive notifications for confidential issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `confidential_note_channel` | string | no | The name of the channel to receive notifications for confidential note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `deployment_channel` | string | no | The name of the channel to receive notifications for deployment events. | | `deployment_events` | boolean | no | Enable notifications for deployment events. | | `incident_channel` | string | no | The name of the channel to receive notifications for incident events. | | `incidents_events` | boolean | no | Enable notifications for incident events. | | `issue_channel` | string | no | The name of the channel to receive notifications for issue events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `job_events` | boolean | no | Enable notifications for job events. | | `merge_request_channel` | string | no | The name of the channel to receive notifications for merge request events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `note_channel` | string | no | The name of the channel to receive notifications for note events. | | `note_events` | boolean | no | Enable notifications for note events. | | `pipeline_channel` | string | no | The name of the channel to receive notifications for pipeline events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `push_channel` | string | no | The name of the channel to receive notifications for push events. | | `push_events` | boolean | no | Enable notifications for push events. | | `tag_push_channel` | string | no | The name of the channel to receive notifications for tag push events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `wiki_page_channel` | string | no | The name of the channel to receive notifications for wiki page events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Slack notifications Disable Slack notifications for a group. Integration settings are reset. DELETE /groups/:id/integrations/slack ### Get Slack notifications settings Get the Slack notifications settings for a group. GET /groups/:id/integrations/slack Slack slash commands -------------------- ### Set up Slack slash commands Set up Slack slash commands for a group. PUT /groups/:id/integrations/slack-slash-commands Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `token` | string | yes | The Slack token. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Slack slash commands Disable Slack slash commands for a group. Integration settings are reset. DELETE /groups/:id/integrations/slack-slash-commands ### Get Slack slash commands settings Get the Slack slash commands settings for a group. GET /groups/:id/integrations/slack-slash-commands Example response: { "id": 4, "title": "Slack slash commands", "slug": "slack-slash-commands", "created_at": "2017-06-27T05:51:39-07:00", "updated_at": "2017-06-27T05:51:39-07:00", "active": true, "push_events": true, "issues_events": true, "confidential_issues_events": true, "merge_requests_events": true, "tag_push_events": true, "note_events": true, "job_events": true, "pipeline_events": true, "comment_on_event_enabled": false, "inherited": false, "properties": { "token": "" } } Squash TM --------- ### Set up Squash TM Set up the Squash TM integration settings for a group. PUT /groups/:id/integrations/squash-tm Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | URL of the Squash TM webhook. | | `token` | string | no | Secret token. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Squash TM Disable the Squash TM integration for a group. Integration settings are preserved. DELETE /groups/:id/integrations/squash-tm ### Get Squash TM settings Get the Squash TM integration settings for a group. GET /groups/:id/integrations/squash-tm Telegram -------- ### Set up Telegram Set up the Telegram integration for a group. PUT /groups/:id/integrations/telegram Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `hostname` | string | no | Custom hostname of the Telegram API. The default value is `https://api.telegram.org`. | | `token` | string | yes | The Telegram bot token (for example, `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`). | | `room` | string | yes | Unique identifier for the target chat or the username of the target channel (in the format `@channelusername`). | | `thread` | integer | no | Unique identifier for the target message thread (topic in a forum supergroup). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | yes | Enable notifications for push events. | | `issues_events` | boolean | yes | Enable notifications for issue events. | | `confidential_issues_events` | boolean | yes | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | yes | Enable notifications for merge request events. | | `tag_push_events` | boolean | yes | Enable notifications for tag push events. | | `note_events` | boolean | yes | Enable notifications for note events. | | `confidential_note_events` | boolean | yes | Enable notifications for confidential note events. | | `pipeline_events` | boolean | yes | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | yes | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Telegram Disable the Telegram integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/telegram ### Get Telegram settings Get the Telegram integration settings for a group. GET /groups/:id/integrations/telegram Unify Circuit ------------- ### Set up Unify Circuit Set up the Unify Circuit integration for a group. PUT /groups/:id/integrations/unify-circuit Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Unify Circuit webhook (for example, `https://circuit.com/rest/v2/webhooks/incoming/...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Unify Circuit Disable the Unify Circuit integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/unify-circuit ### Get Unify Circuit settings Get the Unify Circuit integration settings for a group. GET /groups/:id/integrations/unify-circuit Webex Teams ----------- ### Set up Webex Teams Set up Webex Teams for a group. PUT /groups/:id/integrations/webex-teams Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhook` | string | yes | The Webex Teams webhook (for example, `https://api.ciscospark.com/v1/webhooks/incoming/...`). | | `notify_only_broken_pipelines` | boolean | no | Send notifications for broken pipelines. | | `notify_only_when_pipeline_status_changes` | boolean | no | Send notifications only when the pipeline status for the ref changes. | | `branches_to_be_notified` | string | no | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is `default`. | | `push_events` | boolean | no | Enable notifications for push events. | | `issues_events` | boolean | no | Enable notifications for issue events. | | `confidential_issues_events` | boolean | no | Enable notifications for confidential issue events. | | `merge_requests_events` | boolean | no | Enable notifications for merge request events. | | `tag_push_events` | boolean | no | Enable notifications for tag push events. | | `note_events` | boolean | no | Enable notifications for note events. | | `confidential_note_events` | boolean | no | Enable notifications for confidential note events. | | `pipeline_events` | boolean | no | Enable notifications for pipeline events. | | `wiki_page_events` | boolean | no | Enable notifications for wiki page events. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable Webex Teams Disable Webex Teams for a group. Integration settings are reset. DELETE /groups/:id/integrations/webex-teams ### Get Webex Teams settings Get the Webex Teams settings for a group. GET /groups/:id/integrations/webex-teams YouTrack -------- ### Set up YouTrack Set up the YouTrack integration for a group. PUT /groups/:id/integrations/youtrack Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `issues_url` | string | yes | URL of the issue. | | `project_url` | string | yes | URL of the project. | | `use_inherited_settings` | boolean | no | Indicates whether or not to inherit default settings. Defaults to `false`. | ### Disable YouTrack Disable the YouTrack integration for a group. Integration settings are reset. DELETE /groups/:id/integrations/youtrack ### Get YouTrack settings Get the YouTrack integration settings for a group. GET /groups/:id/integrations/youtrack ---