User Preferences
User preferences allow users to customize their display and UI settings. Each user has their own preferences that are automatically created on first access.
Overview
User preferences store personalization settings such as:
- Date Format: How dates are displayed
- Time Format: 12-hour or 24-hour time
- Timezone: User's preferred timezone
- Theme: Light or dark mode
- Widget Configuration: Dashboard and UI customization
Preferences are automatically created with default values when a user first accesses them. No manual setup required!
Endpoints
Get User Preferences
Retrieve the current user's preferences. Auto-creates with defaults if not exists.
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/users/me/preferences/ \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"success": true,
"message": "Preferences retrieved successfully",
"data": {
"date_format": "YYYY-MM-DD",
"time_format": "24h",
"timezone": "UTC",
"theme": "light",
"widget_config": {}
}
}
import requests
headers = {"Authorization": "Bearer YOUR_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/users/me/preferences/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/users/me/preferences/", {
headers: { "Authorization": "Bearer YOUR_TOKEN" }
})
const data = await response.json()
Create or Update Preferences
Create or update the current user's preferences. Both POST and PUT work identically (upsert).
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/users/me/preferences/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"date_format": "DD/MM/YYYY",
"time_format": "12h",
"timezone": "Asia/Kolkata",
"theme": "dark",
"widget_config": {
"sidebar_collapsed": true,
"default_page_size": 25,
"show_tooltips": false
}
}'
Response:
{
"success": true,
"message": "Preferences updated successfully",
"data": {
"date_format": "DD/MM/YYYY",
"time_format": "12h",
"timezone": "Asia/Kolkata",
"theme": "dark",
"widget_config": {
"sidebar_collapsed": true,
"default_page_size": 25,
"show_tooltips": false
}
}
}
import requests
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/users/me/preferences/",
headers=headers,
json={
"date_format": "DD/MM/YYYY",
"time_format": "12h",
"timezone": "Asia/Kolkata",
"theme": "dark",
"widget_config": {
"sidebar_collapsed": True,
"default_page_size": 25,
"show_tooltips": False
}
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/users/me/preferences/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
date_format: "DD/MM/YYYY",
time_format: "12h",
timezone: "Asia/Kolkata",
theme: "dark",
widget_config: {
sidebar_collapsed: true,
default_page_size: 25,
show_tooltips: false
}
})
})
const data = await response.json()
Field Reference
Date Format
Controls how dates are displayed in the UI.
Type: string
Required: Yes
Choices:
YYYY-MM-DD- ISO format (2024-01-15)DD/MM/YYYY- European format (15/01/2024)MM/DD/YYYY- US format (01/15/2024)DD-MMM-YYYY- Readable format (15-Jan-2024)
Default: YYYY-MM-DD
Example:
{
"date_format": "DD/MM/YYYY"
}
Time Format
Controls whether time is displayed in 12-hour or 24-hour format.
Type: string
Required: Yes
Choices:
24h- 24-hour format (14:30)12h- 12-hour format (2:30 PM)
Default: 24h
Example:
{
"time_format": "12h"
}
Timezone
User's preferred timezone for displaying dates and times.
Type: string
Required: Yes
Validation: Must be a valid IANA timezone
Default: UTC
Common Values:
UTCAmerica/New_YorkAmerica/Los_AngelesEurope/LondonEurope/ParisAsia/KolkataAsia/TokyoAustralia/Sydney
Example:
{
"timezone": "Asia/Kolkata"
}
Theme
UI theme preference for the application.
Type: string
Required: Yes
Choices:
light- Light themedark- Dark theme
Default: light
Example:
{
"theme": "dark"
}
Widget Config
Flexible JSON field for storing dashboard and widget configurations.
Type: object
Required: No
Validation: None (completely flexible)
Default: {}
Example:
{
"widget_config": {
"sidebar_collapsed": true,
"default_page_size": 25,
"show_tooltips": false,
"dashboard_layout": "grid",
"widgets": [
{
"id": "stats",
"position": {"x": 0, "y": 0, "w": 6, "h": 2}
},
{
"id": "chart",
"position": {"x": 6, "y": 0, "w": 6, "h": 4}
}
]
}
}
Usage Examples
Format Date Based on Preference
// Format date based on user preference
function formatDate(date, format) {
switch(format) {
case 'YYYY-MM-DD':
return date.toISOString().split('T')[0];
case 'DD/MM/YYYY':
return `${date.getDate()}/${date.getMonth()+1}/${date.getFullYear()}`;
case 'MM/DD/YYYY':
return `${date.getMonth()+1}/${date.getDate()}/${date.getFullYear()}`;
case 'DD-MMM-YYYY':
const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
return `${date.getDate()}-${months[date.getMonth()]}-${date.getFullYear()}`;
}
}
Error Responses
Invalid Timezone
{
"success": false,
"errors": {
"timezone": ["Invalid timezone: Invalid/Timezone"]
}
}
Invalid Date Format
{
"success": false,
"errors": {
"date_format": ["\"INVALID_FORMAT\" is not a valid choice."]
}
}
Invalid Theme
{
"success": false,
"errors": {
"theme": ["\"auto\" is not a valid choice."]
}
}
Unauthenticated
{
"detail": "Authentication credentials were not provided."
}
Best Practices
1. Load Preferences on App Initialization
// Load preferences when app starts
useEffect(() => {
async function loadPreferences() {
const prefs = await getPreferences();
// Apply preferences to app
applyTheme(prefs.theme);
setDateFormat(prefs.date_format);
setTimezone(prefs.timezone);
}
loadPreferences();
}, []);
2. Debounce Preference Updates
// Debounce updates to avoid excessive API calls
const debouncedUpdate = debounce(async (preferences) => {
await updatePreferences(preferences);
}, 500);
// Usage
function handleThemeChange(theme) {
debouncedUpdate({ ...currentPrefs, theme });
}
3. Cache Preferences Locally
// Cache in localStorage for faster loads
function cachePreferences(prefs) {
localStorage.setItem('user_preferences', JSON.stringify(prefs));
}
function getCachedPreferences() {
const cached = localStorage.getItem('user_preferences');
return cached ? JSON.parse(cached) : null;
}
4. Validate Before Sending
// Validate preferences before updating
function validatePreferences(prefs) {
const validDateFormats = ['YYYY-MM-DD', 'DD/MM/YYYY', 'MM/DD/YYYY', 'DD-MMM-YYYY'];
const validTimeFormats = ['24h', '12h'];
const validThemes = ['light', 'dark'];
if (!validDateFormats.includes(prefs.date_format)) {
throw new Error('Invalid date format');
}
if (!validTimeFormats.includes(prefs.time_format)) {
throw new Error('Invalid time format');
}
if (!validThemes.includes(prefs.theme)) {
throw new Error('Invalid theme');
}
return true;
}
Common Workflows
Initial Setup
- User logs in for the first time
- App calls GET
/api/users/me/preferences/ - Backend auto-creates preferences with defaults
- App applies default preferences to UI
Changing Theme
- User clicks theme toggle
- App updates local state immediately (optimistic update)
- App calls POST
/api/users/me/preferences/with new theme - Backend validates and saves
- On error, revert to previous theme
Timezone Detection
- Detect user's timezone using browser API
- Compare with saved preference
- If different, prompt user to update
- Update preference if user confirms
// Detect browser timezone
const browserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
// Compare with saved preference
if (browserTimezone !== preferences.timezone) {
// Prompt user to update
const shouldUpdate = confirm(
`Your timezone appears to be ${browserTimezone}. Update preferences?`
);
if (shouldUpdate) {
await updatePreferences({
...preferences,
timezone: browserTimezone
});
}
}
Security Considerations
- User-Specific: Each user can only access their own preferences
- Authentication Required: All endpoints require valid authentication
- No Sensitive Data: Preferences should not contain sensitive information
- Validation: All fields are validated on the backend
- Rate Limiting: Standard API rate limits apply
Limitations
- No Partial Updates: POST/PUT replaces all fields (full update only)
- No History: Previous preferences are not stored
- No Sharing: Preferences cannot be shared between users
- Tenant-Specific: Preferences are stored per tenant (not global)
Related Features
- Users - User management and authentication
- User Management API - Complete user API reference
- Authentication - Authentication methods