> ## 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.

# Fetch workspace members

> The unified roster read — one entry per distinct user

## Overview

`useFetchWorkspaceMembers` returns a callable for the [unified roster](/api-reference/workspaces/members/list-members): one entry per distinct user, each with a `reasons` array. Always returned in full (never paginated). With `countOnly`, the shape is `WorkspaceRosterCountsResponse` instead.

## Usage Example

```tsx theme={null}
import { useFetchWorkspaceMembers } from "@sublay/react-js";

function Roster({ workspaceId }: { workspaceId: string }) {
  const fetchWorkspaceMembers = useFetchWorkspaceMembers();

  const load = async () => {
    const roster = await fetchWorkspaceMembers({
      workspaceId,
      include: "ancestorOwners,descendants",
    });
    // roster.data: WorkspaceRosterEntry[]
  };
}
```

## Parameters

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

<ParamField path="include" type="string">
  Comma-separated add-on buckets: `ancestorOwners`, `reachHolders`, `descendants`.
</ParamField>

<ParamField path="countOnly" type="boolean">
  Return per-reason counts + a distinct-user total instead of the array.
</ParamField>

## Returns

`WorkspaceRosterResponse` (`{ data, total }`), or `WorkspaceRosterCountsResponse` (`{ counts, total, distinctUsers }`) when `countOnly` is set.

Each `WorkspaceRosterEntry` is `{ user, reasons }`, where a reason is `{ type, ...detail }` — `member` carries `rank` / `capabilities` / `permissions` / `title` / `metadata`, `ancestor-owner` and `reach-holder` carry `viaWorkspaceId` (reach-holder also `capabilities`), and `descendant-member` carries `workspaceId` / `rank` / `capabilities`.

<Warning>
  **`rank`, `capabilities` and `permissions` are fenced on other users' entries.** They are **omitted** (absent — not `null`) unless the signed-in user holds one of the four people-operating capabilities on this workspace (`invite`, `remove-member`, `edit-member-access`, `edit-member-profile`) or is the `owner` / an `ancestor-owner`. The caller's **own** entry always carries them, so anyone can discover their own access. Who is on the roster (`user`, reason `type`s, `title`, `metadata`, `viaWorkspaceId`) stays visible to any relation — read the three fenced fields defensively (`reason.capabilities ?? []`).
</Warning>

## Related

* [List Members API](/api-reference/workspaces/members/list-members)
