You can also use the recently released Gitlab GraphQL API to query groups by name :

{
  group(fullPath: "your_group_here") {
    projects {
      nodes {
        name
        description
        httpUrlToRepo
        nameWithNamespace
        starCount
      }
    }
  }
}

You can go to the following URL : https://[your_gitlab_host]/-/graphql-explorer and past the above query

The Graphql endpoint is a POST on "https://$gitlab_url/api/graphql" An example using curl and jq:

gitlab_url=<your gitlab host>
access_token=<your access token>
group_name=<your group>

curl -s -H "Authorization: Bearer $access_token" \
     -H "Content-Type:application/json" \
     -d '{ 
          "query": "{ group(fullPath: \"'$group_name'\") { projects {nodes { name description httpUrlToRepo nameWithNamespace starCount}}}}"
      }' "https://$gitlab_url/api/graphql" | jq '.'
Answer from Bertrand Martel on Stack Overflow
🌐
GitLab
gitlab.com › gitlab.org › gitlab foss › #50325
Get all projects (including subgroups) for a given namespace (#50325) · Issues · GitLab.org / GitLab FOSS · GitLab
August 15, 2018 - What I would like to do is to get all projects that are in a namespace (in any sub group). Given I have the following structure...
Top answer
1 of 6
18

You can also use the recently released Gitlab GraphQL API to query groups by name :

{
  group(fullPath: "your_group_here") {
    projects {
      nodes {
        name
        description
        httpUrlToRepo
        nameWithNamespace
        starCount
      }
    }
  }
}

You can go to the following URL : https://[your_gitlab_host]/-/graphql-explorer and past the above query

The Graphql endpoint is a POST on "https://$gitlab_url/api/graphql" An example using curl and jq:

gitlab_url=<your gitlab host>
access_token=<your access token>
group_name=<your group>

curl -s -H "Authorization: Bearer $access_token" \
     -H "Content-Type:application/json" \
     -d '{ 
          "query": "{ group(fullPath: \"'$group_name'\") { projects {nodes { name description httpUrlToRepo nameWithNamespace starCount}}}}"
      }' "https://$gitlab_url/api/graphql" | jq '.'
2 of 6
16

Adding to @Dante's answer,

This gives first 20 projects in the group.

curl --header "PRIVATE-TOKEN: xxxxxxxxxxxxxxx" https://gitlab.your_namespace.com/api/v4/groups/your_group_id/projects

To get more projects we should add 'page' and 'per_page' parameter.

The below request will fetch you up to 100 projects under requested group.

 curl --header "PRIVATE-TOKEN: xxxxxxxxxxxxxxx" https://gitlab.your_namespace.com/api/v4/groups/your_group_id/projects?&per_page=100" .  

If you now want all projects, you have to loop through the pages. Change the page parameter.

Add json_pp to your request to get a nicely formatted output.

curl --header "PRIVATE-TOKEN: xxxxxxxxxxxxxxx" https://gitlab.your_namespace.com/api/v4/groups/your_group_id/projects | json_pp
🌐
Python GitLab
python-gitlab.readthedocs.io › en › stable › gl_objects › groups.html
Groups - python-gitlab v8.5.0
first_group_project = ... last_activity_at ... On GitLab.com, creating top-level groups is currently not permitted using the API. You can only use the API to create subgroups....
🌐
GitHub
github.com › python-gitlab › python-gitlab › issues › 1176
Get all projects inside the subgroups not listing all projects · Issue #1176 · python-gitlab/python-gitlab
September 5, 2020 - gl = gitlab.Gitlab(options.url, options.token) group = gl.groups.get(options.namespace, lazy=True, include_subgroups=True) projects = [] # Get all projects inside the namespace for project in group.projects.list( all=True, owned=False ): projects.append(project) # print(" found " + project.path_with_namespace) # Get all projects inside the subgroups for group in gl.groups.list( all=True, owned=False, query_parameters={"id": options.namespace} ): for project in group.projects.list(all=True): projects.append(project) print("Auto DevOps is", project.auto_devops_enabled, "for", project.path_with_namespace)
Author: python-gitlab
🌐
GitHub
github.com › johannesjo › super-productivity › issues › 2529
Support GitLab groups/subgroups when querying API for projects/issues · Issue #2529 · super-productivity/super-productivity
March 22, 2023 - From what I can tell, the official GitLab API docs don't mention that specific endpoint: https://docs.gitlab.com/ee/api/rest/index.html · If you instead use the /groups/<group>%2<subgroup>/projects (the %2 is important) endpoint to get a list ...
Author: super-productivity
Top answer
1 of 4
1

So, inspired by the answer of sytech, I found out that it was not working in the first place, as the shared projects were still hidden in the subgroups. So I came up with the following code that digs through all various levels of subgroups to find all shared projects. I assume this can be written way more elegant, but it works for me:

# group definition
main_group_id = 11111

# create empty list that will contain final result
list_subgroups_id_all = []

# create empty list that act as temporal storage of the results outside the function
list_subgroups_id_stored = []



# function to create a list of subgroups of a group (id)
def find_subgroups(group_id):

    # retrieve group object
    group = gl.groups.get(group_id)

    # create empty lists to store id of subgroups
    list_subgroups_id = []

    #iterate through group to find id of all subgroups
    for sub in group.subgroups.list():
        list_subgroups_id.append(sub.id)

    return(list_subgroups_id)


# function to iterate over the various groups for subgroup detection
def iterate_subgroups(group_id, list_subgroups_id_all):

    # for a given id, find existing subgroups (id) and store them in a list
    list_subgroups_id = find_subgroups(group_id)

    # add the found items to the list storage variable, so that the results are not overwritten
    list_subgroups_id_stored.append(list_subgroups_id)

    # for each found subgroup_id, test if it is already part of the total id list
    # if not, keep store it and test for more subgroups
    for test_id in list_subgroups_id:
        if test_id not in list_subgroups_id_all:

            # add it to total subgroup id list (final results list)
            list_subgroups_id_all.append(test_id)

            # check whether test_id contains more subgroups
            list_subgroups_id_tmp = iterate_subgroups(test_id, list_subgroups_id_all)

            #if so, append to stored subgroup list that is currently checked
            list_subgroups_id_stored.append(list_subgroups_id_tmp)

    return(list_subgroups_id_all)

# find all subgroup and subsubgroups, etc... store ids in list
list_subgroups_id_all = iterate_subgroups(main_group_id , list_subgroups_id_all)

print("***ids of all subgroups***")
print(list_subgroups_id_all)
print("")

print("***names of all subgroups***")
list_names = []
for ids in list_subgroups_id_all:
    group = gl.groups.get(ids)
    group_name = group.attributes['name']
    list_names.append(group_name)
print(list_names)
#print(list_subgroups_name_all)
print("")

# print all directly integrated projects of the main group, also those in subgroups
print("***integrated projects***")
group = gl.groups.get(main_group_id)
projects=group.projects.list(include_subgroups=True, all=True)
for prj in projects:
    print(prj.attributes['name'])
print("")

# print all shared projects
print("***shared projects***")
for sub in list_subgroups_id_all:
    group = gl.groups.get(sub)
    for shared_prj in group.shared_projects:
        print(shared_prj['path_with_namespace'])
print("")

One question that remains - at the very beginning I retrieve the main group by its id (here: 11111), but can I actually also get this id by looking for the name of the group? Something like: group_id = gl.group.get(attribute={'name','foo'}) (not working)?

2 of 4
1

This code will query all the projects in each subgroup and handle multiple subgroups inside a subgroup as well. it works perfectly and I hope it helps someone else.

import gitlab
import os

# Set your GitLab API access token
access_token = 'GITLAB_ACCESS_TOKEN'
if not access_token:
    raise ValueError("No GitLab access token found. Please set the GITLAB_ACCESS_TOKEN environment variable.")

# Set the URL of your GitLab instance
gitlab_url = os.getenv('GITLAB_URL', 'https://gitLab.com/')

# Replace this with your target subgroup path
subgroup_path = '2323' #'your/subgroup/path or your subgroup number'

# Initialize the GitLab connection
gl = gitlab.Gitlab(gitlab_url, private_token=access_token)

# Recursively find all projects in the subgroup and its subgroups
def find_projects_in_group(group):
    projects = gl.groups.get(group.id).projects.list(all=True)
    
    subgroups = gl.groups.get(group.id).subgroups.list(all=True)
    
    for subgroup in subgroups:
        projects.extend(find_projects_in_group(subgroup))
    return projects

# Find the target subgroup
try:
    target_group = gl.groups.get(subgroup_path)
except gitlab.exceptions.GitlabGetError:
    raise ValueError("Subgroup not found: " + subgroup_path)

# Get the list of projects
projects = find_projects_in_group(target_group)

# Print the list of projects
for project in projects:
    print("project path:["+project.ssh_url_to_repo+"]" )
Find elsewhere
🌐
ETSI
forge.etsi.org › help › help
Groups · Api · Help · GitLab
Calculated as the sum of all repository ... group's projects and subgroups. Available only when the container registry metadata database is enabled. container_registry_size_is_estimated: Indicates whether the size is an exact calculation based on actual data from all repositories (false) or estimated due to performance constraints (true). For GitLab Self-Managed ...
🌐
GitLab
gitlab.com › gitlab.org › #219943
API Enhancement: List all, including nested, subgroups (#219943) · Issues · GitLab.org / GitLab · GitLab
API Enhancement: List all, including ... to solve The `/groups/<grp>/projects` endpoint accepts the query parameter `include_subgroups=true` to include all projects under the group in the list, even those nested under other subgroups...
🌐
GitLab
polaris.cse.unr.edu › gitlab › help › api › groups.md
Groups · Api · Help · GitLab
GET /groups/:id/subgroups · [ { "id": 1, "name": "Foobar Group", "path": "foo-bar", "description": "An interesting group", "visibility": "public", "lfs_enabled": true, "avatar_url": "http://gitlab.example.com/uploads/group/avatar/1/foo.jpg", "web_url": "http://gitlab.example.com/groups/foo-bar", "request_access_enabled": false, "full_name": "Foobar Group", "full_path": "foo-bar", "file_template_project_id": 1, "parent_id": 123 } ] Get a list of projects in this group.
🌐
GitLab
forum.gitlab.com › how to use gitlab
How to get the all project IDs (about 250 projects) within a given Group in GitLab by using API curl - How to Use GitLab - GitLab Forum
June 17, 2021 - I use following part of the bash script to retrieve all IDs of the projects within a given GitLab group using API calls. There are about 250 projects in the group. But when use this script it only retrieves 100 projects ids. How do I retrieve all of the project ids? page=1 #------Retrieve the IDs of the non archived projects in the group while [[ “$page” != “0” ]] do urlCheck=curl -s "$GIT_API/groups?private_token=$GIT_TOKEN&per_page=100&page=$page" | jq -r ".[] | .name" if [[ -n $urlCheck...
Top answer
1 of 2
1

I also have not found any API to help me, and then write a script to do that.

CURRENT_DIR=$(dirname "$0")
GITLAB_SITE="<gitlab site>"
GITLAB_GROUP="<group>"
GITLAB_ACCESS_TOKEN="<access token>"

#### get projects url #####
url_file=$(mktemp)
temp_file=$(mktemp)
for ((page=1; ; page+=1)); do
  # iterate all pages
  url="${GITLAB_SITE}/api/v4/projects?per_page=100&page=${page}"
  data=$(curl  --request GET --header "PRIVATE-TOKEN: ${GITLAB_ACCESS_TOKEN}" $url )
  [ $(jq length <<< "$data") -eq 0 ] && break

  echo "$data" \
  | jq -r --arg GITLAB_GROUP "$GITLAB_GROUP" '.[] | select(.path_with_namespace | startswith("smartcompany")) | [.id] | @csv' \
  | while read -r id; do echo "${GITLAB_SITE}/api/v4/projects/${id}/members/all" >> ${url_file} ; done
done

#### get groups url #####
temp_file=$(mktemp)
for ((page=1; ; page+=1)); do
  # iterate all pages
  url="${GITLAB_SITE}/api/v4/groups?per_page=100&page=${page}"
  data=$(curl  --request GET --header "PRIVATE-TOKEN: ${GITLAB_ACCESS_TOKEN}" $url )
  [ $(jq length <<< "$data") -eq 0 ] && break

  echo "$data" \
  | jq -r --arg GITLAB_GROUP "$GITLAB_GROUP" '.[] | select(.full_path | test("^" + $GITLAB_GROUP + "(/|$)")) | [.id] | @csv' \
  | while read -r id; do echo "${GITLAB_SITE}/api/v4/groups/${id}/members/all" >> ${url_file} ; done
done


#### get menbers ####
tmp_members="$(mktemp)"
while IFS= read -r url
do
  for ((page=1; ; page+=1)); do
    url="${url}?per_page=100&page=${page}"
    data=$(curl  --request GET --header "PRIVATE-TOKEN: ${GITLAB_ACCESS_TOKEN}" $url )
  [ $(jq length <<< "$data") -eq 0 ] && break

    # data
    echo "$data" | jq -r '.[] | [.id,.name] | @csv' >> $tmp_members
  done

done < "${url_file}"

#### remove duplication ####
members_csv="${CURRENT_DIR}/users-$(date '+%Y-%m-%d').csv"
echo "id,name" > "${members_csv}"
sort -n ${tmp_members} | uniq >> "${members_csv}"
2 of 2
1

GitLab offers the option to get the inherited members using:

GET /groups/:id/members/all
GET /projects/:id/members/all

That will retrieve all the members and permissions through the ancestor groups, but not the children groups. This makes sense since let's say that you retrieve all the users from a group, including those that are only in a single project... How do you know to which project do they belong?

Anyway, there is an issue from two years ago where they were debating about the implementation of what you require in a single API call, but it doesn't seem that is implemented right now.

🌐
GitLab
forum.gitlab.com › community › gitlab for open source
How to get group, subgroup, and project name separately via REST API? - GitLab for Open Source - GitLab Forum
January 8, 2026 - Hi everyone, When I fetch project details using the GitLab REST API, I only get the full path in the path_with_namespace field (e.g., Group1/group1.1/group1.1.1/projecttest1). Is there any way to get the group, subgrou…
Top answer
1 of 9
98

If only your private token is available, you can only use the API:

PROJECTS

Use the following command to request projects:

curl "https://<host>/api/v4/projects?private_token=<your private token>"

This will return you the first 20 entries. To get more you can add the paramater per_page

curl "https://<host>/api/v4/projects?private_token=<your private token>&per_page=100"

with this parameter you can request between 20and 100 entries (see REST API Pagination documentation).

If you now want all projects, you have to loop through the pages. To get to another page add the parameter page.

curl "https://<host>/api/v4/projects?private_token=<your private token>&per_page=100&page=<page_number>"

Now you may want to know how many pages there are. For that, add the curl parameter --head. This will not return the payload, but the header.

The result should look like this:

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 13 Jul 2017 17:43:24 GMT
Content-Type: application/json
Content-Length: 29428
Cache-Control: no-cache
Link: <request link>
Vary: Origin
X-Frame-Options: SAMEORIGIN
X-Next-Page: 2
X-Page: 1
X-Per-Page: 20
X-Prev-Page:
X-Request-Id: 80ecc167-4f3f-4c99-b09d-261e240e7fe9
X-Runtime: 4.117558
X-Total: 312257
X-Total-Pages: 15613
Strict-Transport-Security: max-age=31536000

The two interesting parts here are X-Totaland X-Total-Pages. The first is the count of available entries and the second the count of total pages.

I suggest to use python or some other kind of script to handle the requests and concat the results at the end.

If you want to refine the search, consult this wiki page: https://docs.gitlab.com/api/projects.html#projects-api

GROUPS

For groups simply replace projects with groups in the curls. https://docs.gitlab.com/api/groups.html#list-groups


UPDATE:

Here is the official list of Gitlab API clients/wrappers: https://docs.gitlab.com/api/rest/third_party_clients/

I highly recommend using one of these.

2 of 9
10

In bash for Gitlab API V4:

#!/bin/bash
GL_DOMAIN=""
GL_TOKEN=""
echo "" > gitlab_projects_urls.txt
for ((i=1; ; i+=1)); do
    contents=$(curl "$GL_DOMAIN/api/v4/projects?private_token=$GL_TOKEN&per_page=100&page=$i")
    if jq -e '. | length == 0' >/dev/null; then 
       break
    fi <<< "$contents"
    echo "$contents" | jq -r '.[].ssh_url_to_repo' >> gitlab_projects_urls.txt
done
🌐
GitLab
forum.gitlab.com › general
Get project ID within multiple subgroups - General - GitLab Forum
February 9, 2023 - Hello there! How can I get the ID of a project which is inside multiple subgroups via API, for example: my_group/group1/group2/group3/my_project How can I get the ID of my_project using the GitLab API? I’ve found this (Groups API | GitLab) but with it I can only list projects until my_group/group1.