# 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


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
[](https://www.onetrust.com/products/cookie-consent/)

---
# 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" : ""
}
}
---
# 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.
[](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.
[](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.
[](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": ""
}
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