Overview
Returns the user’s profile information, preferences, and usage statistics.
Authentication
Requires User API Key in the X-API-Key header.
Request
GET https://api.syncline.run/v1/user/info
Response
{
"email": "alice@example.com",
"preferences": {
"work_hours": {
"monday": { "enabled": true, "start": "09:00", "end": "17:00" },
"tuesday": { "enabled": true, "start": "09:00", "end": "17:00" },
"wednesday": { "enabled": true, "start": "09:00", "end": "17:00" },
"thursday": { "enabled": true, "start": "09:00", "end": "17:00" },
"friday": { "enabled": true, "start": "09:00", "end": "17:00" },
"saturday": { "enabled": false, "start": "09:00", "end": "17:00" },
"sunday": { "enabled": false, "start": "09:00", "end": "17:00" }
},
"timezone": "America/New_York",
"buffer_minutes": 15,
"availability_window_days": 14,
"max_meetings_per_day": 5,
"energy_pattern": "morning_person",
"scheduling_context": "Prefer mornings for strategic work",
"focus_blocks": [
{
"day": "tuesday",
"start": "09:00",
"end": "12:00",
"reason": "Deep work time"
}
]
},
"stats": {
"total_meetings_scheduled": 47,
"meetings_this_month": 12,
"average_acceptance_time_hours": 3.2,
"reschedule_rate": 0.06,
"fast_acceptance_rate": 0.82,
"preferred_times": {
"morning": 0.65,
"afternoon": 0.30,
"evening": 0.05
}
},
"onboarding_completed": true,
"created_at": "2025-01-15T10:30:00Z"
}
Response Fields
Usage statistics and behavioral insights:
total_meetings_scheduled: Lifetime meeting count
meetings_this_month: Current month’s meetings
average_acceptance_time_hours: How quickly user accepts meetings
reschedule_rate: Percentage of meetings rescheduled (0.0-1.0)
fast_acceptance_rate: Percentage accepted within 2 hours
preferred_times: Distribution of meeting times by period
Whether user has completed initial preference setup
ISO 8601 timestamp of account creation
Use Cases
User Profile Page
// Display user's profile
async function loadUserProfile() {
const info = await fetch('https://api.syncline.run/v1/user/info', {
headers: { 'X-API-Key': userApiKey }
}).then(r => r.json());
return {
email: info.email,
timezone: info.preferences.timezone,
workDays: Object.entries(info.preferences.work_hours)
.filter(([_, hours]) => hours.enabled)
.map(([day]) => day),
meetingCount: info.stats.total_meetings_scheduled,
quality: info.stats.fast_acceptance_rate > 0.8 ? 'Excellent' : 'Good'
};
}
Personalized Recommendations
// Show personalized scheduling tips
async function getSchedulingTips(userEmail) {
const { stats, preferences } = await getUserInfo();
const tips = [];
if (stats.reschedule_rate > 0.15) {
tips.push('You reschedule often. Consider updating your preferences to better match your schedule.');
}
if (stats.fast_acceptance_rate < 0.5) {
tips.push('Meetings are often scheduled at suboptimal times. Tell us more about your preferences!');
}
if (preferences.energy_pattern === 'morning_person' && stats.preferred_times.morning < 0.5) {
tips.push('You prefer mornings but get afternoon meetings. Update your scheduling context!');
}
return tips;
}
Onboarding Check
// Redirect new users to onboarding
async function checkOnboardingStatus() {
const { onboarding_completed } = await getUserInfo();
if (!onboarding_completed) {
window.location.href = '/onboarding';
return false;
}
return true;
}
Usage Dashboard
// Show user their scheduling insights
async function renderDashboard() {
const { stats, preferences } = await getUserInfo();
return {
thisMonth: stats.meetings_this_month,
lifetime: stats.total_meetings_scheduled,
qualityScore: (stats.fast_acceptance_rate * 100).toFixed(0) + '%',
rescheduleRate: (stats.reschedule_rate * 100).toFixed(1) + '%',
energyPattern: preferences.energy_pattern,
preferredTime: Object.entries(stats.preferred_times)
.reduce((a, b) => a[1] > b[1] ? a : b)[0]
};
}
Example: Settings Page
// Complete user settings component
async function UserSettings() {
const info = await getUserInfo();
return {
profile: {
email: info.email,
timezone: info.preferences.timezone,
memberSince: new Date(info.created_at).toLocaleDateString()
},
preferences: {
workHours: info.preferences.work_hours,
bufferTime: info.preferences.buffer_minutes,
maxMeetingsPerDay: info.preferences.max_meetings_per_day,
energyPattern: info.preferences.energy_pattern
},
insights: {
totalMeetings: info.stats.total_meetings_scheduled,
thisMonth: info.stats.meetings_this_month,
qualityScore: info.stats.fast_acceptance_rate,
rescheduleRate: info.stats.reschedule_rate
}
};
}
Best Practices
Cache User Info
// Cache for 10 minutes
let userInfoCache = null;
let cacheTime = 0;
async function getUserInfoCached() {
const now = Date.now();
if (userInfoCache && now - cacheTime < 10 * 60 * 1000) {
return userInfoCache;
}
userInfoCache = await getUserInfo();
cacheTime = now;
return userInfoCache;
}
Update After Changes
// Invalidate cache when preferences change
async function updatePreferences(newPrefs) {
await fetch('https://api.syncline.run/v1/user/preferences', {
method: 'PUT',
headers: {
'X-API-Key': userApiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(newPrefs)
});
// Invalidate cache
userInfoCache = null;
// Fetch fresh data
return await getUserInfo();
}