Skip to content

Analytics API

API endpoints for querying and managing analytics data.

Overview

Endpoints

Get Social Metrics

Retrieve aggregated social metrics by date range and platform.

http
GET /analytics/social-metrics

Query Parameters:

ParameterTypeRequiredDescription
startDatestringNoStart date (YYYY-MM-DD)
endDatestringNoEnd date (YYYY-MM-DD)
platformstringNoFilter by platform

Example Request:

bash
curl "http://localhost:3100/analytics/social-metrics?startDate=2026-01-01&platform=twitter"

Response:

json
{
  "success": true,
  "data": [
    {
      "metric_date": "2026-02-05",
      "platform": "twitter",
      "impressions": 15420,
      "engagement": 892,
      "reach": 12350,
      "followers": 45230
    },
    {
      "metric_date": "2026-02-04",
      "platform": "twitter",
      "impressions": 14100,
      "engagement": 756,
      "reach": 11800,
      "followers": 45150
    }
  ]
}

Get historical follower counts for trend analysis.

http
GET /analytics/followers

Query Parameters:

ParameterTypeRequiredDescription
daysnumberNoNumber of days back (default: 30)
platformstringNoFilter by platform

Example Request:

bash
curl "http://localhost:3100/analytics/followers?days=7&platform=instagram"

Response:

json
{
  "success": true,
  "data": [
    {
      "date": "2026-02-05",
      "platform": "instagram",
      "count": 28450
    },
    {
      "date": "2026-02-04",
      "platform": "instagram",
      "count": 28320
    }
  ]
}

Get Top Posts

Get best performing posts by engagement.

http
GET /analytics/top-posts

Query Parameters:

ParameterTypeRequiredDescription
limitnumberNoNumber of posts (default: 10)
platformstringNoFilter by platform
metricstringNoSort by: engagement, likes, shares

Example Request:

bash
curl "http://localhost:3100/analytics/top-posts?limit=5&metric=engagement"

Response:

json
{
  "success": true,
  "data": [
    {
      "post_id": "post-123",
      "platform": "twitter",
      "content": "Check out our latest episode...",
      "likes": 245,
      "comments": 34,
      "shares": 89,
      "total_engagement": 368,
      "engagement_rate": 2.45
    }
  ]
}

Trigger Analytics Collection

Manually trigger the analytics collection process.

http
POST /analytics/collect

Example Request:

bash
curl -X POST http://localhost:3100/analytics/collect

Response:

json
{
  "success": true,
  "message": "Analytics collection started",
  "platforms": ["twitter", "facebook", "instagram", "linkedin"]
}

Ingest Content Metrics

Receive content metrics from external sources (like X Server).

http
POST /analytics/content-ingest

Request Body:

json
{
  "contentId": "content-123",
  "platform": "rumble",
  "platformContentId": "v12345",
  "views": 5420,
  "watchHours": 145.5,
  "likes": 234,
  "comments": 45,
  "shares": 12
}

Response:

json
{
  "success": true,
  "message": "Content metrics ingested",
  "id": 456
}

Get Content Metrics

Query content performance data.

http
GET /analytics/content-metrics

Query Parameters:

ParameterTypeRequiredDescription
contentIdstringNoFilter by content ID
platformstringNoFilter by platform
startDatestringNoStart date
endDatestringNoEnd date

Example Request:

bash
curl "http://localhost:3100/analytics/content-metrics?contentId=content-123"

Response:

json
{
  "success": true,
  "data": [
    {
      "content_id": "content-123",
      "platform": "rumble",
      "views": 5420,
      "watch_hours": 145.5,
      "likes": 234,
      "comments": 45,
      "collected_at": "2026-02-05T18:00:00.000Z"
    },
    {
      "content_id": "content-123",
      "platform": "youtube",
      "views": 12350,
      "watch_hours": 312.8,
      "likes": 567,
      "comments": 89,
      "collected_at": "2026-02-05T18:00:00.000Z"
    }
  ]
}

Data Collection Flow

Collection Implementation

javascript
// helpers/cron/collectAnalytics.js
export async function collectAnalytics() {
  const platforms = ['twitter', 'facebook', 'instagram', 'linkedin'];
  
  for (const platform of platforms) {
    // Get platform analytics
    const analytics = await getAyrshareAnalytics(platform);
    
    // Store in PostgreSQL
    await query(
      `INSERT INTO social_metrics 
       (metric_date, platform, impressions, engagement, reach, followers)
       VALUES ($1, $2, $3, $4, $5, $6)
       ON CONFLICT (metric_date, platform) 
       DO UPDATE SET impressions = $3, engagement = $4`,
      [new Date(), platform, analytics.impressions, analytics.engagement, 
       analytics.reach, analytics.followers]
    );
    
    // Store follower count
    await query(
      `INSERT INTO platform_followers (date, platform, count)
       VALUES ($1, $2, $3)
       ON CONFLICT (date, platform) DO UPDATE SET count = $3`,
      [new Date(), platform, analytics.followers]
    );
  }
  
  // Collect post performance
  const posts = await getAyrshareHistory();
  for (const post of posts) {
    await query(
      `INSERT INTO post_performance 
       (post_id, platform, ayrshare_id, content, likes, comments, shares, impressions)
       VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
      [post.id, post.platform, post.ayrshareId, post.content,
       post.likes, post.comments, post.shares, post.impressions]
    );
  }
}

Query Helpers

javascript
// helpers/postgres/queries.js

export async function getSocialMetrics(startDate, endDate, platform) {
  let sql = `SELECT * FROM social_metrics WHERE 1=1`;
  const params = [];
  
  if (startDate) {
    params.push(startDate);
    sql += ` AND metric_date >= $${params.length}`;
  }
  
  if (endDate) {
    params.push(endDate);
    sql += ` AND metric_date <= $${params.length}`;
  }
  
  if (platform) {
    params.push(platform);
    sql += ` AND platform = $${params.length}`;
  }
  
  sql += ` ORDER BY metric_date DESC`;
  
  return query(sql, params);
}

export async function getTopPosts(limit = 10, platform, metric = 'engagement') {
  const orderBy = {
    engagement: 'likes + comments + shares',
    likes: 'likes',
    shares: 'shares',
  }[metric];
  
  let sql = `
    SELECT *, 
           likes + comments + shares as total_engagement
    FROM post_performance
    WHERE 1=1
  `;
  const params = [];
  
  if (platform) {
    params.push(platform);
    sql += ` AND platform = $${params.length}`;
  }
  
  sql += ` ORDER BY ${orderBy} DESC LIMIT $${params.length + 1}`;
  params.push(limit);
  
  return query(sql, params);
}

Error Handling

All endpoints return consistent error format:

json
{
  "success": false,
  "error": "Error message",
  "code": "ERROR_CODE"
}

Common Errors:

CodeDescription
INVALID_DATEInvalid date format
DB_ERRORDatabase query failed
COLLECTION_FAILEDAnalytics collection failed

MediaMagic CRM Documentation