# Roles

## List

**get** `/zones/{zoneId}/groups/{groupId}/roles`

Returns the roles assigned to the group. Members inherit these roles. Returns the shared role-assignment shape with `principal_type` set to `group`. Use cursor pagination via `after`/`before`; pass `expand[]=total_count` to include the matching row count. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of role assignments, mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested assignment that exists on the group, in a single page. IDs not on the group are silently omitted.

### Path Parameters

- `zoneId: string`

- `groupId: string`

### Query Parameters

- `after: optional string`

  Cursor for forward pagination

- `before: optional string`

  Cursor for backward pagination

- `"expand[]": optional "total_count" or array of "total_count"`

  - `UnionMember0 = "total_count"`

    - `"total_count"`

  - `UnionMember1 = array of "total_count"`

    - `"total_count"`

- `"filter[id]": optional string or array of string`

  Restrict results to the role assignment with this ID. Repeatable, max 100. Mutually exclusive with after/before.

  - `UnionMember0 = string`

    Restrict results to the role assignment with this ID. Repeatable, max 100. Mutually exclusive with after/before.

  - `UnionMember1 = array of string`

- `limit: optional number`

  Maximum number of items to return

### Returns

- `items: array of RoleAssignment`

  - `id: string`

    Unique identifier of the role assignment

  - `created_at: string`

    Entity creation timestamp

  - `principal_id: string`

    ID of the principal the role is assigned to (a user, application, or group ID).

  - `principal_type: string`

    The kind of principal the role is assigned to: `user`, `application`, or `group`. A role assigned to a `group` is inherited by that group's members.

  - `role_id: string`

    ID of the assigned role

  - `role_identifier: string`

    Role identifier: a lowercase slug (letters and digits separated by single hyphens or underscores), unique per owner type within a zone. Role identifiers surface in policy evaluation, so the slug restriction keeps them unambiguous in policy text.

  - `role_owner_type: "platform" or "customer"`

    Owner type of the assigned role. Disambiguates roles that share an identifier across owner types.

    - `"platform"`

    - `"customer"`

  - `updated_at: string`

    Entity update timestamp

  - `zone_id: string`

    Zone this assignment belongs to

  - `scope_id: optional string`

    The ID of the scoped resource. Null when the assignment is unscoped.

  - `scope_type: optional string`

    The kind of resource this grant is scoped to (e.g. `zone`). Null when the assignment is unscoped (applies to the owning zone itself).

- `pagination: object { after_cursor, before_cursor, total_count }`

  Cursor-based pagination metadata

  - `after_cursor: string`

    An opaque cursor used for paginating through a list of results

  - `before_cursor: string`

    An opaque cursor used for paginating through a list of results

  - `total_count: optional number`

    Total number of items matching the query. Only included when expand[]=total_count is requested.

### Example

```http
curl https://api.keycard.ai/zones/$ZONE_ID/groups/$GROUP_ID/roles \
    -H "Authorization: Bearer $KEYCARD_API_API_KEY"
```

## Add

**post** `/zones/{zoneId}/groups/{groupId}/roles`

Assigns a role to the group; members inherit it. Provide role_id, or role_identifier with owner_type. Returns the shared role-assignment shape with `principal_type` set to `group`.

### Path Parameters

- `zoneId: string`

- `groupId: string`

### Body Parameters

- `owner_type: optional "platform" or "customer"`

  Owner type of the role to assign. Required with role_identifier (an identifier is unique only per owner type); must be omitted with role_id.

  - `"platform"`

  - `"customer"`

- `role_id: optional string`

  ID of the role to assign. Provide exactly one of role_id or role_identifier; owner_type must be omitted when role_id is used.

- `role_identifier: optional string`

  Role identifier: a lowercase slug (letters and digits separated by single hyphens or underscores), unique per owner type within a zone. Role identifiers surface in policy evaluation, so the slug restriction keeps them unambiguous in policy text.

- `scope_id: optional string`

  The ID of the resource to scope the grant to. Provide together with scope_type, or omit both for an unscoped assignment. When scope_type is `zone`, this must reference a different zone in the same organization.

- `scope_type: optional string`

  The kind of resource to scope the grant to (e.g. `zone`). Provide together with scope_id, or omit both for an unscoped assignment (applies to the owning zone itself). Only platform roles on the org zone may carry a scope.

### Returns

- `RoleAssignment = object { id, created_at, principal_id, 8 more }`

  Represents a role assigned to a principal within a zone

  - `id: string`

    Unique identifier of the role assignment

  - `created_at: string`

    Entity creation timestamp

  - `principal_id: string`

    ID of the principal the role is assigned to (a user, application, or group ID).

  - `principal_type: string`

    The kind of principal the role is assigned to: `user`, `application`, or `group`. A role assigned to a `group` is inherited by that group's members.

  - `role_id: string`

    ID of the assigned role

  - `role_identifier: string`

    Role identifier: a lowercase slug (letters and digits separated by single hyphens or underscores), unique per owner type within a zone. Role identifiers surface in policy evaluation, so the slug restriction keeps them unambiguous in policy text.

  - `role_owner_type: "platform" or "customer"`

    Owner type of the assigned role. Disambiguates roles that share an identifier across owner types.

    - `"platform"`

    - `"customer"`

  - `updated_at: string`

    Entity update timestamp

  - `zone_id: string`

    Zone this assignment belongs to

  - `scope_id: optional string`

    The ID of the scoped resource. Null when the assignment is unscoped.

  - `scope_type: optional string`

    The kind of resource this grant is scoped to (e.g. `zone`). Null when the assignment is unscoped (applies to the owning zone itself).

### Example

```http
curl https://api.keycard.ai/zones/$ZONE_ID/groups/$GROUP_ID/roles \
    -X POST \
    -H "Authorization: Bearer $KEYCARD_API_API_KEY"
```

## Remove

**delete** `/zones/{zoneId}/groups/{groupId}/roles/{roleId}`

Revokes a role from the group. Provide the same (scope_type, scope_id) pair the grant was created with, or omit both to revoke the unscoped grant.

### Path Parameters

- `zoneId: string`

- `groupId: string`

- `roleId: string`

### Query Parameters

- `scope_id: optional string`

  Scope target of the grant to revoke. Provide together with scope_type.

- `scope_type: optional string`

  Scope kind of the grant to revoke. Provide together with scope_id.

### Example

```http
curl https://api.keycard.ai/zones/$ZONE_ID/groups/$GROUP_ID/roles/$ROLE_ID \
    -X DELETE \
    -H "Authorization: Bearer $KEYCARD_API_API_KEY"
```
