Skip to content
Zeitlos
Dashboard

Authentication

.md

Profile fields

Store custom fields — a role, a bio, preferences — on every user.

Beyond identity, a project can define custom fields stored on every user: a bio, a role, a set of interests. You define them in the dashboard or via the MCP. Your app reads and writes their values through the SDK.

Defining a field

Go to Authentication → Profile fields and add a field. Each one has:

SettingDescription
NameThe key you'll use in code, e.g. role
DescriptionA note for whoever manages users in the dashboard
TypeText, Single choice, or Multiple choice
OptionsFor the choice types — one per line
Visible to the userWhether the user can see the field at all
Editable by the userWhether the user can change it themselves

Types

The following TypeScript types will be returned depending on the type of the profile field:

TypeValue in code
Textstring | null
Single choicestring | null
Multiple choicestring[] | null

Visibility and editability

The visibility and editability properties of a field define the following:

Visible:

  • true - This field will be returned in the getUser({ profile: true }) response.
  • false - This field will not be returned when getting the profile.

Editable:

  • true - This field can be edited by the user themselves via the updateProfile() method.
  • false - This field can only be edited from the dashboard. Useful for fields like a role.

Editable implies visible, so a field that isn't visible can't be user-editable.

Reading the profile

Ask for the profile alongside the user — one round trip:

TypeScript
const me = await client.auth.getUser({ profile: true });
me?.profile.bio; // "…"
me?.profile.role; // "member"

Writing the profile

TypeScript
await client.auth.updateProfile({ bio: 'Hello' });
await client.auth.updateProfile({ bio: null }); // null clears a field

A user can only update their own profile, and only fields marked editable. Writing a profile field that was marked as not editable is rejected.

Typing the profile

You can pass your field shape as a type argument:

TypeScript
type Profile = {
  bio: string;
  role: 'admin' | 'member';
  interests: string[];
};

const me = await client.auth.getUser<Profile>({ profile: true });
me?.profile.role; // 'admin' | 'member' | null | undefined
me?.profile.xyz; // compile error — not a declared field

Note

Every field comes back optional and nullable — absent if not visible to you, null if visible but unset. Declare the plain shape and the SDK adds | null | undefined for you.

Field values must extend string | string[] | null.

Managing fields

Add, change or remove fields in the dashboard, or through the MCP server — handy when an assistant is writing the code that uses them. The SDK reads and writes values, never definitions.