# Group service

Service for managing groups within an organization

OpenAPI file: [`nominal.authentication.groups.v1.json`](https://dev.nominal.io/api/_downloads/0a573ba593ff61e38c99ab9975c62fc6/nominal.authentication.groups.v1.json)

## Endpoints

### Create or update group

POST `/authentication/groups/v1`

Org-scoped upsert.

Creates a new group if Group.rid is empty in the request (server assigns the rid). Both Group.org_rid and Group.group_id are required on create, and the new group_id must be unique within the organization.

Updates an existing group if Group.rid is present in the request. Group.org_rid and Group.group_id are immutable: when set on the update request they must match the existing values, but they may be omitted to leave them unchanged. Fields in the group message marked as OUTPUT_ONLY are ignored when present in the input request. All other mutable fields are fully overwritten, and will be cleared if not set in the request.

Throws HTTP 400 / gRPC 3 if a supplied immutable field does not match the existing group. Throws HTTP 404 / gRPC 5 if the group identified by Group.rid for an update does not exist. Throws HTTP 409 / gRPC 6 if a create would result in duplicate group_ids within the organization. Throws HTTP 403 / gRPC 7 if the caller is not authorized.

Body

`group` [`Group`](https://dev.nominal.io/api/rest/group-service.md#group) required
:   ​

    Fields of `Group`

    `rid` string
    :   ​

    `orgRid` string
    :   Required on create requests; immutable on updates.

    `groupId` string
    :   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

    `displayName` string
    :   ​

    `description` string
    :   ​

    `userRids` array of string output only
    :   The list of users in this group.

    `createdAt` string (date-time) output only
    :   ​

    `updatedAt` string (date-time) output only
    :   ​

    `symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
    :   Symbol to identify groups

        Fields of `Symbol`

        one of `icon`, `emoji`, `image` required
        :   ​

            **icon**

            `icon` string
            :   Icon name (e.g. castle)

            **emoji**

            `emoji` string
            :   Emoji name (e.g. :castle:)

            **image**

            `image` string
            :   Image url (e.g. https://example.com/image.png)

    `membershipManagedManually` boolean
    :   Whether group membership is managed manually in Nominal. Defaults to false.

Response

`rid` string
:   ​

`orgRid` string
:   Required on create requests; immutable on updates.

`groupId` string
:   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

`displayName` string
:   ​

`description` string
:   ​

`userRids` array of string
:   The list of users in this group.

`createdAt` string (date-time)
:   ​

`updatedAt` string (date-time)
:   ​

`symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
:   Symbol to identify groups

    Fields of `Symbol`

    one of `icon`, `emoji`, `image`
    :   ​

        **icon**

        `icon` string
        :   Icon name (e.g. castle)

        **emoji**

        `emoji` string
        :   Emoji name (e.g. :castle:)

        **image**

        `image` string
        :   Image url (e.g. https://example.com/image.png)

`membershipManagedManually` boolean
:   Whether group membership is managed manually in Nominal. Defaults to false.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/authentication/groups/v1" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "group": {
    "rid": "<rid>",
    "orgRid": "<org rid>",
    "groupId": "<group id>",
    "displayName": "<display name>",
    "description": "<description>",
    "symbol": {
      "icon": "<icon>"
    },
    "membershipManagedManually": true
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "group": {
            "rid": "<rid>",
            "orgRid": "<org rid>",
            "groupId": "<group id>",
            "displayName": "<display name>",
            "description": "<description>",
            "symbol": {"icon": "<icon>"},
            "membershipManagedManually": True,
        },
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "group": {
            "rid": "<rid>",
            "orgRid": "<org rid>",
            "groupId": "<group id>",
            "displayName": "<display name>",
            "description": "<description>",
            "symbol": {"icon": "<icon>"},
            "membershipManagedManually": True,
        },
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/authentication/groups/v1",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "group": {
                    "rid": "<rid>",
                    "orgRid": "<org rid>",
                    "groupId": "<group id>",
                    "displayName": "<display name>",
                    "description": "<description>",
                    "symbol": {"icon": "<icon>"},
                    "membershipManagedManually": True,
                },
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "rid": "<rid>",
  "orgRid": "<org rid>",
  "groupId": "<group id>",
  "displayName": "<display name>",
  "description": "<description>",
  "userRids": [
    "<user rids>"
  ],
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z",
  "symbol": {
    "icon": "<icon>"
  },
  "membershipManagedManually": true
}
```

### Get groups

POST `/authentication/groups/v1/batch-get`

Get batch of groups within the user’s organization

Body

The body is an array of string.

Response

The body is a map of string to [`Group`](https://dev.nominal.io/api/rest/group-service.md#group).

Fields of `Group`

`rid` string
:   ​

`orgRid` string
:   Required on create requests; immutable on updates.

`groupId` string
:   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

`displayName` string
:   ​

`description` string
:   ​

`userRids` array of string
:   The list of users in this group.

`createdAt` string (date-time)
:   ​

`updatedAt` string (date-time)
:   ​

`symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
:   Symbol to identify groups

    Fields of `Symbol`

    one of `icon`, `emoji`, `image`
    :   ​

        **icon**

        `icon` string
        :   Icon name (e.g. castle)

        **emoji**

        `emoji` string
        :   Emoji name (e.g. :castle:)

        **image**

        `image` string
        :   Image url (e.g. https://example.com/image.png)

`membershipManagedManually` boolean
:   Whether group membership is managed manually in Nominal. Defaults to false.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/authentication/groups/v1/batch-get" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '[
  "string"
]'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1/batch-get",
    headers={"Authorization": "Bearer <api key>"},
    json=["string"],
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1/batch-get",
    headers={"Authorization": "Bearer <api key>"},
    json=["string"],
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/authentication/groups/v1/batch-get",
            headers={"Authorization": "Bearer <api key>"},
            json=["string"],
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "<key>": {
    "rid": "<rid>",
    "orgRid": "<org rid>",
    "groupId": "<group id>",
    "displayName": "<display name>",
    "description": "<description>",
    "userRids": [
      "<user rids>"
    ],
    "createdAt": "2026-01-01T00:00:00Z",
    "updatedAt": "2026-01-01T00:00:00Z",
    "symbol": {
      "icon": "<icon>"
    },
    "membershipManagedManually": true
  }
}
```

### Get group by ID

GET `/authentication/groups/v1/id/{groupId}`

Gets a group by its ID within the user’s organization

Path parameters

`groupId` string required
:   ​

Response

`rid` string
:   ​

`orgRid` string
:   Required on create requests; immutable on updates.

`groupId` string
:   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

`displayName` string
:   ​

`description` string
:   ​

`userRids` array of string
:   The list of users in this group.

`createdAt` string (date-time)
:   ​

`updatedAt` string (date-time)
:   ​

`symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
:   Symbol to identify groups

    Fields of `Symbol`

    one of `icon`, `emoji`, `image`
    :   ​

        **icon**

        `icon` string
        :   Icon name (e.g. castle)

        **emoji**

        `emoji` string
        :   Emoji name (e.g. :castle:)

        **image**

        `image` string
        :   Image url (e.g. https://example.com/image.png)

`membershipManagedManually` boolean
:   Whether group membership is managed manually in Nominal. Defaults to false.

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/authentication/groups/v1/id/<group id>" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.get(
    "https://api.gov.nominal.io/api/authentication/groups/v1/id/<group id>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/authentication/groups/v1/id/<group id>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/authentication/groups/v1/id/<group id>",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "rid": "<rid>",
  "orgRid": "<org rid>",
  "groupId": "<group id>",
  "displayName": "<display name>",
  "description": "<description>",
  "userRids": [
    "<user rids>"
  ],
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z",
  "symbol": {
    "icon": "<icon>"
  },
  "membershipManagedManually": true
}
```

### Search groups

POST `/authentication/groups/v1/search`

Searches all groups in the user’s organization using given query

Body

`pageSize` integer
:   Page sizes greater than 1_000 will be rejected. Default pageSize is 100.

`nextPageToken` string
:   ​

`query` [`SearchGroupsQuery`](https://dev.nominal.io/api/rest/group-service.md#searchgroupsquery) required
:   ​

    Fields of `SearchGroupsQuery`

    one of `exactSubstringText`, `and`, `or`, `memberUsers`
    :   ​

        **exactSubstringText**

        `exactSubstringText` string
        :   ​

        **and**

        `and` [`SearchQueryAnd`](https://dev.nominal.io/api/rest/group-service.md#searchqueryand)
        :   and is implemented to allow for list (use SearchQueryAnd([]))

            Fields of `SearchQueryAnd`

            `queries` array of [`SearchGroupsQuery`](https://dev.nominal.io/api/rest/group-service.md#searchgroupsquery)
            :   ​

        **or**

        `or` [`SearchQueryOr`](https://dev.nominal.io/api/rest/group-service.md#searchqueryor)
        :   ​

            Fields of `SearchQueryOr`

            `queries` array of [`SearchGroupsQuery`](https://dev.nominal.io/api/rest/group-service.md#searchgroupsquery)
            :   ​

        **memberUsers**

        `memberUsers` [`SearchQueryMemberUsers`](https://dev.nominal.io/api/rest/group-service.md#searchquerymemberusers)
        :   ​

            Fields of `SearchQueryMemberUsers`

            `userRids` array of string
            :   1 to 1,000 items. Each item: at most 256 characters.

Response

`results` array of [`Group`](https://dev.nominal.io/api/rest/group-service.md#group)
:   ​

    Fields of `Group`

    `rid` string
    :   ​

    `orgRid` string
    :   Required on create requests; immutable on updates.

    `groupId` string
    :   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

    `displayName` string
    :   ​

    `description` string
    :   ​

    `userRids` array of string
    :   The list of users in this group.

    `createdAt` string (date-time)
    :   ​

    `updatedAt` string (date-time)
    :   ​

    `symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
    :   Symbol to identify groups

        Fields of `Symbol`

        one of `icon`, `emoji`, `image`
        :   ​

            **icon**

            `icon` string
            :   Icon name (e.g. castle)

            **emoji**

            `emoji` string
            :   Emoji name (e.g. :castle:)

            **image**

            `image` string
            :   Image url (e.g. https://example.com/image.png)

    `membershipManagedManually` boolean
    :   Whether group membership is managed manually in Nominal. Defaults to false.

`nextPageToken` string
:   ​

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/authentication/groups/v1/search" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "query": {
    "exactSubstringText": "<exact substring text>"
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1/search",
    headers={"Authorization": "Bearer <api key>"},
    json={"query": {"exactSubstringText": "<exact substring text>"}},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1/search",
    headers={"Authorization": "Bearer <api key>"},
    json={"query": {"exactSubstringText": "<exact substring text>"}},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/authentication/groups/v1/search",
            headers={"Authorization": "Bearer <api key>"},
            json={"query": {"exactSubstringText": "<exact substring text>"}},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "results": [
    {
      "rid": "<rid>",
      "orgRid": "<org rid>",
      "groupId": "<group id>",
      "displayName": "<display name>",
      "description": "<description>",
      "userRids": [
        "<user rids>"
      ],
      "createdAt": "2026-01-01T00:00:00Z",
      "updatedAt": "2026-01-01T00:00:00Z",
      "symbol": {
        "icon": "<icon>"
      },
      "membershipManagedManually": true
    }
  ],
  "nextPageToken": "<next page token>"
}
```

### Create group membership

POST `/authentication/groups/v1/{groupMembership.key.groupRid}/memberships`

Adds a member to a manually managed group. Re-adding an existing member is a no-op. Throws HTTP 400 / gRPC 3 if group_rid or member_rid is missing, or member_rid is not a supported RID type. Throws HTTP 403 / gRPC 7 if the caller is not authorized to update the group, including when the group does not exist. The permission check runs before the group lookup so unknown groups are not disclosed. Throws HTTP 400 / gRPC 3 if the target user is not in the group’s organization. Throws HTTP 400 / gRPC 3 if the group’s membership is not managed manually.

Path parameters

`groupMembership.key.groupRid` string required
:   At most 256 characters.

Body

`key` object
:   Identity is a nested key so delete can address a membership without the full resource, which may gain fields later. Identity is a nested key so delete can address a membership without the full resource, which may gain fields later.

Response

`key` [`GroupMembershipKey`](https://dev.nominal.io/api/rest/group-service.md#groupmembershipkey)
:   Identity is a nested key so delete can address a membership without the full resource, which may gain fields later.

    Fields of `GroupMembershipKey`

    `groupRid` string
    :   At most 256 characters.

    `memberRid` string
    :   The member of the group. Only user RIDs are accepted today. At most 256 characters.

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/authentication/groups/v1/<group membership.key.group rid>/memberships" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "key": {
    "memberRid": "<member rid>"
  }
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<group membership.key.group rid>/memberships",
    headers={"Authorization": "Bearer <api key>"},
    json={"key": {"memberRid": "<member rid>"}},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<group membership.key.group rid>/memberships",
    headers={"Authorization": "Bearer <api key>"},
    json={"key": {"memberRid": "<member rid>"}},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/authentication/groups/v1/<group membership.key.group rid>/memberships",
            headers={"Authorization": "Bearer <api key>"},
            json={"key": {"memberRid": "<member rid>"}},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "key": {
    "groupRid": "<group rid>",
    "memberRid": "<member rid>"
  }
}
```

### Get group

GET `/authentication/groups/v1/{groupRid}`

Get group within the user’s organization

Path parameters

`groupRid` string required
:   ​

Response

`rid` string
:   ​

`orgRid` string
:   Required on create requests; immutable on updates.

`groupId` string
:   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

`displayName` string
:   ​

`description` string
:   ​

`userRids` array of string
:   The list of users in this group.

`createdAt` string (date-time)
:   ​

`updatedAt` string (date-time)
:   ​

`symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
:   Symbol to identify groups

    Fields of `Symbol`

    one of `icon`, `emoji`, `image`
    :   ​

        **icon**

        `icon` string
        :   Icon name (e.g. castle)

        **emoji**

        `emoji` string
        :   Emoji name (e.g. :castle:)

        **image**

        `image` string
        :   Image url (e.g. https://example.com/image.png)

`membershipManagedManually` boolean
:   Whether group membership is managed manually in Nominal. Defaults to false.

Request

**curl**

```shell
curl "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.get(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.get(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "rid": "<rid>",
  "orgRid": "<org rid>",
  "groupId": "<group id>",
  "displayName": "<display name>",
  "description": "<description>",
  "userRids": [
    "<user rids>"
  ],
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z",
  "symbol": {
    "icon": "<icon>"
  },
  "membershipManagedManually": true
}
```

### Update group metadata

PUT `/authentication/groups/v1/{groupRid}/metadata`

Updates the metadata of a group

Path parameters

`groupRid` string required
:   ​

Body

`displayName` string
:   ​

`description` string
:   ​

`symbol` [`UpdateGroupSymbolWrapper`](https://dev.nominal.io/api/rest/group-service.md#updategroupsymbolwrapper)
:   ​

    Fields of `UpdateGroupSymbolWrapper`

    `value` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
    :   ​

        Fields of `Symbol`

        one of `icon`, `emoji`, `image` required
        :   ​

            **icon**

            `icon` string
            :   Icon name (e.g. castle)

            **emoji**

            `emoji` string
            :   Emoji name (e.g. :castle:)

            **image**

            `image` string
            :   Image url (e.g. https://example.com/image.png)

Response

`rid` string
:   ​

`orgRid` string
:   Required on create requests; immutable on updates.

`groupId` string
:   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

`displayName` string
:   ​

`description` string
:   ​

`userRids` array of string
:   The list of users in this group.

`createdAt` string (date-time)
:   ​

`updatedAt` string (date-time)
:   ​

`symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
:   Symbol to identify groups

    Fields of `Symbol`

    one of `icon`, `emoji`, `image`
    :   ​

        **icon**

        `icon` string
        :   Icon name (e.g. castle)

        **emoji**

        `emoji` string
        :   Emoji name (e.g. :castle:)

        **image**

        `image` string
        :   Image url (e.g. https://example.com/image.png)

`membershipManagedManually` boolean
:   Whether group membership is managed manually in Nominal. Defaults to false.

Request

**curl**

```shell
curl -X PUT "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>/metadata" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "displayName": "<display name>",
  "description": "<description>",
  "symbol": {
    "value": {
      "icon": "<icon>"
    }
  }
}'
```

**requests**

```python
import requests

response = requests.put(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>/metadata",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "displayName": "<display name>",
        "description": "<description>",
        "symbol": {"value": {"icon": "<icon>"}},
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.put(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>/metadata",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "displayName": "<display name>",
        "description": "<description>",
        "symbol": {"value": {"icon": "<icon>"}},
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.put(
            "https://api.gov.nominal.io/api/authentication/groups/v1/<group rid>/metadata",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "displayName": "<display name>",
                "description": "<description>",
                "symbol": {"value": {"icon": "<icon>"}},
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "rid": "<rid>",
  "orgRid": "<org rid>",
  "groupId": "<group id>",
  "displayName": "<display name>",
  "description": "<description>",
  "userRids": [
    "<user rids>"
  ],
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z",
  "symbol": {
    "icon": "<icon>"
  },
  "membershipManagedManually": true
}
```

### Delete group membership

DELETE `/authentication/groups/v1/{key.groupRid}/memberships/{key.memberRid}`

Removes a member from a manually managed group. Removing a non-member is a no-op. Throws HTTP 400 / gRPC 3 if group_rid or member_rid is missing, or member_rid is not a supported RID type. Throws HTTP 403 / gRPC 7 if the caller is not authorized to update the group, including when the group does not exist. The permission check runs before the group lookup so unknown groups are not disclosed. Throws HTTP 400 / gRPC 3 if the group’s membership is not managed manually.

Path parameters

`key.groupRid` string required
:   At most 256 characters.

`key.memberRid` string required
:   The member of the group. Only user RIDs are accepted today. At most 256 characters.

Response

An empty JSON object, `{}`.

Request

**curl**

```shell
curl -X DELETE "https://api.gov.nominal.io/api/authentication/groups/v1/<key.group rid>/memberships/<key.member rid>" \
  -H "Authorization: Bearer <api key>"
```

**requests**

```python
import requests

response = requests.delete(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<key.group rid>/memberships/<key.member rid>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.delete(
    "https://api.gov.nominal.io/api/authentication/groups/v1/<key.group rid>/memberships/<key.member rid>",
    headers={"Authorization": "Bearer <api key>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.delete(
            "https://api.gov.nominal.io/api/authentication/groups/v1/<key.group rid>/memberships/<key.member rid>",
            headers={"Authorization": "Bearer <api key>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{}
```

## Errors

[Errors](https://dev.nominal.io/api.md#errors) shows how these errors are sent.

Each error’s `errorName` is `NominalAuthenticationGroupsV1:` followed by its name below.

| Status | Name | Notes |
| --- | --- | --- |
| 400 | `GroupErrorsIdentityMismatch` | Request identity field does not match the existing group |
| 400 | `GroupErrorsInvalidRid` | RID field is invalid |
| 400 | `GroupErrorsMembershipNotManagedManually` | Group membership is not managed manually |
| 400 | `GroupErrorsMissingRequiredField` | Required field missing on request |
| 400 | `GroupErrorsRequestedPageSizeTooLarge` | Requested page size is too large |
| 400 | `GroupErrorsUserNotInOrg` | User is not a member of the group organization |
| 403 | `GroupErrorsUnauthorized` | Not authorized for group |
| 404 | `GroupErrorsNotFound` | Group not found |
| 409 | `GroupErrorsIdConflict` | Group with given group_id already exists in organization |

## Types

### Group

A group represents a collection of users within an organization

`rid` string
:   ​

`orgRid` string
:   Required on create requests; immutable on updates.

`groupId` string
:   Group ID, unique per org. If sourced from the customer’s IdP, will match IdP group name. Required on create requests; immutable on updates.

`displayName` string
:   ​

`description` string
:   ​

`userRids` array of string output only
:   The list of users in this group.

`createdAt` string (date-time) output only
:   ​

`updatedAt` string (date-time) output only
:   ​

`symbol` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
:   Symbol to identify groups

`membershipManagedManually` boolean
:   Whether group membership is managed manually in Nominal. Defaults to false.

### GroupMembershipKey

Client-known identity of a group membership.

`groupRid` string required
:   At most 256 characters.

`memberRid` string required
:   The member of the group. Only user RIDs are accepted today. At most 256 characters.

### SearchGroupsQuery

Set at most one of the fields below.

one of `exactSubstringText`, `and`, `or`, `memberUsers`
:   ​

    **exactSubstringText**

    `exactSubstringText` string
    :   ​

    **and**

    `and` [`SearchQueryAnd`](https://dev.nominal.io/api/rest/group-service.md#searchqueryand)
    :   and is implemented to allow for list (use SearchQueryAnd([]))

    **or**

    `or` [`SearchQueryOr`](https://dev.nominal.io/api/rest/group-service.md#searchqueryor)
    :   ​

    **memberUsers**

    `memberUsers` [`SearchQueryMemberUsers`](https://dev.nominal.io/api/rest/group-service.md#searchquerymemberusers)
    :   ​

### SearchQueryAnd

`queries` array of [`SearchGroupsQuery`](https://dev.nominal.io/api/rest/group-service.md#searchgroupsquery)
:   ​

### SearchQueryMemberUsers

Matches the groups that any of the users is a direct member of, whether that membership is synced from the identity provider or managed manually.

`userRids` array of string
:   1 to 1,000 items. Each item: at most 256 characters.

### SearchQueryOr

`queries` array of [`SearchGroupsQuery`](https://dev.nominal.io/api/rest/group-service.md#searchgroupsquery)
:   ​

### Symbol

Set exactly one of the fields below.

one of `icon`, `emoji`, `image` required
:   ​

    **icon**

    `icon` string
    :   Icon name (e.g. castle)

    **emoji**

    `emoji` string
    :   Emoji name (e.g. :castle:)

    **image**

    `image` string
    :   Image url (e.g. https://example.com/image.png)

### UpdateGroupSymbolWrapper

`value` [`Symbol`](https://dev.nominal.io/api/rest/group-service.md#symbol)
:   ​

Page design based on [Scalar](https://scalar.com), MIT License.
