---
title: "Update user"
method: PATCH
path: "/zones/{zoneId}/users/{id}"
tags: ["Users"]
---

# Update user

`PATCH /zones/{zoneId}/users/{id}`

Update a user

## Path parameters

- `zoneId` string, required
- `id` string, required

## Request body

- IamUserUpdate — Schema for updating an existing user
  - `identifier` string, safe-text — Zone-scoped user identifier
  - `status` 'active' | 'disabled' — Status of the user. Set to `disabled` to prevent the user from authenticating and revoke their active sessions, or `active` to re-enable.

## Response `200`

An authenticated user entity

- IamUser — An authenticated user entity
  - `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
            - `oauth2` IamProviderOAuth2Protocol, nullable — OAuth 2.0 protocol configuration
              - …
            - `openid` IamProviderOpenIDProtocol, nullable — OpenID Connect protocol configuration
              - …
          - `metadata` object, nullable — Provider metadata
            - `icon_url` string, uri — Icon URL
          - `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

## Other responses

- `400` — Error response
- `404` — Error response
- `409` — Error response
- `default` — Error response

## Changes

- **2026-08-26** `d65d51379d93` — 7 info
  - added the non-success response with the status `400`
  - added the optional property `credentials` to the response with the `200` status
  - added the optional property `groups` to the response with the `200` status
  - added the optional property `role_assignments/items/group_id` to the response with the `200` status
  - …3 more
- **2026-07-01** `2f5033ed4491` — 1 breaking
  - the `identifier` request property type/format changed from `string`/`` to `string`/`safe-text`
- **2026-06-17** `1a0dd4d857ee` — 2 info
  - added the new optional request property `status`
  - added the required property `status` to the response with the `200` status
- **2026-06-09** `7e0e4fa2e16f` — 1 info
  - added the optional property `role_assignments` to the response with the `200` status
- **2026-05-22** `ffb6f697525f` — 2 info
  - added the optional property `grant_count` to the response with the `200` status
  - added the optional property `session_count` to the response with the `200` status

[Full history](https://skmtc.dev/keycardai/apis/untitled-api/changes/zones/:zoneId/users/:id/patch.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)
