Files
bookhoard/docs/developer/api/users/update_profile.md
T
John O'Keefe cc5677eb17 docs(auth,users,devices,progress,matching): Beam batch 8 — WO5 backfill complete
14 endpoints backfilled: devices pending/approve/reject; users
password/profile/profile-delete self-service (admin variants in prose);
admin list_users + update_user_max_devices; progress history; book
matching; new password-rules doc.

Gate fix: authLabel missed JWT middleware written inline as
createJWTMiddleware(cfg) (uppercase 'JWT') — reported auth 'none' for
/api/auth self-service routes and would have for any wrapper-inlined
group. Labeled 'JWTMiddleware' + fallthrough 'jwt' case.

Claude registry: 12 entries. Drift fixed by gate: list_users on-device —
handler returns raw []database.Users (bare array, full model incl.
password_hash — real leak the API emits; pinned + documented; earlier
draft had invented {users,total,limit,offset} wrapper). max-devices
response is {message} only. books/match is GET /api/books/match
{matches, action}. progress history sessions = ReadingHistory rows
(pgtype fields). make test 9/9.
2026-10-24 17:33:32 -04:00

2.2 KiB

method, path, auth, area
method path auth area
PUT /api/auth/profile jwt authentication

Update Profile

Update user profile information. Supports both self-edit and admin modes.

Endpoints:

  • Self-edit: PUT /api/auth/profile
  • Admin edit: PUT /api/auth/profile/:id

Auth: Required Content-Type: application/json

Self-Edit Mode

Users can update their own profile. All fields are optional.

Request Body

Field Type Required Description
username string No New username (must be unique, 3-50 chars)
email string No New email (must be unique, valid format)
first_name string No User's first name
last_name string No User's last name
theme string No Theme preference

Example Request

{
  "username": "newusername",
  "email": "newemail@example.com",
  "first_name": "John",
  "last_name": "Smith",
  "theme": "dracula"
}

Admin Mode

Admins can update any user by providing the user ID in the URL. Additionally supports role changes.

URL Parameter: :id - Target user's UUID

Additional Request Body Fields (Admin Only)

Field Type Required Description
role string No New role: "user" or "admin"

Example Admin Request

{
  "username": "newusername",
  "email": "newemail@example.com",
  "role": "admin"
}

Response (200 OK)

{
  "message": null
}

Error Responses

Code Description
400 Invalid input data or invalid role
401 Invalid or expired token
403 Admin access required (admin mode only)
404 User not found (admin mode only)
409 Username or email already taken