Skip to main content

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

email
string
User’s email address
preferences
object
User’s scheduling preferences (see User Preferences)
stats
object
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
onboarding_completed
boolean
Whether user has completed initial preference setup
created_at
string
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();
}