User Profile
Manage user profiles, settings, and account preferences
Manage user profiles, settings, and account information.
Profile Management
Complete user profile management including personal information, settings, preferences, notifications, and account security.
Overview
The User Profile API provides:
- Profile information management
- User settings and preferences
- Password changes
- Account deletion
- User statistics
- Admin user management
Base Path: /v1/user
Get User Profile
Retrieve the authenticated user's profile information.
GET /v1/user/profileX-API-Key: your-api-key
Authorization: Bearer your-jwt-token{
"success": true,
"status": 200,
"message": "Profile retrieved successfully",
"data": {
"id": "user_123",
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"username": "johndoe",
"avatar": "https://cdn.yourdomain.com/avatars/user_123.jpg",
"bio": "Professional forex trader with 10 years experience",
"phone": "+1234567890",
"role": "user",
"status": "active",
"emailVerified": true,
"phoneVerified": false,
"location": {
"country": "United States",
"city": "New York",
"timezone": "America/New_York"
},
"social": {
"twitter": "https://twitter.com/johndoe",
"linkedin": "https://linkedin.com/in/johndoe",
"website": "https://johndoe.com"
},
"stats": {
"postsCount": 45,
"followersCount": 234,
"followingCount": 156,
"coursesCompleted": 12,
"tradesWon": 89,
"tradesTotal": 134
},
"preferences": {
"theme": "dark",
"language": "en",
"notifications": {
"email": true,
"push": true,
"sms": false
},
"privacy": {
"showEmail": false,
"showPhone": false,
"profileVisible": true
}
},
"createdAt": "2024-01-15T00:00:00.000Z",
"updatedAt": "2025-10-21T12:00:00.000Z",
"lastLogin": "2025-10-21T09:30:00.000Z"
},
"meta": {
"timestamp": "2025-10-21T12:00:00.000Z",
"version": "v1"
}
}Update Profile
Update user profile information.
PUT /v1/user/profileX-API-Key: your-api-key
Authorization: Bearer your-jwt-token
Content-Type: application/json{
"firstName": "John",
"lastName": "Smith",
"username": "johnsmith",
"bio": "Updated bio here",
"phone": "+1234567890",
"location": {
"country": "United States",
"city": "Los Angeles",
"timezone": "America/Los_Angeles"
},
"social": {
"twitter": "https://twitter.com/johnsmith",
"linkedin": "https://linkedin.com/in/johnsmith",
"website": "https://johnsmith.com"
}
}{
"success": true,
"status": 200,
"message": "Profile updated successfully",
"data": {
"id": "user_123",
"firstName": "John",
"lastName": "Smith",
"username": "johnsmith",
// ... updated fields
"updatedAt": "2025-10-21T12:05:00.000Z"
},
"meta": {
"timestamp": "2025-10-21T12:05:00.000Z",
"version": "v1"
}
}Validation Rules:
firstName: 1-50 characterslastName: 1-50 charactersusername: 3-30 characters, alphanumeric + underscorebio: Max 500 charactersphone: Valid phone number format
Change Password
Change the user's password.
PUT /v1/user/password{
"currentPassword": "OldPassword123!",
"newPassword": "NewPassword456!",
"confirmPassword": "NewPassword456!"
}{
"success": true,
"status": 200,
"message": "Password changed successfully",
"data": null,
"meta": {
"timestamp": "2025-10-21T12:10:00.000Z",
"version": "v1"
}
}Password Requirements:
- **Minimum 8 characters
- **At least one uppercase letter
- **At least one lowercase letter
- **At least one number
- **At least one special character
- **Cannot be same as previous 3 passwords
User Settings
Get Settings
GET /v1/user/settings{
"success": true,
"status": 200,
"data": {
"theme": "dark",
"language": "en",
"timezone": "America/New_York",
"dateFormat": "MM/DD/YYYY",
"timeFormat": "12h",
"currency": "USD",
"notifications": {
"email": {
"enabled": true,
"frequency": "instant",
"types": ["trade_alerts", "course_updates", "announcements"]
},
"push": {
"enabled": true,
"types": ["messages", "trade_alerts", "comments"]
},
"sms": {
"enabled": false,
"types": ["critical_alerts"]
}
},
"privacy": {
"showEmail": false,
"showPhone": false,
"profileVisible": true,
"showOnlineStatus": true,
"allowMessages": "everyone",
"allowComments": "everyone"
},
"trading": {
"defaultLotSize": 1.0,
"defaultRiskPercent": 2.0,
"confirmOrders": true,
"showPnL": true
},
"education": {
"autoPlayNextLesson": true,
"playbackSpeed": 1.0,
"showTranscripts": true
}
}
}Update Settings
PUT /v1/user/settings{
"theme": "light",
"language": "es",
"notifications": {
"email": {
"enabled": true,
"frequency": "daily_digest",
"types": ["trade_alerts", "announcements"]
},
"push": {
"enabled": false
}
},
"trading": {
"defaultRiskPercent": 1.5
}
}{
"success": true,
"status": 200,
"message": "Settings updated successfully",
"data": {
// Updated settings object
}
}User Statistics
Get detailed user statistics and activity metrics.
GET /v1/user/stats{
"success": true,
"status": 200,
"message": "User stats retrieved successfully",
"data": {
"overview": {
"memberSince": "2024-01-15T00:00:00.000Z",
"daysSinceMember": 280,
"lastActive": "2025-10-21T09:30:00.000Z",
"totalLogins": 456
},
"trading": {
"totalTrades": 134,
"activeTrades": 5,
"wins": 89,
"losses": 45,
"winRate": 66.42,
"totalProfitLoss": 2345.67,
"bestTrade": 450.00,
"worstTrade": -125.00,
"averageHoldTime": "2.5 days",
"favoriteSymbols": ["EUR/USD", "GBP/JPY", "XAU/USD"]
},
"education": {
"coursesEnrolled": 8,
"coursesCompleted": 5,
"lessonsCompleted": 234,
"totalWatchTime": 45600,
"averageProgress": 67.5,
"certificates": 5
},
"community": {
"postsCreated": 45,
"commentsPosted": 234,
"reactionsGiven": 567,
"reactionsReceived": 1234,
"followers": 234,
"following": 156,
"reputation": 892
},
"ai": {
"conversationsTotal": 67,
"messagesTotal": 890,
"tokensUsed": 234567,
"favoriteTopics": ["Technical Analysis", "Risk Management"]
},
"engagement": {
"weeklyActive": true,
"dailyActive": true,
"streak": 14,
"longestStreak": 45
}
}
}Avatar Upload
Upload Avatar
POST /v1/user/avatarX-API-Key: your-api-key
Authorization: Bearer your-jwt-token
Content-Type: multipart/form-dataForm Data:
avatar: [file]{
"success": true,
"status": 200,
"message": "Avatar uploaded successfully",
"data": {
"avatarUrl": "https://cdn.yourdomain.com/avatars/user_123.jpg"
}
}Requirements:
- File types: JPG, PNG, GIF
- Max size: 5MB
- Recommended: 400x400px square
- Auto-resized to 400x400px
Delete Account
Permanently delete user account.
DELETE /v1/user/accountX-API-Key: your-api-key
Authorization: Bearer your-jwt-token
Content-Type: application/json{
"password": "CurrentPassword123!",
"confirmation": "DELETE MY ACCOUNT"
}{
"success": true,
"status": 200,
"message": "Account deleted successfully",
"data": null
}What Happens:
- **User data anonymized or deleted
- **Sessions terminated
- **Tokens invalidated
- **Subscriptions cancelled
- **Content optionally preserved or deleted
- **Backup created for 30 days (GDPR compliance)
**This action is irreversible!
Admin Endpoints
Get All Users (Admin Only)
GET /v1/admin/users| Parameter | Type | Description |
|---|---|---|
| page | number | Page number |
| limit | number | Results per page |
| search | string | Search by name or email |
| role | string | Filter by role |
| status | string | Filter by status |
{
"success": true,
"status": 200,
"data": [
{
"id": "user_123",
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"role": "user",
"status": "active",
"emailVerified": true,
"createdAt": "2024-01-15T00:00:00.000Z",
"lastLogin": "2025-10-21T09:30:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 12500,
"pages": 625
}
}Get User by ID (Admin Only)
GET /v1/admin/users/:userIdResponse: Same as GET /v1/user/profile
Update User Role (Admin Only)
PUT /v1/admin/users/:userId/role{
"role": "educator"
}Available Roles:
user- Regular usereducator- Can create coursestrader- Premium trading featuresadmin- Full platform accessmoderator- Content moderation access
Update User Status (Admin Only)
PUT /v1/admin/users/:userId/status{
"status": "suspended",
"reason": "Terms of service violation"
}Available Statuses:
active- Normal accountsuspended- Temporarily disabledbanned- Permanently disabledpending- Awaiting verification
Delete User (Admin Only)
DELETE /v1/admin/users/:userIdPlatform Statistics (Admin Only)
GET /v1/admin/stats{
"success": true,
"status": 200,
"data": {
"users": {
"total": 12500,
"active": 8234,
"new_today": 45,
"new_this_week": 234,
"new_this_month": 890
},
"engagement": {
"daily_active_users": 3456,
"weekly_active_users": 6789,
"monthly_active_users": 9012,
"average_session_duration": 420
},
"content": {
"total_posts": 12345,
"total_comments": 34567,
"total_courses": 123,
"total_lessons": 1234
},
"trading": {
"active_trades": 456,
"total_trades": 23456,
"win_rate": 64.5
},
"revenue": {
"monthly": 45678.90,
"annual": 548146.80
}
}
}Notification Preferences
Get Notification Preferences
GET /v1/user/settings/notifications{
"success": true,
"status": 200,
"data": {
"email": {
"enabled": true,
"frequency": "instant",
"types": {
"trade_alerts": true,
"course_updates": true,
"announcements": true,
"weekly_summary": false,
"marketing": false
}
},
"push": {
"enabled": true,
"types": {
"messages": true,
"trade_alerts": true,
"comments": true,
"reactions": false
}
},
"sms": {
"enabled": false,
"types": {
"critical_alerts": true
}
}
}
}Update Notification Preferences
PUT /v1/user/settings/notifications{
"email": {
"enabled": true,
"frequency": "daily_digest",
"types": {
"trade_alerts": true,
"marketing": false
}
},
"push": {
"enabled": false
}
}Frequency Options:
instant- Immediate deliveryhourly_digest- Batched hourlydaily_digest- Once per dayweekly_digest- Once per weekdisabled- No emails
Privacy Settings
Get Privacy Settings
GET /v1/user/settings/privacy{
"success": true,
"status": 200,
"data": {
"profileVisible": true,
"showEmail": false,
"showPhone": false,
"showLocation": true,
"showOnlineStatus": true,
"showActivity": true,
"allowMessages": "everyone",
"allowComments": "everyone",
"allowTagging": "following",
"dataSharing": {
"analytics": true,
"marketing": false,
"thirdParty": false
}
}
}Update Privacy Settings
PUT /v1/user/settings/privacy{
"profileVisible": true,
"showEmail": false,
"allowMessages": "following",
"dataSharing": {
"marketing": false
}
}Options for allowMessages and allowComments:
everyone- All usersfollowing- Only users I followfollowers- Only my followersnone- Nobody
Options for allowTagging:
everyonefollowingnone
Profile Completion
Check profile completion percentage:
GET /v1/user/profile/completion{
"success": true,
"status": 200,
"data": {
"percentage": 85,
"completed": [
"basic_info",
"avatar",
"bio",
"location",
"social_links"
],
"missing": [
"phone_verification",
"trading_experience"
],
"suggestions": [
{
"field": "phone",
"action": "Add and verify your phone number",
"points": 10
},
{
"field": "tradingExperience",
"action": "Complete trading experience survey",
"points": 5
}
]
}
}Achievements & Badges
Get User Achievements
GET /v1/user/achievements{
"success": true,
"status": 200,
"data": {
"total": 23,
"categories": {
"trading": [
{
"id": "first_trade",
"title": "First Trade",
"description": "Created your first trade idea",
"icon": "🎯",
"earnedAt": "2024-01-20T10:00:00.000Z"
},
{
"id": "winning_streak_10",
"title": "10 Win Streak",
"description": "10 winning trades in a row",
"icon": "🔥",
"earnedAt": "2024-03-15T14:30:00.000Z"
}
],
"education": [
{
"id": "first_course",
"title": "Eager Learner",
"description": "Completed your first course",
"icon": "📚",
"earnedAt": "2024-02-01T00:00:00.000Z"
}
],
"community": [
{
"id": "popular_post",
"title": "Popular Creator",
"description": "Post received 100+ reactions",
"icon": "*",
"earnedAt": "2024-04-10T12:00:00.000Z"
}
]
}
}
}Following System
Get Followers
GET /v1/user/followers| Parameter | Type | Description |
|---|---|---|
| page | number | Page number |
| limit | number | Results per page |
{
"success": true,
"status": 200,
"data": [
{
"id": "user_789",
"firstName": "Jane",
"lastName": "Smith",
"username": "janesmith",
"avatar": "https://cdn.yourdomain.com/avatars/user_789.jpg",
"bio": "Forex trader",
"followedAt": "2024-05-10T00:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 234,
"pages": 12
}
}Get Following
GET /v1/user/followingResponse: Same format as Get Followers
Follow User
POST /v1/user/follow/:userId{
"success": true,
"status": 200,
"message": "User followed successfully",
"data": {
"userId": "user_789",
"following": true
}
}Unfollow User
DELETE /v1/user/follow/:userIdCode Examples
React Profile Component
import { useState, useEffect } from 'react';
function UserProfile() {
const [profile, setProfile] = useState(null);
const [editing, setEditing] = useState(false);
useEffect(() => {
fetchProfile();
}, []);
const fetchProfile = async () => {
const response = await fetch('/v1/user/profile', {
headers: {
'X-API-Key': apiKey,
'Authorization': `Bearer ${token}`
}
});
const { data } = await response.json();
setProfile(data);
};
const updateProfile = async (updates) => {
const response = await fetch('/v1/user/profile', {
method: 'PUT',
headers: {
'X-API-Key': apiKey,
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(updates)
});
const { data } = await response.json();
setProfile(data);
setEditing(false);
};
if (!profile) return <div>Loading...</div>;
return (
<div className="profile">
{editing ? (
<ProfileEditForm
profile={profile}
onSave={updateProfile}
onCancel={() => setEditing(false)}
/>
) : (
<>
<img src={profile.avatar} alt={profile.firstName} />
<h1>{profile.firstName} {profile.lastName}</h1>
<p>@{profile.username}</p>
<p>{profile.bio}</p>
<div className="stats">
<div>
<strong>{profile.stats.followersCount}</strong>
<span>Followers</span>
</div>
<div>
<strong>{profile.stats.followingCount}</strong>
<span>Following</span>
</div>
<div>
<strong>{profile.stats.postsCount}</strong>
<span>Posts</span>
</div>
</div>
<button onClick={() => setEditing(true)}>
Edit Profile
</button>
</>
)}
</div>
);
}Settings Management
async function updateSettings(newSettings) {
const response = await fetch('/v1/user/settings', {
method: 'PUT',
headers: {
'X-API-Key': apiKey,
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(newSettings)
});
const { data } = await response.json();
return data;
}
// Example: Toggle dark mode
await updateSettings({
theme: 'dark'
});
// Example: Disable email notifications
await updateSettings({
notifications: {
email: {
enabled: false
}
}
});
// Example: Update privacy
await updateSettings({
privacy: {
profileVisible: false,
allowMessages: 'following'
}
});Password Change Flow
async function changePassword(currentPassword, newPassword) {
try {
const response = await fetch('/v1/user/password', {
method: 'PUT',
headers: {
'X-API-Key': apiKey,
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
currentPassword,
newPassword,
confirmPassword: newPassword
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return { success: true };
} catch (error) {
console.error('Password change failed:', error);
return { success: false, error: error.message };
}
}
// Usage
const result = await changePassword('OldPass123!', 'NewPass456!');
if (result.success) {
alert('Password changed successfully!');
} else {
alert(`Error: ${result.error}`);
}Avatar Upload
async function uploadAvatar(file) {
const formData = new FormData();
formData.append('avatar', file);
const response = await fetch('/v1/user/avatar', {
method: 'POST',
headers: {
'X-API-Key': apiKey,
'Authorization': `Bearer ${token}`
// Don't set Content-Type, browser will set it with boundary
},
body: formData
});
const { data } = await response.json();
return data.avatarUrl;
}
// Usage with file input
const input = document.getElementById('avatarInput');
input.addEventListener('change', async (e) => {
const file = e.target.files[0];
if (file.size > 5 * 1024 * 1024) {
alert('File too large. Max 5MB.');
return;
}
const avatarUrl = await uploadAvatar(file);
console.log('New avatar:', avatarUrl);
});Profile Object Schema
interface UserProfile {
id: string;
email: string;
firstName: string;
lastName: string;
username: string;
avatar?: string;
bio?: string;
phone?: string;
role: 'user' | 'educator' | 'trader' | 'admin' | 'moderator';
status: 'active' | 'suspended' | 'banned' | 'pending';
emailVerified: boolean;
phoneVerified: boolean;
location?: {
country: string;
city: string;
timezone: string;
};
social?: {
twitter?: string;
linkedin?: string;
website?: string;
};
stats: {
postsCount: number;
followersCount: number;
followingCount: number;
coursesCompleted: number;
tradesWon: number;
tradesTotal: number;
};
preferences: {
theme: 'light' | 'dark' | 'auto';
language: string;
notifications: NotificationPreferences;
privacy: PrivacySettings;
};
createdAt: string;
updatedAt: string;
lastLogin: string;
}Error Responses
Invalid Password
{
"success": false,
"status": 400,
"message": "Password validation failed",
"error": "Password must be at least 8 characters with uppercase, lowercase, number, and special character"
}Username Taken
{
"success": false,
"status": 409,
"message": "Username already taken",
"error": "Please choose a different username"
}Insufficient Permissions
{
"success": false,
"status": 403,
"message": "Insufficient permissions",
"error": "Admin access required"
}Security Considerations
Profile Updates
- **Email changes require verification
- **Username changes limited to once per 30 days
- **Sensitive fields require password confirmation
- **Rate limited to prevent abuse
Data Privacy
- **Users control what information is public
- **GDPR compliant
- **Right to be forgotten
- **Data export available
- **Activity logs maintained
Admin Actions
- **All admin actions logged
- **Audit trail maintained
- **Reversible actions when possible
- **User notified of account changes
Best Practices
1. Profile Completion
Encourage users to complete their profile:
const completion = await fetch('/v1/user/profile/completion');
const { data } = await completion.json();
if (data.percentage < 100) {
showCompletionPrompt(data.suggestions);
}2. Avatar Guidelines
- Use square images (1:1 ratio)
- Minimum 200x200px
- Maximum 5MB file size
- Supported formats: JPG, PNG, GIF
3. Settings Organization
Group related settings:
const sections = [
{ name: 'General', settings: ['theme', 'language'] },
{ name: 'Notifications', settings: ['email', 'push', 'sms'] },
{ name: 'Privacy', settings: ['profileVisible', 'allowMessages'] },
{ name: 'Trading', settings: ['defaultRisk', 'confirmOrders'] }
];4. Real-time Updates
Update UI immediately after changes:
const updated = await updateProfile(changes);
setProfile(updated); // Update local state
showSuccessMessage('Profile updated!');Related Documentation
- Authentication - Login and token management
- Notifications - Notification system
- Privacy - Privacy policy and GDPR
- Security - Security best practices