Account profile
GET /v1/account/me and PATCH /v1/account/me — field table, update semantics and constraints.
/v1/account/me is the account's extended profile. Identity fields come from auth and the extended profile belongs to account; the response keeps them in two blocks instead of flattening them, because merging into one layer would erase "which context owns this field" from the contract entirely.
GET /me
curl 'https://id.example.com/v1/account/me' \
-H "Authorization: Bearer $ACCOUNT_ACCESS_TOKEN"{
"success": true,
"sub": "usr_...",
"username": "alice",
"display_name": "Alice",
"email": "[email protected]",
"email_verified": true,
"created_at": "2026-01-04T10:00:00.000Z",
"profile": {
"gender": "female",
"birthdate": "1994-03-08",
"age": 32,
"locale": "zh-Hans",
"timezone": "Asia/Shanghai",
"bio": "Hello",
"metadata": {}
}
}| Field | Owner | Notes |
|---|---|---|
sub | auth | Unique user identifier |
username | auth | Username, may be null |
display_name | auth | Display name |
email / email_verified | auth | Primary email and its verification state |
created_at | auth | Account creation time |
profile.gender | account | Gender, nullable |
profile.birthdate | account | Birthdate, YYYY-MM-DD, nullable |
profile.age | account | Age derived from the birthdate, read-only, nullable |
profile.locale | account | Language preference, nullable |
profile.timezone | account | Time zone, nullable |
profile.bio | account | Bio, up to 2000 chars |
profile.metadata | account | Custom key/value pairs, bounded on write |
PATCH /me
Partial update: omitted fields stay unchanged, an explicit null clears a value.
| Parameter | Type | Notes |
|---|---|---|
gender | string | null | 1–32 chars |
birthdate | string | null | YYYY-MM-DD, must be a real calendar date |
locale | string | null | 1–35 chars |
timezone | string | null | 1–64 chars |
bio | string | null | Up to 2000 chars |
metadata | object | Keys 1–64 chars, at most 32 keys, 4096 bytes serialized |
curl -X PATCH 'https://id.example.com/v1/account/me' \
-H "Authorization: Bearer $ACCOUNT_ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"bio":"Hello","timezone":"Asia/Shanghai"}'Unknown fields are rejected
The body is strict: a field that is not declared is an error, not silently ignored. Extra keys in a PATCH usually mean the client misspelled a name, and ignoring them lets the user believe the change applied when nothing happened.
The birthdate must be a real date
Format validation alone is not enough: 2023-02-30 is well-formed but does not exist, and storing it makes the derived age come out negative or NaN.
Rules
| Rule | Notes |
|---|---|
| No step-up | Updating the profile loses no data |
age is not writable | Derived from birthdate, so the two can never contradict each other |
| metadata bounds | Enforced on write only, not on read; otherwise historical data would make GET fail validation |
Related
- Editing identity fields: Profile
- Identity fields readable by clients: User info
- Scopes and audiences: Scopes and audiences