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

# List Members

> The unified roster — one entry per distinct user, each with a reasons array

Returns the roster as a **single unified array, one entry per distinct user**, each carrying a `reasons` array explaining *why* the user appears. Requires **roster visibility** — **any relation** to the workspace (owner, ancestor-owner, member, or reach-holder). A caller with no relation gets a `404`.

**Always returned in full — never paginated.** `include` flags only *add* entries; they never change the shape. `countOnly` is the numbers-only escape hatch.

## Path Parameters

<ParamField path="id" type="string" required>
  The workspace UUID.
</ParamField>

## Query Parameters

<ParamField query="include" type="string">
  Comma-separated add-on buckets. Default returns `owner` + direct `member`s. Options: `ancestorOwners`, `reachHolders`, `descendants`.
</ParamField>

<ParamField query="countOnly" type="boolean">
  When `true`, returns per-reason counts + a distinct-user total instead of the array (never materializes the roster). Honors the same includes.
</ParamField>

## Reasons

Each entry's `reasons[]` contains `{ type, ...detail }` objects. A user present for several reasons is **one** entry carrying multiple reasons.

| `type`              | Detail                                                     | Counted as a seat?                      |
| ------------------- | ---------------------------------------------------------- | --------------------------------------- |
| `owner`             | —                                                          | **Yes**                                 |
| `member`            | `rank`, `capabilities`, `permissions`, `title`, `metadata` | **Yes**                                 |
| `ancestor-owner`    | `viaWorkspaceId`                                           | No (informational)                      |
| `reach-holder`      | `viaWorkspaceId`, `capabilities`                           | No (informational)                      |
| `descendant-member` | `workspaceId`, `rank`, `capabilities`                      | Counted under the `descendants` include |

<Warning>
  **The authority-bearing detail fields are fenced.** `capabilities`, `permissions` and `rank` are **omitted from a reason** (absent — not `null`) on **other users'** entries unless the caller:

  * holds one of the four people-operating capabilities on this workspace — `invite`, `remove-member`, `edit-member-access`, `edit-member-profile`; **or**
  * is the workspace's `owner` or an `ancestor-owner`; **or**
  * is a service/master key.

  The caller's **own** entry always carries them in full, so anyone can discover their own access. Who is on the roster — `user`, the reason `type`s, `title`, `metadata`, `viaWorkspaceId`, `workspaceId` — stays visible to any relation. Treat the three fields as optional in your types.
</Warning>

## Response (array mode)

```json theme={null}
{
  "data": [
    {
      "user": { "id": "u_pat" },
      "reasons": [
        { "type": "member", "rank": 5, "capabilities": ["view", "invite"], "permissions": [], "title": "Frontend Lead", "metadata": {} },
        { "type": "ancestor-owner", "viaWorkspaceId": "ws_root" }
      ]
    }
  ],
  "total": 1
}
```

The same roster read by a caller who cannot manage people here — the `member` reason keeps its identity fields but drops the authority-bearing ones:

```json theme={null}
{
  "data": [
    {
      "user": { "id": "u_pat" },
      "reasons": [
        { "type": "member", "title": "Frontend Lead", "metadata": {} },
        { "type": "ancestor-owner", "viaWorkspaceId": "ws_root" }
      ]
    }
  ],
  "total": 1
}
```

## Response (`countOnly=true`)

```json theme={null}
{
  "counts": { "owner": 1, "member": 12, "ancestorOwner": 2, "reachHolder": 3, "descendantMember": 40 },
  "total": 13,
  "distinctUsers": 52
}
```

`total` is the **distinct-user seat number** (owner + direct members), **not** the sum of buckets (buckets overlap). Ancestor-owners and reach-holders are never counted as seats.

See also: [useFetchWorkspaceMembers](/hooks/workspaces/use-fetch-workspace-members) · [Fetch Member Standing](/api-reference/workspaces/members/fetch-member-standing)
