ZitadelDocs

Create user

POST
/users

Authorization

headerAuthorizationBearer <token>

Scope: user.write

Query Parameters

project_id*string

The unique identifier of the project

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

Adds the new user to this team: creating the user also creates an active membership in it. Omit it to create a user with no memberships.

This is team membership, not lifecycle ownership. It does not decide who may deprovision the user, and the created user stays self-owned either way. The owning team is reported on reads as metadata.lifecycle_owner_team_id and cannot be set through this API. See ADR 024.

The team also scopes team-unique attributes for this create: an attribute the schema marks unique per team is checked against this team's members.

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

Request Body

application/json
  1. body

attributes is the document that must satisfy the user schema named by schema.

The resource primary key is server-assigned and returned in the response, so the request carries no id; metadata is server-owned for the same reason. Neither is part of this schema, which is what frees a user schema to declare properties of those names.

A request carrying any other top-level property is rejected rather than ignored. attributes stays open, since the user schema is what determines what belongs in it.

schema*string

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

Length1 <= length
attributes*

The user's schema-defined content. Validated against schema; a property the schema does not permit is rejected with user.invalid.

Response Body

The user was created successfully

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.

curl -X POST 'https://example.com/users?project_id=string' \  -H 'Content-Type: application/json' \  -d '{  "schema": "string",  "attributes": {}}'
{  "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}