Skip to main content

Overview

The Public Groups API enables programmatic management of organization groups for access control.
Groups are only available on Teams and Enterprise plans.

List Groups

Retrieve all groups in the organization.
GET /public/groups

Response

object
string
Always “list”
data
array
required
Array of group objects

Group Object

id
string
required
Group unique identifier
name
string
required
Group name
externalId
string
External identifier for directory sync
collections
array
Collection access assignments

Get Group

Retrieve details of a specific group.
GET /public/groups/{id}
id
string
required
Group ID
curl -X GET "https://api.bitwarden.com/public/groups/{id}" \
  -H "Authorization: Bearer {org_api_token}"

Get Group Member IDs

Retrieve all member IDs in a group.
GET /public/groups/{id}/member-ids
id
string
required
Group ID

Response

Returns an array of organization user IDs:
[
  "member-guid-1",
  "member-guid-2"
]

Create Group

Create a new group.
curl -X POST "https://api.bitwarden.com/public/groups" \
  -H "Authorization: Bearer {org_api_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Engineering Team",
    "externalId": "eng_team_001",
    "collections": [
      {
        "id": "collection-guid",
        "readOnly": false,
        "hidePasswords": false
      }
    ]
  }'

Request Body

name
string
required
Group name
externalId
string
External identifier for directory sync (LDAP/SCIM)
collections
array
required
Collection access assignments

Collection Assignment

id
string
required
Collection ID
readOnly
boolean
default:"false"
Read-only access
hidePasswords
boolean
default:"false"
Hide password fields

Update Group

Update an existing group.
PUT /public/groups/{id}
id
string
required
Group ID

Request Body

Provide complete group object with all fields.
curl -X PUT "https://api.bitwarden.com/public/groups/{id}" \
  -H "Authorization: Bearer {org_api_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Engineering - Updated",
    "collections": [
      {
        "id": "collection-guid-1",
        "readOnly": false
      },
      {
        "id": "collection-guid-2",
        "readOnly": true
      }
    ]
  }'
Provide the complete collections array. Any collections not included will be removed from the group.

Update Group Member IDs

Update which members belong to a group.
PUT /public/groups/{id}/member-ids
id
string
required
Group ID
memberIds
array
required
Complete array of organization user IDs
{
  "memberIds": [
    "member-guid-1",
    "member-guid-2",
    "member-guid-3"
  ]
}

Delete Group

Permanently delete a group.
DELETE /public/groups/{id}
id
string
required
Group ID to delete
curl -X DELETE "https://api.bitwarden.com/public/groups/{id}" \
  -H "Authorization: Bearer {org_api_token}"
Deleting a group removes members from the group but doesn’t delete the members themselves.

Use Cases

Sync from Active Directory

import ldap
import requests

# Connect to AD
ldap_conn = ldap.initialize('ldap://dc.company.com')
ldap_conn.simple_bind_s('[email protected]', 'password')

# Get AD groups
result = ldap_conn.search_s(
    'OU=Groups,DC=company,DC=com',
    ldap.SCOPE_SUBTREE,
    '(objectClass=group)'
)

for dn, attrs in result:
    group_name = attrs['cn'][0].decode()
    external_id = attrs['distinguishedName'][0].decode()
    
    # Create in Bitwarden
    requests.post(
        'https://api.bitwarden.com/public/groups',
        headers={'Authorization': f'Bearer {org_token}'},
        json={
            'name': group_name,
            'externalId': external_id,
            'collections': []
        }
    )

Automated Team Setup

// Create groups for new team
const teams = ['Engineering', 'Product', 'Design'];
const groupIds = {};

for (const team of teams) {
  const response = await fetch(
    'https://api.bitwarden.com/public/groups',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${orgToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: team,
        collections: [
          {id: teamCollections[team], readOnly: false}
        ]
      })
    }
  );
  
  const group = await response.json();
  groupIds[team] = group.id;
}

// Assign members to groups
const memberAssignments = {
  '[email protected]': ['Engineering'],
  '[email protected]': ['Product', 'Design'],
  '[email protected]': ['Engineering', 'Product']
};

for (const [email, teams] of Object.entries(memberAssignments)) {
  // Find member by email
  const members = await fetch(
    'https://api.bitwarden.com/public/members',
    {headers: {'Authorization': `Bearer ${orgToken}`}}
  ).then(r => r.json());
  
  const member = members.data.find(m => m.email === email);
  if (member) {
    // Update member's groups
    const groupIdsForMember = teams.map(t => groupIds[t]);
    await fetch(
      `https://api.bitwarden.com/public/members/${member.id}/group-ids`,
      {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${orgToken}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({groupIds: groupIdsForMember})
      }
    );
  }
}

Audit Group Membership

#!/bin/bash

# Generate report of all groups and members

GROUPS=$(curl -s "https://api.bitwarden.com/public/groups" \
  -H "Authorization: Bearer $ORG_API_TOKEN")

echo "Group Membership Report"
echo "======================"
echo ""

echo $GROUPS | jq -r '.data[] | .id' | while read GROUP_ID; do
  GROUP_NAME=$(echo $GROUPS | jq -r ".data[] | select(.id==\"$GROUP_ID\") | .name")
  
  MEMBERS=$(curl -s "https://api.bitwarden.com/public/groups/${GROUP_ID}/member-ids" \
    -H "Authorization: Bearer $ORG_API_TOKEN")
  
  MEMBER_COUNT=$(echo $MEMBERS | jq '. | length')
  
  echo "$GROUP_NAME: $MEMBER_COUNT members"
done

Build docs developers (and LLMs) love