๐ฅ Recipe ยท User & Group Management
Enable Admin SDK API and list Google Workspace group members
Search for a group by name, paginate through its full membership, and export the roster to CSV using the Google Admin Directory API
Complexity
Intermediate
Impact
user-management + audit + reporting + google-workspace
Context
Why This Matters
Admins are frequently asked to produce the definitive list of who belongs to a company-wide distribution or security group โ e.g. "all employees", "all managers", or a department roster. While the Google Admin console exposes this in the UI, it tops out at a few hundred rows, does not export cleanly, and forces you to click into each group one at a time.
This recipe walks through the programmatic path: enabling the Admin SDK API in your Google Cloud project, granting the right OAuth scopes, locating a group whose display name may not exactly match what the requester called it, and paginating the members endpoint to export a complete, sorted CSV.
Run this recipe when you need an auditable snapshot of group membership for access reviews, HR headcount reconciliation, license reviews, or mail-merge distribution lists.
Expected Outcomes
You will have:
- The Admin SDK API enabled in your Google Cloud project (a one-time prerequisite).
- Confirmed the correct group email when the display name is ambiguous (e.g. "all employees" โ
sysaid-all@domain.com). - A complete, paginated list of group members โ including nested groups, suspended accounts, and external members.
- A sorted CSV export (
email,role,status,type) suitable for HR or audit handoff. - A reusable script you can point at any group email in the future.
Risks & Considerations
Warnings & gotchas
- Admin SDK API must be enabled. The first call returns
HTTP 403: Admin SDK API has not been used in project <N> before or it is disabled. After enabling, wait 1โ2 minutes for propagation before retrying. - Scope consent is separate from API enablement. Granting
admin.directory.group.readonlyandadmin.directory.group.member.readonlyis a distinct step โ a 403 after enabling the API usually means missing scopes. - Group display names are not unique. A request for "all employees" may resolve to Sysaid All, All Managers, Engineering All, etc. Always confirm with the requester before exporting.
- Query syntax is picky. The
queryparameter on/groupsdoes not supportname:valuelike the users endpoint โ it only acceptsmemberKey=. Use client-side filtering on the full list instead. - Pagination is required. Default
maxResultsis 200. A group with 234 members will silently truncate unless you follownextPageToken. - Privacy. Member email lists are sensitive. Store the CSV in a restricted location and purge after use per your data retention policy.
- Nested groups. If a member has
type=GROUP, the roster is not flat โ you may need to recursively expand to get the true user set.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| Admin SDK API enabled in GCP project | Required before any Directory API call will succeed โ API is disabled by default. |
| https://www.googleapis.com/auth/admin.directory.group.readonly | List and read group metadata (name, email, member count). |
| https://www.googleapis.com/auth/admin.directory.group.member.readonly | List members of a specific group. |
| Google Workspace Super Admin or delegated Groups Admin role | Required to invoke Directory API endpoints with <code>customer=my_customer</code> or <code>domain=</code> parameters. |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
For End Users
How an employee would ask Dex for help
Step-by-step: Google Admin console
1. Open the Groups list
admin.google.com โ Directory โ Groups
2. Search for the group
Use the search bar at the top of the Groups page. Because display names are not unique, try partial matches like all or employees and review results carefully. Note the group's email address โ that's the unique key.
3. Open the group
Click the group name to open its details page, then select the Members tab.
4. Export members
- Click Members in the left sidebar of the group page.
- Click the Download members button (cloud-download icon) in the top-right.
- Choose All members and click Download. A CSV is emailed to you and also available under in the Admin console.
5. Verify counts
Compare the row count in the downloaded CSV to the Direct members count shown on the group overview. If they differ, the group likely contains nested groups โ expand them separately or use the API recipe below.
Note: the Admin console export is limited to direct members and does not include suspended or external accounts flagged as such. For audit-grade output, use the API.
Google Admin Directory API
Prerequisite: enable the Admin SDK API
Visit https://console.developers.google.com/apis/api/admin.googleapis.com/overview?project={PROJECT_ID} and click Enable. Wait 60โ120 seconds before your first call.
1. List groups in the domain
GET https://admin.googleapis.com/admin/directory/v1/groups?domain={domain}&maxResults=200
Authorization: Bearer {access_token}Paginate via nextPageToken until all groups are retrieved. The query parameter on this endpoint only accepts memberKey=, not name: โ filter client-side on name or email.
2. Get a specific group by email (if you know it)
GET https://admin.googleapis.com/admin/directory/v1/groups/{group_email}Returns 404 if the email is wrong โ confirm via step 1 if unsure.
3. List members with pagination
GET https://admin.googleapis.com/admin/directory/v1/groups/{group_email}/members?maxResults=200Response shape:
{
"kind": "admin#directory#members",
"members": [
{
"email": "user@domain.com",
"role": "MEMBER",
"type": "USER",
"status": "ACTIVE"
}
],
"nextPageToken": "..."
}Follow nextPageToken until absent. Each member has type of USER, GROUP, CUSTOMER, or EXTERNAL โ decide whether to recursively expand nested groups.
Common errors
| Status | Meaning | Fix |
|---|---|---|
| 403 insufficient authentication scopes | OAuth token missing directory scopes | Re-consent with admin.directory.group.readonly + admin.directory.group.member.readonly |
| 403 Admin SDK API has not been used... | API disabled in GCP project | Enable at the console URL above, wait 2 min |
| 404 Resource Not Found: groupKey | Group email does not exist | List groups first to confirm the email |
| 400 Invalid Input: name:value | Unsupported query syntax on /groups | List all groups and filter client-side |
Bash script walkthrough
The downloadable script below uses gcloud (for obtaining an access token) and curl + jq to list a group's members and export them to CSV. It handles pagination automatically.
Prerequisites
gcloudCLI installed and authenticated as a Workspace admin with the required scopes:gcloud auth application-default login --scopes=\ https://www.googleapis.com/auth/admin.directory.group.readonly,\ https://www.googleapis.com/auth/admin.directory.group.member.readonly,\ https://www.googleapis.com/auth/cloud-platformjqinstalled (brew install jq/apt install jq).- Admin SDK API enabled in the active GCP project.
Usage
./list-group-members.sh --group all-employees@domain.com --out members.csv
./list-group-members.sh --search "all" --domain domain.com # find candidatesWhat it does
- Acquires an access token via
gcloud auth application-default print-access-token. - If
--searchis given, paginates/groupsand prints matches (name, email, member count) for you to pick from. - If
--groupis given, paginates/groups/{key}/membersusingnextPageToken. - Writes a sorted CSV with columns
email,role,status,type. - Reports HTTP errors with actionable hints (403 scopes, 404 not found, API not enabled).
Next steps