---
title: "List users"
method: GET
path: "/zones/{zoneId}/users"
tags: ["Users"]
---

# List users

`GET /zones/{zoneId}/users`

Returns a list of users in the specified zone.

Note: cursor pagination, search, and sort are not yet enabled for all zones. Where they are not enabled, the response returns all users in the zone (capped at 100) in `items`, with `after_cursor` and `before_cursor` set to `null` and `total_count` of `0`; `filter[email]` and `filter[identifier]` are still applied, while the pagination, search, and sort parameters below are accepted but ignored.

Use cursor pagination via `after`/`before`. Sort: comma-separated field list; prefix with `-` for descending. Use `expand[]=total_count` to include the matching row count, `expand[]=session_count` to include per-user session counts, `expand[]=grant_count` to include per-user delegated-grant counts, `expand[]=role-assignments` to include each user's structured role grants (direct grants only by default, each tagged with `source`; use `role_source=all` to also include group-inherited), `expand[]=groups` to include each user's group memberships, `expand[]=credentials` to include each user's authentication credentials (each with its `provider_id`), and `expand[]=credentials.provider` to additionally inline the full identity provider on each federation credential. Filter by exact email via `filter[email]` and by exact identifier via `filter[identifier]`; restrict to members of a group via `filter[groups]` (repeatable, OR'd across values); search via `query[email]` / `query[subject]` / `query[]` (substring match, OR'd across repeated values). `query[]` matches against email and federation credential subject. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of users — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested user that exists in the zone, in a single page. IDs not in the zone are silently omitted.

## Path parameters

- `zoneId` string, required

## Query parameters

- `after` string
- `before` string
- `limit` integer
- `expand[]` union
  - 'total_count' | 'session_count' | 'grant_count' | 'role-assignments' | 'groups' | 'credentials' | 'credentials.provider'
  - string[]
- `role_source` 'user' | 'group' | 'all'
- `filter[email]` union
  - string, email — Filter by exact email address
  - string[]
- `filter[id]` union
  - string — Restrict results to users with this publicId. Repeatable, max 100. Mutually exclusive with after/before.
  - string[]
- `filter[identifier]` union
  - string — Filter by exact user identifier
  - string[]
- `filter[groups]` union
  - string — Restrict to members of this group (by group ID). Repeatable; OR'd across values.
  - string[]
- `query[email]` union
  - string — Search by email (substring match)
  - string[]
- `query[subject]` union
  - string — Search by federated credential subject (substring match)
  - string[]
- `query[]` union
  - string — Search across email and credential subject (substring match)
  - string[]
- `sort` string

## Response `200`

Default Response

- object
  - `items` IamUser[], required
    - `id` string, required — Unique identifier of the user
    - `organization_id` string, required — Organization that owns this user
    - `zone_id` string, required — Zone this user belongs to
    - `identifier` string, required — Zone-scoped user identifier. Defaults to the user's Keycard ID. When the provider has user_identifier_claim configured, the value is set from that claim at user creation time.
    - `subject` string — Subject identifier from the identity provider
    - `issuer` string — Issuer identifier of the identity provider
    - `email` string, email, required — Email address of the user
    - `email_verified` boolean, required — Whether the email address has been verified
    - `status` 'active' | 'disabled', required — Status of the user. Disabled users cannot authenticate.
    - `provider_id` string — Reference to the identity provider. This field is undefined when the source identity provider is deleted but the user is not deleted.
    - `created_at` string, date-time, required — Entity creation timestamp
    - `updated_at` string, date-time, required — Entity update timestamp
    - `authenticated_at` string — Date when the user was last authenticated
    - `session_count` integer — Session count for this user. Populated only when `expand[]=session_count` is set on the listing endpoint.
    - `grant_count` integer — Delegated-grant count for this user. Populated only when `expand[]=grant_count` is set on the listing endpoint.
    - `role_assignments` IamUserRoleAssignment[] — Role grants for this user within the zone. Populated only when `expand[]=role-assignments` is set on the listing endpoint.
      - `role_id` string, required — ID of the assigned role
      - `role_identifier` string, required — Role identifier: a lowercase slug (letters and digits separated by single hyphens or underscores), unique per owner type within a zone. Role identifiers surface in policy evaluation, so the slug restriction keeps them unambiguous in policy text.
      - `role_owner_type` 'platform' | 'customer', required — Owner type of the granted role. Disambiguates roles that share an identifier across owner types.
      - `scope` object, nullable, required — The resource this grant is scoped to, or null when the grant is unscoped (applies to the owning zone itself).
        - `type` string, required — The kind of resource this grant is scoped to (e.g. `zone`).
        - `id` string, required — The ID of the scoped resource.
      - `source` 'user' | 'group', required — The principal that holds this grant: `user` when assigned directly to the user, or `group` when inherited through group membership.
      - `group_id` string — ID of the group this grant is inherited from. Present only when `source` is `group`.
    - `groups` IamUserGroup[] — Groups this user belongs to within the zone. Populated only when `expand[]=groups` is set on the listing endpoint.
      - `id` string, required — Unique identifier of the group
      - `identifier` string, required — Zone-unique slug that policy rules match on.
      - `name` string, required — Human-readable group name
    - `credentials` IamUserCredential[] — Authentication credentials for this user, each carrying its identity provider for federation credentials. Populated only when `expand[]=credentials` is set on the listing endpoint.
      - union — An authentication credential belonging to a user.
        - IamUserCredentialFederation — Common fields shared by all user credential types
          - `created_at` string, date-time, required — Entity creation timestamp
          - `updated_at` string, date-time, required — Entity update timestamp
          - `type` 'federation', required
          - `subject` string — Subject identifier from the identity provider.
          - `issuer` string — Issuer identifier of the identity provider.
          - `provider_id` string, nullable, required — ID of the identity provider backing this credential. `null` when the source provider has been deleted.
          - `provider` IamProvider — A Provider is a system that supplies access to Resources and allows actors (Users or Applications) to authenticate.
            - `id` string, required — Unique identifier of the provider
            - `organization_id` string, required — Organization that owns this provider
            - `zone_id` string, required — Zone this provider belongs to
            - `slug` string, required — URL-safe identifier, unique within the zone
            - `name` string, required — Human-readable name
            - `description` string, nullable — Human-readable description
            - `identifier` string, required — User specified identifier, unique within the zone
            - `type` 'external' | 'keycard-vault' | 'keycard-sts'
            - `client_id` string, nullable — OAuth 2.0 client identifier
            - `client_secret_set` boolean — Indicates whether a client secret is configured
            - `protocols` object, nullable — Protocol-specific configuration
              - …
            - `metadata` object, nullable — Provider metadata
              - …
            - `owner_type` 'platform' | 'customer', required — Who owns this provider. Platform-owned providers cannot be modified via API.
            - `created_at` string, date-time, required — Entity creation timestamp
            - `updated_at` string, date-time, required — Entity update timestamp
        - IamUserCredentialPassword — Common fields shared by all user credential types
          - `created_at` string, date-time, required — Entity creation timestamp
          - `updated_at` string, date-time, required — Entity update timestamp
          - `type` 'password', required
  - `pagination` IamPagination, required — Cursor-based pagination metadata
    - `after_cursor` string, required — An opaque cursor used for paginating through a list of results
    - `before_cursor` string, required — An opaque cursor used for paginating through a list of results
    - `total_count` integer — Total number of items matching the query. Only included when expand[]=total_count is requested.

## Other responses

- `400` — Error response
- `default` — Error response

## Changes

- **2026-08-26** `d65d51379d93` — 10 info
  - added the new optional `query` request parameter `filter[groups]`
  - added the new optional `query` request parameter `filter[identifier]`
  - added the new optional `query` request parameter `role_source`
  - added the non-success response with the status `400`
  - …6 more
- **2026-06-17** `1a0dd4d857ee` — 1 info
  - added the required property `items/items/status` to the response with the `200` status
- **2026-06-09** `7e0e4fa2e16f` — 1 info
  - added the optional property `items/items/role_assignments` to the response with the `200` status
- **2026-05-22** `ffb6f697525f` — 2 info
  - added the optional property `items/items/grant_count` to the response with the `200` status
  - added the optional property `items/items/session_count` to the response with the `200` status
- **2026-05-18** `2861899ae69e` — 6 info
  - added the new optional `query` request parameter `filter[email]`
  - added the new optional `query` request parameter `filter[id]`
  - added the new optional `query` request parameter `query[]`
  - added the new optional `query` request parameter `query[email]`
  - …2 more

[Full history](https://skmtc.dev/keycardai/apis/untitled-api/changes/zones/:zoneId/users/get.md)

---

[API](https://skmtc.dev/keycardai/apis/untitled-api.md) · [All operations](https://skmtc.dev/keycardai/apis/untitled-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/keycardai/untitled-api/revisions/d65d51379d93/schema)
