Identity & Access Management

Preview — pending review

This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.

Edit an IAM user's profile

PATCH
/scopes/{scopeId}/iam/users/{userId}

Applies a partial update to the editable profile fields of the selected user (the detail header's "Edit" action / profile editor): display name, job title, department, manager and phone. Lifecycle status, role assignments, group membership, credentials and tags are managed through their dedicated endpoints and are NOT writable here. The updated record is returned and becomes immediately visible to subsequent reads. Validation: userId must exist and be visible in scopeId (404 via ErrNotFound); only the whitelisted profile fields are accepted — unknown or read-only fields (email, status, roles) are rejected with 422 VALIDATION_FAILED; name, when present, must be at least 2 characters; manager may be set to null to clear it; updates to a user whose current state forbids edits (e.g. deletion in progress) return 409 CONFLICT. Async & state: Synchronous — returns 200 with the updated IamUser. A resource.updated SSE frame (kind iam.user, patch containing the changed profile fields) is emitted so other open consoles refresh. Errors: 401 unauthenticated; 403 when the caller lacks owner|admin on the scope; 404 when scopeId/userId is unknown; 409 when the user's current state blocks the edit; 412 when the If-Match revision is stale; 422 on field validation failure; 500 on write failure. Idempotency/Concurrency: Idempotency-Key recommended — replaying the same key returns the first outcome without reapplying. If-Match with the ETag from the detail read is honoured; a mismatch returns 412 PRECONDITION_FAILED so concurrent edits are never silently overwritten.

Authorization

bearerToken
headerAuthorizationBearer <token>

An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.

Path Parameters

scopeId*string

Opaque ownership+authorization scope resolving to tenant + subscription + project.

userId*string

Identifier of the IAM user.

Header Parameters

Idempotency-Key?string

Optional; recommended for safe retries. When sent, the same key+body within 24h replays the original result and the same key with a different body is 409 CONFLICT; keys are unique per tenant. When an API token or service-account (bearer) caller omits it, the request is applied once with no replay protection (a retry may apply it again). A console session gets one from the edge.

Formatuuid
If-Match?string

ETag for optimistic concurrency on mutations/deletes; mismatch results in 412.

Request Body

application/json
  1. body

Partial profile update (detail header "Edit"). Only editable profile fields; lifecycle, roles, groups, credentials and tags have dedicated endpoints.

name?string

New display name.

Match^[^\p{C}\p{Z}\x{10000}-\x{10FFFF}](?:[^\p{C}\p{Zl}\p{Zp}\x{10000}-\x{10FFFF}]*[^\p{C}\p{Z}\x{10000}-\x{10FFFF}])?$
Length2 <= length <= 255
title?string

New job title.

department?string

New department.

manager?|

New manager display name; null clears the manager.

phone?string

New contact phone number.

Response Body

The updated IAM user.

application/json
  1. response

IAM user record (member, guest, or service account) as consumed by the Users page and the user detail page.

id*string

User identifier.

name*string

Full display name.

email*string

Canonical email address (masked at the presentation layer, not by the API). The stored value as is — addresses are validated when written, never re-validated on read.

title*string

Job title.

avatarColor*string

Deterministic avatar color token used by the console.

status*string

The MEMBERSHIP in this tenant. INACTIVE = a tenant admin suspended it: this tenant's scopes stop resolving for the person, while their memberships in other tenants keep working. Independent of operatorLocked.

Value in"ACTIVE""INACTIVE""INVITED"
operatorLocked*boolean

Whether a platform operator has locked the person's sign-in globally. While true the user cannot sign in to any tenant whatever status says, and a tenant admin cannot lift it -- enabling the membership answers 409; only the platform operator unlocks. Independent of status.

type*string

Account type.

Value in"MEMBER""GUEST""SERVICE_ACCOUNT"
mfaEnabled*boolean

Whether the user has at least one enrolled MFA device.

lastLogin*|

Last successful sign-in (ISO); null when the user has never signed in.

Formatdate-time
invitedAt*|

When the invitation was sent; null for users not created via invite.

Formatdate-time
createdAt*string

Creation timestamp (ISO).

Formatdate-time
lastPasswordChange*|

Last successful password change (ISO); null for SSO-only users or never set.

Formatdate-time
department*string

Organizational department.

manager*|

Manager display name; null when unset.

phone*string

Contact phone number.

employeeId*string

HR employee identifier.

groups*array<string>

Ids of the groups the user belongs to.

mfaDevices*array<>

Enrolled MFA devices.

apiKeys*array<>

Personal API keys (prefix and status only; secrets are never present here).

roles*array<>

Direct role assignments.

activity*array<>

Recent activity rows for the Activity tab.

tags*array<>

Custom governance key/value tags applied to the user via the Tags tab ("Add tag" -> iam.user.tag.create). Distinct from derived tags; drives access-review and cost-attribution dimensions.

accessSummary?

What the member can reach in the tenant; present on list and invite answers.

curl -X PATCH "https://example.com/scopes/string/iam/users/string" \  -H "Content-Type: application/json" \  -d '{}'
{  "id": "string",  "name": "string",  "email": "string",  "title": "string",  "avatarColor": "string",  "status": "ACTIVE",  "operatorLocked": true,  "type": "MEMBER",  "mfaEnabled": true,  "lastLogin": "2019-08-24T14:15:22Z",  "invitedAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "lastPasswordChange": "2019-08-24T14:15:22Z",  "department": "string",  "manager": "string",  "phone": "string",  "employeeId": "string",  "groups": [    "string"  ],  "mfaDevices": [    {      "id": "string",      "kind": "TOTP",      "name": "string",      "addedAt": "2019-08-24T14:15:22Z",      "lastUsedAt": "2019-08-24T14:15:22Z",      "primary": true    }  ],  "apiKeys": [    {      "id": "string",      "name": "string",      "prefix": "string",      "createdAt": "2019-08-24T14:15:22Z",      "lastUsedAt": "2019-08-24T14:15:22Z",      "status": "ACTIVE"    }  ],  "roles": [    {      "role": "owner",      "roleId": "string",      "roleName": "string",      "scopeKind": "tenant",      "scopeLabel": "string",      "assignedAt": "2019-08-24T14:15:22Z"    }  ],  "activity": [    {      "id": "string",      "at": "2019-08-24T14:15:22Z",      "action": "string",      "resource": "string",      "status": "SUCCESS"    }  ],  "tags": [    {      "key": "string",      "value": "string"    }  ],  "accessSummary": {    "kind": "tenant",    "subscriptions": 0,    "projects": 0  }}