Skip to content

Instantly share code, notes, and snippets.

@jerrywonderr
Last active February 3, 2026 12:48
Show Gist options
  • Select an option

  • Save jerrywonderr/0dfabc992f37d38f51557a7156e6c2ca to your computer and use it in GitHub Desktop.

Select an option

Save jerrywonderr/0dfabc992f37d38f51557a7156e6c2ca to your computer and use it in GitHub Desktop.
Sync for GoCreators

Analytics Endpoints – Backend data spec

Frontend expects these endpoints to return JSON matching the TypeScript interfaces in lib/api/creator.ts. Dummy data is currently returned; uncomment real API calls when backend is ready.

Endpoints

1. GET /api/creators/analytics/insights

Returns AnalyticsInsights:

{
  content_performance_trends: {
    trend: 'up' | 'down' | 'stable',
    change_percentage: number,  // e.g. 12.5 (percentage)
    period: string  // e.g. "last month", "last week"
  },
  audience_growth_prediction: {
    predicted_followers: number,  // e.g. 125000
    growth_rate: number,  // e.g. 8.3 (percentage)
    timeframe: string  // e.g. "next 30 days"
  },
  best_posting_times: Array<{
    platform: string,  // 'instagram', 'tiktok', 'youtube'
    day: string,  // day name, e.g. 'Tuesday'
    hour: number,  // 0-23
    engagement_score: number  // 0-10 scale
  }>,
  engagement_patterns: Array<{
    platform: string,
    pattern: string,  // short title, e.g. "Peak engagement on weekends"
    description: string  // explanation, e.g. "Your audience is most active..."
  }>
}

Usage: Shows content performance trends, growth predictions, best posting times, and engagement patterns.


2. GET /api/creators/analytics/platforms/{platform}

Returns PlatformAnalytics. Platform param: ig | ttk | yt (or instagram | tiktok | youtube).

{
  platform: string,  // 'instagram', 'tiktok', or 'youtube'
  followers: number,  // For IG/TikTok (0 for YouTube)
  subscribers: number,  // For YouTube (0 for IG/TikTok)
  average_engagement: number,  // Average likes/comments/etc
  average_views: number,  // Average views per post/video
  engagement_rate: number,  // Percentage (e.g. 7.6)
  growth_rate: number,  // Percentage growth (e.g. 5.2)
  snapshot_date: string  // ISO date string
}

Usage: Platform-specific stats cards showing followers/subscribers, engagement rate, average views, and growth rate.

Note: Frontend conditionally calls this based on user's linked platforms (hasInstagram, hasTiktok, hasYoutube).


3. GET /api/creators/analytics/follower-growth

Returns FollowerGrowthData:

{
  data_points: Array<{
    month: string,  // e.g. "Jan", "Feb", "Mar"
    instagram: number,  // Follower count for Instagram
    tiktok: number,  // Follower count for TikTok
    youtube: number  // Subscriber count for YouTube
  }>
}

Usage: Line chart showing follower/subscriber growth over time (typically last 6 months). Each data point represents one month with counts for all three platforms.

export interface AnalyticsInsights {
best_posting_times: Array<{
platform: string
day: string
hour: number
engagement_score: number
}>
content_performance_trends: {
trend: 'up' | 'down' | 'stable'
change_percentage: number
period: string
}
audience_growth_prediction: {
predicted_followers: number
growth_rate: number
timeframe: string
}
engagement_patterns: Array<{
platform: string
pattern: string
description: string
}>
}
export interface PlatformAnalytics {
platform: string
followers: number
subscribers: number
average_engagement: number
average_views: number
engagement_rate: number
growth_rate: number
snapshot_date: string
}
export interface FollowerGrowthData {
data_points: Array<{
month: string
instagram: number
tiktok: number
youtube: number
}>
}
function getAnalyticsInsightsDummy(): AnalyticsInsights {
return {
content_performance_trends: {
trend: 'up',
change_percentage: 12.5,
period: 'last month',
},
audience_growth_prediction: {
predicted_followers: 125000,
growth_rate: 8.3,
timeframe: 'next 30 days',
},
best_posting_times: [
{ platform: 'instagram', day: 'Tuesday', hour: 14, engagement_score: 8.5 },
{ platform: 'instagram', day: 'Thursday', hour: 18, engagement_score: 8.2 },
{ platform: 'tiktok', day: 'Friday', hour: 20, engagement_score: 9.1 },
{ platform: 'tiktok', day: 'Saturday', hour: 19, engagement_score: 8.8 },
{ platform: 'youtube', day: 'Wednesday', hour: 16, engagement_score: 7.9 },
],
engagement_patterns: [
{
platform: 'instagram',
pattern: 'Peak engagement on weekends',
description: 'Your audience is most active Saturday-Sunday between 2-4 PM',
},
{
platform: 'tiktok',
pattern: 'Evening surge',
description: 'Highest engagement occurs weekday evenings 7-9 PM',
},
{
platform: 'youtube',
pattern: 'Mid-week momentum',
description: 'Best performance on Tuesday-Thursday with longer-form content',
},
],
};
}
function getPlatformAnalyticsDummy(platform: string): PlatformAnalytics {
const base = {
platform,
snapshot_date: new Date().toISOString(),
};
switch (platform.toLowerCase()) {
case 'ig':
case 'instagram':
return {
...base,
platform: 'instagram',
followers: 42000,
subscribers: 0,
average_engagement: 3200,
average_views: 8500,
engagement_rate: 7.6,
growth_rate: 5.2,
};
case 'ttk':
case 'tiktok':
return {
...base,
platform: 'tiktok',
followers: 68000,
subscribers: 0,
average_engagement: 8500,
average_views: 125000,
engagement_rate: 12.5,
growth_rate: 8.7,
};
case 'yt':
case 'youtube':
return {
...base,
platform: 'youtube',
followers: 0,
subscribers: 15000,
average_engagement: 1200,
average_views: 8500,
engagement_rate: 8.0,
growth_rate: 6.1,
};
default:
return {
...base,
platform,
followers: 0,
subscribers: 0,
average_engagement: 0,
average_views: 0,
engagement_rate: 0,
growth_rate: 0,
};
}
}
function getFollowerGrowthDummy(): FollowerGrowthData {
return {
data_points: [
{ month: "Jan", instagram: 8000, tiktok: 15000, youtube: 5000 },
{ month: "Feb", instagram: 8500, tiktok: 18000, youtube: 6000 },
{ month: "Mar", instagram: 9200, tiktok: 22000, youtube: 7500 },
{ month: "Apr", instagram: 9800, tiktok: 28000, youtube: 8500 },
{ month: "May", instagram: 10000, tiktok: 35000, youtube: 9200 },
{ month: "Jun", instagram: 10000, tiktok: 40000, youtube: 10000 },
],
};
}
/** Pillars of celebration. Backend computes achieved from current data. */
export interface CreatorCelebratoryStats {
/** Total lifetime earnings (currency). Thresholds: 1k, 5k, 10k, 25k, 50k, 100k, 500k, 1m */
total_earnings: {
current_value: number;
milestones: CelebratoryMilestone[];
};
/** Unique brand partners. Thresholds: First (1), 10, 50, 100, 500, 1000 */
brand_partners: {
current_value: number;
milestones: CelebratoryMilestone[];
};
/** Paid brand collaborations count. Thresholds: First (1), 10, 50, 100, 500, 1000 */
paid_collabs: {
current_value: number;
milestones: CelebratoryMilestone[];
};
/** Checklist; when all true, show "Ready for brand discovery" */
profile_completion: CelebratoryProfileCompletion;
/** Monthly engagement (views). Only present if social dashboards are linked. Thresholds: 100k–1b */
monthly_engagement?: {
current_value: number;
milestones: CelebratoryMilestone[];
};
/** Total followers/subscribers. Only present if social accounts are linked. Thresholds: 10k–10m */
total_followers?: {
current_value: number;
milestones: CelebratoryMilestone[];
};
}
function getCelebratoryStatsDummy(): CreatorCelebratoryStats {
const earningsThresholds = [1000, 5000, 10000, 25000, 50000, 100000, 500000, 1000000];
const earningsLabels = ["1k", "5k", "10k", "25k", "50k", "100k", "500k", "1m"];
const currentEarnings = 8500;
const partnerThresholds = [1, 10, 50, 100, 500, 1000];
const partnerLabels = ["First Recurring Brand Partner", "10 brand partners", "50 brand partners", "100 brand partners", "500 brand partners", "1000 brand partners"];
const currentPartners = 3;
const collabLabels = ["First Paid Brand Collaboration", "10 paid brand collabs", "50 paid brand collabs", "100 paid brand collabs", "500 paid brand collabs", "1000 paid brand collabs"];
const currentCollabs = 5;
const engagementThresholds = [100000, 500000, 1e6, 5e6, 10e6, 50e6, 100e6, 500e6, 1e9];
const engagementLabels = ["100k views", "500k views", "1m views", "5m views", "10m views", "50m views", "100m views", "500m views", "1b views"];
const currentEngagement = 320000;
const followerThresholds = [10000, 50000, 100000, 250000, 500000, 1e6, 5e6, 10e6];
const followerLabels = ["10k", "50k", "100k", "250k", "500k", "1m", "5m", "10m"];
const currentFollowers = 42000;
const mk = (threshold: number, label: string, current: number): CelebratoryMilestone => ({
threshold,
label,
achieved: current >= threshold,
current_value: current,
});
return {
total_earnings: {
current_value: currentEarnings,
milestones: earningsThresholds.map((t, i) => mk(t, earningsLabels[i], currentEarnings)),
},
brand_partners: {
current_value: currentPartners,
milestones: partnerThresholds.map((t, i) => mk(t, partnerLabels[i], currentPartners)),
},
paid_collabs: {
current_value: currentCollabs,
milestones: partnerThresholds.map((t, i) => mk(t, collabLabels[i], currentCollabs)),
},
profile_completion: {
bio: true,
niche_tags: true,
verified: false,
social_platforms_linked: true,
portfolio_links_filled: false,
ready_for_brand_discovery: false,
},
monthly_engagement: {
current_value: currentEngagement,
milestones: engagementThresholds.map((t, i) => mk(t, engagementLabels[i], currentEngagement)),
},
total_followers: {
current_value: currentFollowers,
milestones: followerThresholds.map((t, i) => mk(t, followerLabels[i], currentFollowers)),
},
};
}

Dashboard Stats Endpoint – Backend data spec

Frontend expects this endpoint to return JSON matching the TypeScript interface in lib/api/creator.ts. Dummy data is currently returned; uncomment real API call when backend is ready.

Endpoint

GET /api/creators/dashboard/stats

Returns CreatorDashboardStats:

{
  active_projects: number,  // Currently active projects count
  avg_project_rating: number | null,  // Average rating across all projects (e.g. 4.8)
  follower_count: number | null,  // Total followers across all platforms
  engagement_rate: number | null  // Average engagement rate as decimal (e.g. 0.076 for 7.6%)
}

Usage: Combined stats for the top dashboard stat cards:

  • Active Projects card
  • Avg Rating card
  • Followers card
  • Engagement Rate card
export interface CreatorSpotlight {
featured_creators: Array<{
id: string;
name: string | null;
bio: string | null;
profile_picture: string | null;
follower_count: number | null;
specialties: string[] | null;
recent_work: Array<{
title: string | null;
thumbnail: string | null;
platform: string | null;
}>;
}>;
trending_hashtags: string[];
platform_insights: Record<
string,
{
trending_content_types: string[];
optimal_posting_times: string[];
}
>;
}

Earnings Endpoints – Backend data spec

Frontend expects these endpoints to return JSON matching the TypeScript interfaces in lib/api/creator.ts. Dummy data is currently returned; uncomment real API calls when backend is ready.

Endpoints

1. GET /api/creators/earnings/info

Returns CreatorEarningsInfo:

{
  total_earnings: number,  // Lifetime total
  pending_earnings: number,  // Awaiting payment
  this_month_earnings: number,  // Current month total
  last_payout: number | null,  // Last payout amount
  next_payout_date: string | null,  // ISO date string
  earnings_by_platform: Array<{
    platform: string,  // 'instagram', 'tiktok', 'youtube'
    earnings: number
  }>
}

Usage: Summary cards showing total earnings, pending earnings, this month's earnings, and last payout. Used in both dashboard and earnings pages.


2. GET /api/creators/earnings/log?page={page}&per_page={perPage}

Returns CreatorEarningsLog:

{
  earnings: Array<{
    id: string,
    project_id: string | null,
    project_name: string | null,
    amount: number,
    date: string | null,  // ISO date string
    type: string | null,  // e.g. 'campaign_payment'
    status: string | null  // 'paid', 'pending', etc.
  }>,
  total_records: number,
  page: number,
  per_page: number
}

Usage: Paginated earnings history list. Used in earnings page.


3. GET /api/creators/earnings/payouts

Returns { payouts: CreatorPayoutRequest[] }:

{
  payouts: Array<{
    id: string,
    amount: number,
    status: string | null,  // 'processed', 'pending', etc.
    requested_at: string | null,  // ISO date string
    processed_at: string | null,  // ISO date string
    payment_method: string | null  // e.g. 'bank_transfer'
  }>
}

Usage: List of payout requests. Used in earnings page.


4. GET /api/creators/earnings/widget

Returns EarningsData:

{
  currentMonth: {
    total: number,
    trend: number,  // Percentage change (e.g. 12.5)
    breakdown: {
      completed: number,
      pending: number,
      inProgress: number
    }
  },
  pendingPayments: {
    total: number,
    count: number,
    nextPaymentDate?: string,  // ISO date string
    items: Array<{
      id: string,
      campaignName: string,
      brandName: string,
      amount: number,
      dueDate: string,  // ISO date string
      status: 'pending' | 'processing' | 'scheduled'
    }>
  },
  paymentHistory: Array<{
    id: string,
    date: string,  // ISO date string
    campaignName: string,
    brandName: string,
    amount: number,
    status: 'paid' | 'refunded',
    invoiceUrl?: string
  }>,
  lifetimeStats: {
    totalEarned: number,
    totalCampaigns: number,
    averagePerCampaign: number,
    topEarningMonth: {
      month: string,  // e.g. 'September 2025'
      amount: number
    }
  }
}

Usage: Detailed earnings widget data for dashboard. Includes current month overview, pending payments list, payment history, and lifetime statistics.

function getEarningsInfoDummy(): CreatorEarningsInfo {
return {
total_earnings: 15420,
pending_earnings: 1250,
this_month_earnings: 2450,
last_payout: 3200,
next_payout_date: new Date(Date.now() + 5 * 86400000).toISOString(),
earnings_by_platform: [
{ platform: 'instagram', earnings: 8500 },
{ platform: 'tiktok', earnings: 4200 },
{ platform: 'youtube', earnings: 2720 },
],
};
}
function getEarningsLogDummy(): CreatorEarningsLog {
return {
earnings: [
{
id: '1',
project_id: 'proj-1',
project_name: 'Summer Collection Launch',
amount: 1500,
date: new Date(Date.now() - 10 * 86400000).toISOString(),
type: 'campaign_payment',
status: 'paid',
},
{
id: '2',
project_id: 'proj-2',
project_name: 'Spring Collection',
amount: 1200,
date: new Date(Date.now() - 25 * 86400000).toISOString(),
type: 'campaign_payment',
status: 'paid',
},
{
id: '3',
project_id: 'proj-3',
project_name: 'Brand Collaboration',
amount: 900,
date: new Date(Date.now() - 40 * 86400000).toISOString(),
type: 'campaign_payment',
status: 'paid',
},
{
id: '4',
project_id: 'proj-4',
project_name: 'Tech Product Review',
amount: 750,
date: new Date(Date.now() + 5 * 86400000).toISOString(),
type: 'campaign_payment',
status: 'pending',
},
],
total_records: 4,
page: 1,
per_page: 10,
};
}
function getPayoutRequestsDummy(): { payouts: CreatorPayoutRequest[] } {
return {
payouts: [
{
id: 'payout-1',
amount: 3200,
status: 'processed',
requested_at: new Date(Date.now() - 15 * 86400000).toISOString(),
processed_at: new Date(Date.now() - 10 * 86400000).toISOString(),
payment_method: 'bank_transfer',
},
{
id: 'payout-2',
amount: 1800,
status: 'pending',
requested_at: new Date(Date.now() - 3 * 86400000).toISOString(),
processed_at: null,
payment_method: 'bank_transfer',
},
],
};
}
function getEarningsWidgetDataDummy(): EarningsData {
return {
currentMonth: {
total: 2450,
trend: 12.5,
breakdown: {
completed: 1800,
pending: 450,
inProgress: 200,
},
},
pendingPayments: {
total: 1250,
count: 3,
nextPaymentDate: new Date(Date.now() + 5 * 86400000).toISOString(),
items: [
{
id: '1',
campaignName: 'Summer Collection Launch',
brandName: 'Fashion Brand Co',
amount: 750,
dueDate: new Date(Date.now() + 5 * 86400000).toISOString(),
status: 'pending',
},
{
id: '2',
campaignName: 'Tech Product Review',
brandName: 'Tech Innovations',
amount: 300,
dueDate: new Date(Date.now() + 10 * 86400000).toISOString(),
status: 'scheduled',
},
{
id: '3',
campaignName: 'Holiday Special',
brandName: 'Retail Giant',
amount: 200,
dueDate: new Date(Date.now() + 15 * 86400000).toISOString(),
status: 'processing',
},
],
},
paymentHistory: [
{
id: '1',
date: new Date(Date.now() - 10 * 86400000).toISOString(),
campaignName: 'Product Launch Campaign',
brandName: 'Beauty Brand',
amount: 1500,
status: 'paid',
invoiceUrl: '/invoices/1',
},
{
id: '2',
date: new Date(Date.now() - 25 * 86400000).toISOString(),
campaignName: 'Spring Collection',
brandName: 'Fashion Co',
amount: 1200,
status: 'paid',
invoiceUrl: '/invoices/2',
},
{
id: '3',
date: new Date(Date.now() - 40 * 86400000).toISOString(),
campaignName: 'Brand Collaboration',
brandName: 'Lifestyle Brand',
amount: 900,
status: 'paid',
},
],
lifetimeStats: {
totalEarned: 15420,
totalCampaigns: 15,
averagePerCampaign: 1028,
topEarningMonth: {
month: 'September 2025',
amount: 3200,
},
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment