Skip to content

Edit a user's profile (self or moderator)

PATCH
/users/{ref}

Self-edit always allowed; editing other users requires the users.profile.edit.any capability (Admin by default).

ref
required
integer format: int64

PATCH semantics — only present fields are updated, but the schema treats each field as the new full value (no JSON Merge Patch nested ops). Clearing a field is sending an empty string (for text) or null (for nullable URLs).

object
display_name
string
nullable <= 100 characters
bio
string
<= 1000 characters
avatar_url
string
nullable <= 1024 characters
location
string
<= 100 characters
website_url
string format: uri
nullable <= 500 characters
social_links
object
key
additional properties
string
<= 100 characters
language

BCP47 tag, or empty string to reset to “system default”. Validated only loosely server-side — frontend constrains the picker to a known list.

string
<= 35 characters
theme

Empty string resets the pref to “follow system”.

string
Allowed values: "" light dark
hide_from_anonymous

Owner opt-out from anonymous profile exposure (ADR 0070 → ADR 0024). Default false. When true, the owner’s public profile page (/users/by-username, /users/by-ref) returns 404 to anonymous viewers even with public mode on. Authenticated viewers and the content-visibility gating are unaffected.

boolean

Updated profile

Merged user + profile view. display_name is the resolved display string (profile.display_name → user.fullname → user.username, first non-empty). avatar_url is null for users without an uploaded avatar; the frontend renders a generated initials disc in that case.

object
ref
required
integer format: int64
username
required
string
fullname

The raw user.fullname value, for the rare case a caller needs the unresolved string (account settings page). Most UI surfaces should use display_name instead.

string
nullable
display_name
required

Resolved display string ready to render — never empty.

string
bio
string
avatar_url
string
nullable
location
string
website_url
string format: uri
nullable
social_links

Free-form platform → handle map. Frontend renders known platforms (twitter, instagram, artstation, …) as icon links; unknown keys are ignored.

object
key
additional properties
string
language

IETF BCP47 language tag (e.g. “en”, “es-AR”). Empty string = “use system / browser default”. Drives the i18n switcher in the user menu.

string
theme

UI theme preference. Empty string = follow system / OS. Persisted alongside the profile so it follows the user across browsers.

string
Allowed values: "" light dark
member_since
required
string format: date-time
post_count
required

Total live posts authored by this user.

integer format: int64
origin_server_id

Set on profiles mirroring a remote site’s user. NULL = locally-owned account.

string format: uuid
nullable

Malformed request

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Authentication required, missing, or invalid

object
error
required

Human-readable error summary

string
Example
the request could not be completed
Example
{
"error": "authentication required: sign in and retry with a valid session or API token"
}

Authenticated but missing required capabilities

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Resource not found

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Operator has disabled self-edit for the field carried in field. The frontend renders an inline “locked by your administrator” tooltip without blocking other fields.

object
error
required
string
reason
required
string
Allowed values: field_disabled_by_operator
field
required
string