Docs

Update my user information

PATCH
/users/me

Partially updates the caller's own schema-defined attributes. The merged result is validated against the user's schema before commit. Concurrent writes are last-write-wins.

With project_id, the user is updated only when the session belongs to that project.

Authorization

sessionCookie
cookie__Host-zitadel_session<token>

The session cookie issued at session creation or superseding handoff exchange.

A browser holds it as __Host-zitadel_session, with Secure. Over plain http to a loopback host (localhost, 127.0.0.1, ::1) the server sets it as zitadel_session instead, without Secure or the prefix, so that Safari keeps it, and accepts that name there too; __Host-zitadel_session takes precedence. A program sends __Host-zitadel_session over any transport.

A missing or invalid cookie yields 401 with code auth.unauthorized and the message Missing or invalid session token.

Cross-site request forgery (ADR 053 §5): a state-changing request that this cookie authenticates must come from the same origin — a cross-site browser request is refused with 403 and code auth.csrf_invalid. Every such request must also send the session's token from GET /sessions/me/csrf in the X-Zitadel-CSRF header, or it answers the same 403. The only exceptions are the POST …/query reads, which need no token. Safe methods (GET) are not checked. A request a project secret authenticates is not affected.

Query Parameters

project_id?string

The project the caller signs its users in to. The cookie's session is used only when it belongs to this project; a session of any other project answers 403 with sess.project_mismatch.

A session belongs to one project, while a browser sends its cookie to every app on the same host. An app passes its own project, so that a session of another project never reads or acts as one of its users, and signing out of the app never ends it. The SDKs pass it when they read the session or sign out.

sess.project_mismatch does not mean the session is invalid: it is live in its own project, so keep its cookie.

Match^[a-zA-Z0-9_-]+$

Request Body

The changes to merge into the user.

application/json
  1. body

A partial update of the caller's own attributes, merged into the current state: an omitted key stays untouched, an object merges recursively, null deletes the attribute, and any other value replaces the stored one. The merged result is validated as a whole against the user's schema.

Unlike PATCH /users/{user_id}, the schema pointer cannot be moved here: schema upgrades are a management operation.

attributes*

The changed attributes only. null deletes an attribute; omitted keys are untouched.

Properties1 <= properties

Response Body

Updated user state.

application/json
  1. response

A user represents an individual identity in the system. It can be used to represent a human user, but also a service account or any other type of identity.

attributes is the document that satisfies the user schema named by schema: its property names and types are defined entirely by that schema, and it is what the schema validates. The rest of the object — id, schema, metadata — is the server-owned envelope. Keeping the two apart means a schema may name a property id or metadata without colliding with the envelope, and closed-world keywords (additionalProperties: false, propertyNames, unevaluatedProperties) behave as their author expects.

id*user-id
Match^user_[a-zA-Z0-9_-]+$
schema*string

The schema that defines the content of attributes. These schemas can be created using the /schemas endpoint. A default schema is provided. This schema can be retrieved using the same endpoint.

attributes*

The user's content, satisfying the schema named by schema. Property names and types are determined entirely by that schema.

metadata*
identifier?string

The current value of the user schema's designated identifier (x-identifier), resolved live at read time. Absent when the schema designates no identifier or the user carries no value for it.

identifier_property?string

The schema property identifier came from, so clients can reach the property's schema for semantics (a mailto link, a field label) instead of guessing from the value. Present exactly when identifier is.

display?string

The x-display rendering — the designated properties' values joined in list order, resolved live at read time. Purely presentational. Absent when the schema designates no display properties or the user carries no values for them. Clients render display, falling back to identifier, then id.

teams?array<>

The user's team memberships, present only when the request asked for them with expand: ["teams"] (ADR 059). Absent means it was not requested; [] means the user has none.

Deliberately outside metadata: memberships are a related collection, not part of the server-owned envelope, and it is a different concept from metadata.lifecycle_owner_team_id (ADR 024).

teams_truncated?boolean

True when the user is on more teams than the embedded list carries. The embedded list is capped and cannot be paged; read them all at GET /users/{user_id}/teams. Present only alongside teams.

Example Request
import { configureZitadel, getApi } from "@zitadel/api/config";import { setApiCsrfToken } from "@zitadel/api/runtime/auth";// In the browser, through the SDK proxy: the session cookie authenticates the call.const client = getApi(configureZitadel({ projectId: "proj_01KWH1P4MYS7F0N9WD3P2E4YM5" }));// A write the session cookie authenticates carries the session's CSRF token.setApiCsrfToken((await client.getMySessionCsrfToken()).csrf_token);const myUser = await client.patchMyUser({ attributes: {} });
Example Response
{  "id": "string",  "schema": "string",  "attributes": {},  "metadata": {    "created_at": "2019-08-24T14:15:22Z",    "updated_at": "2019-08-24T14:15:22Z",    "status": "active",    "lifecycle_owner_team_id": "string",    "lifecycle_owner_team": {      "id": "string",      "name": "string",      "status": "active",      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  },  "identifier": "string",  "identifier_property": "string",  "display": "string",  "teams": [    {      "id": "string",      "name": "string",      "membership_status": "pending",      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ],  "teams_truncated": true}

Was this helpful?