User API
User, Profile, and Permission Surface
Manage profile data, language, visibility preferences, and permission bootstrap
These routes back the signed-in user settings area and the helper APIs the frontend uses to hydrate the current session. They do not include admin-only user management.
JWT or user API keyMultipart uploadProfile preferencesPermission bootstrap
Source
- Profile controller:
backend-nestjs/src/controllers/user-profile.controller.ts - Language controller:
backend-nestjs/src/controllers/user-language.controller.ts - Permissions controller:
backend-nestjs/src/controllers/user-permissions.controller.ts - Users controller:
backend-nestjs/src/users/users.controller.ts - DTOs:
backend-nestjs/src/dto/user-profile.dto.ts,backend-nestjs/src/users/dto/list-users.query.dto.ts
Authentication and Permissions
- All routes on this page require authentication.
- Routes using
JwtAuthGuardaccept bearer JWT and, where supported, user API keys. POST /api/user/profile-pictureis marked with@AllowIncompleteOnboarding(), so it can be used before onboarding is complete.- Profile writes are scoped to the authenticated user only.
Endpoint Reference
Profile and Settings
| Method | Path | Purpose | Request or query | Auth | Source |
|---|---|---|---|---|---|
GET | /api/user/profile | Read the current user profile and settings. | None | JWT or user API key | controllers/user-profile.controller.ts |
POST | /api/user/profile-picture | Upload and set a profile picture. | Multipart field: file | JWT or user API key | controllers/user-profile.controller.ts |
PATCH | /api/user/profile | Update profile fields and UI preferences. | Body: profile fields | JWT or user API key | controllers/user-profile.controller.ts |
DELETE | /api/user/event-labels/:label | Remove one saved event label and strip it from the user's events. | Path: label | JWT or user API key | controllers/user-profile.controller.ts |
PATCH | /api/user/theme | Update theme color only. | Body: themeColor | JWT or user API key | controllers/user-profile.controller.ts |
PATCH | /api/user/password | Change the current user's password. | Body: currentPassword,newPassword | JWT or user API key | controllers/user-profile.controller.ts |
PATCH | /api/users/me/language | Update the preferred UI language. | Body: preferredLanguage | JWT or user API key | controllers/user-language.controller.ts |
Session Bootstrap and Sharing Helpers
| Method | Path | Purpose | Request or query | Auth | Source |
|---|---|---|---|---|---|
GET | /api/users/me | Read the current user entity from the users service. | None | JWT or user API key | users/users.controller.ts |
GET | /api/users | Search users for sharing flows. | Query: search | JWT or user API key | users/users.controller.ts |
GET | /api/user-permissions | Get the current permission snapshot. | None | JWT or user API key | controllers/user-permissions.controller.ts |
GET | /api/user-permissions/accessible-organizations | List organizations accessible to the current user. | None | JWT or user API key | controllers/user-permissions.controller.ts |
GET | /api/user-permissions/accessible-reservation-calendars | List reservation calendars accessible to the current user. | None | JWT or user API key | controllers/user-permissions.controller.ts |
Request Shapes
Update profile
UpdateProfileDto in backend-nestjs/src/dto/user-profile.dto.ts
username: optional, minimum 3 charsemail: optional, valid emailfirstName: optional stringlastName: optional stringprofilePictureUrl: optional URL, max 2048 charsweekStartDay: optional integer0..6defaultCalendarView: optionalmonth|weektimezone: optional stringtimeFormat: optional12h|24hlanguage: optional enumen|hu|de|frpreferredLanguage: optional enumen|hu|de|frhideReservationsTab: optional booleanhiddenResourceIds: optional number arrayvisibleCalendarIds: optional number arrayvisibleResourceTypeIds: optional number arrayhiddenFromLiveFocusTags: optional string array, max 64 chars eacheventLabels: optional string array, max 64 chars eachdefaultTasksCalendarId: optional number ornull
Implementation behavior from the controller:
- Username and email uniqueness are rechecked only if those fields actually changed.
hiddenFromLiveFocusTagsandeventLabelsare normalized, deduplicated, trimmed, and capped to 100 items.defaultTasksCalendarIdcan be cleared withnull.- Changing
defaultTasksCalendarIdcan trigger task-to-calendar resyncs for tasks with due dates.
Profile picture upload
Rules enforced in backend-nestjs/src/controllers/user-profile.controller.ts
- field name:
file - allowed MIME types:
image/jpeg,image/png,image/gif,image/webp - max file size:
2MB
Theme and password
UpdateThemeDto.themeColor: optional hex string#rgbor#rrggbbChangePasswordDto.currentPassword: required stringChangePasswordDto.newPassword: required, minimum 6 chars
Language
UpdateLanguagePreferenceDto.preferredLanguage: required enumen|hu|de|fr
User search
ListUsersQueryDto.search: optional safe text, max 80 chars
Example Calls
Update profile preferences
curl -X PATCH "$PRIMECAL_API/api/user/profile" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"timezone": "Europe/Budapest",
"timeFormat": "24h",
"weekStartDay": 1,
"visibleCalendarIds": [2, 3, 5],
"hiddenFromLiveFocusTags": ["no_focus", "private"],
"defaultTasksCalendarId": 7
}'
Upload a profile picture
curl -X POST "$PRIMECAL_API/api/user/profile-picture" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@C:/tmp/avatar.webp"
Search users for sharing
curl "$PRIMECAL_API/api/users?search=justin" \
-H "Authorization: Bearer $TOKEN"
Bootstrap permission-aware UI
curl "$PRIMECAL_API/api/user-permissions" \
-H "Authorization: Bearer $TOKEN"
Response Notes
GET /api/user/profilereturns the richest user-settings payload, including visibility preferences, live-focus hidden tags, event labels, onboarding state, and privacy policy acceptance info.GET /api/users/meis a lighter current-user lookup from the users service.PATCH /api/user/passwordreturns a simple success message after validating the current password.DELETE /api/user/event-labels/:labelreturns the removed label, remaining labels, and the number of events affected.
Best Practices
- Use
GET /api/user/profileas the primary settings bootstrap route. - Use
GET /api/user-permissionsbefore rendering reservations, organization settings, or role-sensitive UI. - Send only changed fields in
PATCH /api/user/profile; the controller intentionally performs narrow uniqueness checks. - Keep
eventLabelsandhiddenFromLiveFocusTagsnormalized on the client too, so UI state matches the backend normalization rules. - Use
Personal Logs APIfor audit history rather than overloading these settings endpoints with activity concerns.