> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Group Management

> Create and manage groups, membership, model availability, and group ACU caps via the service-key API.

<Info>
  This documentation is for the federal deployments of Devin. [Back to Devin Docs](/get-started/devin-intro)
</Info>

Manage [groups](/federal/groups) programmatically: create, read, update, and delete groups, manage their membership, and configure their [model availability](/federal/model-provisioning) and [ACU caps](/federal/acu-limits). These endpoints are available only on multi-tenant federal deployments.

All endpoints are JSON `POST` requests. Every request body includes `service_key`; see the [API overview](/federal/api/overview) for authentication, scoping, pagination, and errors. Read endpoints require **Teams Read-Only**; write endpoints require **Teams Update**. These handlers have the self-hosted, multi-tenant deployment gate but do not apply the separate analytics-access tier check used by `/Analytics`.

The group object returned by read and write endpoints:

| Field                        | Description                                                                                               |
| ---------------------------- | --------------------------------------------------------------------------------------------------------- |
| `group_id`                   | The group's ID.                                                                                           |
| `name`                       | The group name.                                                                                           |
| `member_count`               | Number of current members.                                                                                |
| `cascade_model_uids`         | Model UIDs allowed for Cascade. An empty list means the group imposes no Cascade restriction.             |
| `command_model_uids`         | Model UIDs allowed for Command. An empty list means the group imposes no Command restriction.             |
| `configured_cycle_acu_limit` | The group's configured per-member ACU cap. Omitted when none is configured. Always positive when present. |
| `effective_cycle_acu_limit`  | The cap actually enforced for the group after combining with team limits. Omitted when no limit applies.  |

***

## List groups

```
POST /api/v1/ListGroups
```

Lists groups visible to the service key. Team-scoped keys list all groups in the team; group-scoped keys list only their assigned group. Requires **Teams Read-Only**. Supports `page_size` / `page_token`.

```bash theme={null}
curl -X POST https://<your-server>/api/v1/ListGroups \
  -H "Content-Type: application/json" \
  -d '{"service_key": "your_service_key"}'
```

```json theme={null}
{
  "groups": [
    {"groupId": "group_a", "name": "Engineering", "memberCount": 24},
    {"groupId": "group_b", "name": "Data Science", "memberCount": 9}
  ],
  "nextPageToken": ""
}
```

## Get group

```
POST /api/v1/GetGroup
```

Reads one group, including its model allowlists and configured and effective ACU cap. Requires **Teams Read-Only**. Missing, cross-team, and out-of-scope groups return `not_found`.

```bash theme={null}
curl -X POST https://<your-server>/api/v1/GetGroup \
  -H "Content-Type: application/json" \
  -d '{"service_key": "your_service_key", "group_id": "group_a"}'
```

```json theme={null}
{
  "group": {
    "groupId": "group_a",
    "name": "Engineering",
    "memberCount": 24,
    "cascadeModelUids": ["model-uid-1", "model-uid-2"],
    "commandModelUids": [],
    "configuredCycleAcuLimit": 50,
    "effectiveCycleAcuLimit": 50
  }
}
```

## Create group

```
POST /api/v1/CreateGroup
```

Creates a group with the given `name` in the effective team. Requires **Teams Update**. Group-scoped keys cannot create groups.

```bash theme={null}
curl -X POST https://<your-server>/api/v1/CreateGroup \
  -H "Content-Type: application/json" \
  -d '{"service_key": "your_service_key", "name": "Engineering"}'
```

The response contains the created `group` object.

## Update group

```
POST /api/v1/UpdateGroup
```

Atomically patches a group. Only fields present in the request are changed; omitted fields are untouched. A request with no patch fields returns `invalid_argument`. Requires **Teams Update**.

<ParamField body="group_id" type="string" required>
  The group to update.
</ParamField>

<ParamField body="name" type="string">
  New group name.
</ParamField>

<ParamField body="cascade_models" type="object">
  `{"model_uids": [...]}` — replaces the group's Cascade model allowlist. Passing an empty list clears the group's Cascade restriction. See [Model Provisioning](/federal/model-provisioning) for how group allowlists combine.
</ParamField>

<ParamField body="command_models" type="object">
  `{"model_uids": [...]}` — replaces the group's Command model allowlist. Passing an empty list clears the group's Command restriction.
</ParamField>

<ParamField body="set_cycle_acu_limit" type="number">
  Sets the group's per-member ACU cap per billing cycle. Must be positive. Mutually exclusive with `clear_cycle_acu_limit`.
</ParamField>

<ParamField body="clear_cycle_acu_limit" type="boolean">
  Clears the group's ACU cap, restoring team or default behavior. In this service-key API, `set_cycle_acu_limit` must be finite and positive; use this explicit clear operation to remove the group override. The portal's group ACU limit control accepts `cycle_acu_limit: 0` as a clear request.
</ParamField>

```bash theme={null}
curl -X POST https://<your-server>/api/v1/UpdateGroup \
  -H "Content-Type: application/json" \
  -d '{
    "service_key": "your_service_key",
    "group_id": "group_a",
    "cascade_models": {"model_uids": ["model-uid-1", "model-uid-2"]},
    "set_cycle_acu_limit": 50
  }'
```

The response contains the updated `group` object.

## Delete group

```
POST /api/v1/DeleteGroup
```

Deletes a group by `group_id`. Deleting a group that is already missing from the key's possible scope is a successful no-op. Requires **Teams Update**.

```bash theme={null}
curl -X POST https://<your-server>/api/v1/DeleteGroup \
  -H "Content-Type: application/json" \
  -d '{"service_key": "your_service_key", "group_id": "group_a"}'
```

## List group members

```
POST /api/v1/ListGroupMembers
```

Lists the current members of one group. Requires **Teams Read-Only**. Supports `page_size` / `page_token`.

```bash theme={null}
curl -X POST https://<your-server>/api/v1/ListGroupMembers \
  -H "Content-Type: application/json" \
  -d '{"service_key": "your_service_key", "group_id": "group_a"}'
```

```json theme={null}
{
  "members": [
    {"userId": "user_abc", "email": "dev@agency.gov"}
  ],
  "nextPageToken": ""
}
```

## Add group members

```
POST /api/v1/AddGroupMembers
```

Adds current team users to a group by email (`user_emails`, 1–1,000 entries). Requires **Teams Update**.

* Idempotent: adding an existing member is a successful no-op.
* Emails are trimmed and deduplicated case-insensitively.
* All-or-nothing: if any email is unknown or belongs to another team, the whole request is rejected and nothing is written.

```bash theme={null}
curl -X POST https://<your-server>/api/v1/AddGroupMembers \
  -H "Content-Type: application/json" \
  -d '{
    "service_key": "your_service_key",
    "group_id": "group_a",
    "user_emails": ["dev@agency.gov", "lead@agency.gov"]
  }'
```

## Remove group members

```
POST /api/v1/RemoveGroupMembers
```

Removes users from a group by email (`user_emails`, 1–1,000 entries). Requires **Teams Update**. Validation is all-or-nothing like Add group members; removing a valid user who is not a member is a successful no-op.

```bash theme={null}
curl -X POST https://<your-server>/api/v1/RemoveGroupMembers \
  -H "Content-Type: application/json" \
  -d '{
    "service_key": "your_service_key",
    "group_id": "group_a",
    "user_emails": ["dev@agency.gov"]
  }'
```
