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

> List the caller's direct-membership + owned workspaces

Returns a paginated list of workspaces scoped to the caller's **direct memberships + owned workspaces** (both index-backed, no ancestor climb).

<Note>
  This is deliberately **not** an "everything I can reach" tree listing — that per-row reach resolution is deferred. Use this for the common "my workspaces" UI call.
</Note>

## Query Parameters

<ParamField query="page" type="number">
  Page number for pagination.
</ParamField>

<ParamField query="limit" type="number">
  Page size.
</ParamField>

<ParamField query="include" type="string">
  Comma-separated include flags. `include=memberCount` adds a `memberCount` to **every row** — the workspace's **direct** member count, the same number [Fetch Workspace](/v8/api-reference/workspaces/fetch-workspace) returns for one workspace, counting neither descendants nor reach-holders.

  It is resolved with a single grouped query over the page that was returned, so a workspace switcher showing counts costs one request rather than one per row. Omit the flag and the field is **absent** from each row — not `null`, not `0`. An unrecognized flag value is ignored rather than rejected.
</ParamField>

<ParamField query="actingUserId" type="string" required>
  Service/master keys only — the user to act as, whose workspaces are listed. **Required for a key:** this route has no unbounded path — the list is defined as *somebody's* memberships — so a key that names nobody is refused with `400 workspace/missing-user-id`.

  A plain user token omits it — the actor is the token's own user. The field is **not** ignored for such a token: sending your *own* user id is a harmless no-op, but sending **anyone else's** is a `403 workspace/unauthorized`. See [Acting on behalf of a user](/v8/sdk/workspaces/overview#acting-on-behalf-of-a-user).
</ParamField>

## Response

Returns a paginated response of [Workspace](/v8/data-models/workspace) objects.

```
GET /v8/:projectId/workspaces?page=1&limit=10&include=memberCount
```

```json theme={null}
{
  "data": [
    {
      "id": "0f1c7a6e-9d4b-4f2a-8c31-5b6e2a7d1c04",
      "name": "Acme HQ",
      "metadata": {},
      "ownerId": "3a9e5c11-72d8-4a6b-9f10-8c2d4e7b5a33",
      "parentWorkspaceId": null,
      "depth": 0,
      "inheritsFromParent": false,
      "createdAt": "2026-01-14T09:12:44.001Z",
      "updatedAt": "2026-01-14T09:12:44.001Z",
      "memberCount": 12
    }
  ],
  "pagination": { "page": 1, "pageSize": 10, "totalPages": 1, "totalItems": 1, "hasMore": false }
}
```

`memberCount` appears only when `include=memberCount` was sent. `limit` defaults to `20` when omitted, and `page` to `1`.

## Error Responses

<AccordionGroup>
  <Accordion title="Missing Acting User — 400">
    ```json theme={null}
    { "error": "Missing user ID", "code": "workspace/missing-user-id" }
    ```

    A service/master key called this route without naming an `actingUserId`. The listing is scoped to a user's own memberships and owned workspaces, so there is nobody to scope it to.
  </Accordion>

  <Accordion title="Acted as Another User — 403">
    ```json theme={null}
    { "error": "Unauthorized", "code": "workspace/unauthorized" }
    ```

    A plain user token sent an `actingUserId` naming a **different** user. Only a service/master key may act as someone else.
  </Accordion>

  <Accordion title="Undeclared Query Parameter — 400">
    ```json theme={null}
    { "error": "Unrecognized key: \"sort\"", "code": "workspace/invalid-query" }
    ```

    This route declares `page`, `limit`, `include`, `actingUserId` and `projectId`, and refuses anything else rather than ignoring it. Two or more at once are named together: `Unrecognized keys: "sort", "order"`. The two exceptions across the bundle are the cache-busters `_` and `_t`, which are dropped before the request is read. See [Shapes the server rejects](/v8/sdk/workspaces/overview#shapes-the-server-rejects).
  </Accordion>
</AccordionGroup>

See also: [useFetchManyWorkspaces](/v8/hooks/workspaces/use-fetch-many-workspaces) · [useFetchManyWorkspacesWrapper](/v8/hooks/workspaces/use-fetch-many-workspaces-wrapper)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.