## List

`client.Zones.Groups.List(ctx, zoneID, query) (*ZoneGroupListResponse, error)`

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

Returns a paginated list of the groups in the specified zone. Use cursor pagination via `after`/`before`. Sort: comma-separated field list; prefix with `-` for descending (allowed: created_at, name, identifier). Pass `expand[]=member_count` to include each group's member count, `expand[]=roles` to include the identifiers of the roles assigned to each group, and `expand[]=total_count` to include the matching row count. Filter by exact identifier via `filter[identifier]` (repeatable, OR'd across values). Search via `query[]` (case-insensitive substring match, OR'd across repeated values); it matches the group's name and identifier. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of groups — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested group that exists in the zone, in a single page. IDs not in the zone are silently omitted.

### Parameters

- `zoneID string`

- `query ZoneGroupListParams`

  - `After param.Field[string]`

    Cursor for forward pagination

  - `Before param.Field[string]`

    Cursor for backward pagination

  - `Expand param.Field[ZoneGroupListParamsExpandUnion]`

    - `type ZoneGroupListParamsExpandString string`

      - `const ZoneGroupListParamsExpandStringTotalCount ZoneGroupListParamsExpandString = "total_count"`

      - `const ZoneGroupListParamsExpandStringMemberCount ZoneGroupListParamsExpandString = "member_count"`

      - `const ZoneGroupListParamsExpandStringRoles ZoneGroupListParamsExpandString = "roles"`

    - `type ZoneGroupListParamsExpandArray []string`

      - `const ZoneGroupListParamsExpandArrayItemTotalCount ZoneGroupListParamsExpandArrayItem = "total_count"`

      - `const ZoneGroupListParamsExpandArrayItemMemberCount ZoneGroupListParamsExpandArrayItem = "member_count"`

      - `const ZoneGroupListParamsExpandArrayItemRoles ZoneGroupListParamsExpandArrayItem = "roles"`

  - `FilterID param.Field[ZoneGroupListParamsFilterIDUnion]`

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

    - `string`

    - `type ZoneGroupListParamsFilterIDArray []string`

  - `FilterIdentifier param.Field[ZoneGroupListParamsFilterIdentifierUnion]`

    Filter by exact group identifier

    - `string`

    - `type ZoneGroupListParamsFilterIdentifierArray []string`

  - `Limit param.Field[int64]`

    Maximum number of items to return

  - `Query param.Field[ZoneGroupListParamsQueryUnion]`

    Search across name and identifier (substring match)

    - `string`

    - `type ZoneGroupListParamsQueryArray []string`

  - `Sort param.Field[string]`

    Comma-separated sort fields. Prefix with - for descending. Allowed: created_at, name, identifier

### Returns

- `type ZoneGroupListResponse struct{…}`

  - `Items []Group`

    - `ID string`

      Unique identifier of the group

    - `CreatedAt Time`

      Entity creation timestamp

    - `External bool`

      Whether the group is synced from an external directory. When true the group is directory-owned and its membership is read-only; when false it is managed in Keycard. Read-only: set by external sync, never by the caller.

    - `Identifier string`

      User-specified identifier, unique within the zone. Automatically assigned for groups from an external directory.

    - `Name string`

      Human-readable group name

    - `OrganizationID string`

      Organization this group belongs to

    - `UpdatedAt Time`

      Entity update timestamp

    - `ZoneID string`

      Zone this group belongs to

    - `MemberCount int64`

      Number of users in the group. Included only when requested via `expand[]=member_count` (group get or list).

    - `Roles []string`

      Identifiers of the roles assigned to the group; members inherit them. Deduped across scopes. Included only when requested via `expand[]=roles` (group get or list).

  - `Pagination ZoneGroupListResponsePagination`

    Cursor-based pagination metadata

    - `AfterCursor string`

      An opaque cursor used for paginating through a list of results

    - `BeforeCursor string`

      An opaque cursor used for paginating through a list of results

    - `TotalCount int64`

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

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/keycardai/keycard-go"
  "github.com/keycardai/keycard-go/option"
)

func main() {
  client := keycard.NewClient(
    option.WithAPIKey("My API Key"),
  )
  groups, err := client.Zones.Groups.List(
    context.TODO(),
    "zoneId",
    keycard.ZoneGroupListParams{

    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", groups.Items)
}
```
