---
title: "List"
method: GET
path: "/groups"
tags: ["groups"]
---

# List

`GET /groups`

## Request

- Base URL: `https://api.instruxi.dev/api/v1/enforcer`
- URL: `https://api.instruxi.dev/api/v1/enforcer/groups`
- Auth: one of:
  - API key in header `Authorization`
  - API key in header `X-API-Key`

Every group in the caller's tenant (the policy's baseline group-read rule — any authenticated member of a tenant may list its groups). q searches name/description, type_id filters to one group_type, sort is name (A-Z, default) | name_desc | recent | oldest. Groups of a RESERVED type (a service's, e.g. enforcer-graph's per-DAG sharing groups) are omitted unless include_reserved=true or type_id names that type. Archived groups are omitted unless archived=true|all.

## Query parameters

- `q` string
- `sort` 'name' | 'name_desc' | 'recent' | 'oldest'
- `type_id` string
- `include_reserved` boolean
- `archived` 'false' | 'true' | 'all'
- `limit` integer
- `offset` integer
- `tenant_id` string, uuid
- `all_tenants` boolean

## Response `200`

OK

- InternalDeliveryHttpHandlerGroupPageResponse
  - `data` EnforcerV3InternalDomainGroupGroup[]
    - `agent_count` integer: AgentCount is the number of service-account members, computed on load.
    - `archived_at` string: ArchivedAt is set while the group is archived (#305, 000123): kept with its members, hidden from GET /groups by default, read-only, and not granting. nil = live. READ-ONLY on the model ("->") for the same reason as Metadata: Update is a full Save, and a PATCH that loaded the group just before someone archived it would otherwise write archived_at back to NULL. Written only by Repository.SetArchived.
    - `archived_by` string
    - `created_at` string
    - `created_by` string
    - `description` string
    - `group_type_id` string: GroupTypeID classifies the group; nil = untyped. Must reference a GLOBAL type or one from the group's own tenant (enforced by the usecase).
    - `id` string
    - `is_public` boolean
    - `member_count` integer: MemberCount is computed on load, not stored. It counts HUMAN members only; service accounts (agents) are counted in AgentCount (AGENTS_CONTRACT §8: member counts are split).
    - `name` string
    - `slug` string
    - `tenant_id` string
    - `updated_at` string
  - `limit` integer
  - `offset` integer
  - `success` boolean
  - `total` integer

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: forbidden: tenant_id/all_tenants beyond your own tenant without the cross_tenant grant

---

[API](https://skmtc.dev/instruxi/apis/enforcer-api.md) · [All operations](https://skmtc.dev/instruxi/apis/enforcer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/instruxi/apis/enforcer-api/revisions/fa82bc1becc0?raw)
