Analytics API
Access post performance metrics, follower growth, best posting times, and content analysis. Analytics data is cached and refreshed at most once per hour (follower counts refresh daily).
Included: Analytics endpoints are included on all paid plans (Build, Accelerate, and Unlimited). Your API key must have the analytics permission.
Supported platforms
Analytics are available for nine platforms:
Endpoints
/api/v1/analytics/postsPer-post performance metricsIncluded/api/v1/analytics/dailyDaily aggregated metricsIncluded/api/v1/analytics/best-timeBest times to postIncluded/api/v1/analytics/followersFollower count historyIncluded/api/v1/analytics/content-typesPerformance by content typeIncluded/api/v1/analytics/retentionYouTube audience retentionIncluded/api/v1/analytics/refreshManually refresh analyticsIncludedPer-post performance metrics
/api/v1/analytics/postsPer-post performance metricsIncludedRetrieve engagement metrics for individual posts. Sort by engagement, likes, or impressions to find your best-performing content.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
accountId | string | Required | The account ID to fetch analytics for. The platform is resolved automatically from the account. |
limit | integer | Optional | Number of posts to return (1-100)Default: 20 |
cursor | string | Optional | Pagination cursor from a previous response |
sort | string | Optional | Sort posts by metricDefault: datedatelikesimpressionsengagement |
order | string | Optional | Sort directionDefault: descascdesc |
accountIdstringRequiredThe account ID to fetch analytics for. The platform is resolved automatically from the account.
limitintegerOptionalNumber of posts to return (1-100)
Default: 20
cursorstringOptionalPagination cursor from a previous response
sortstringOptionalSort posts by metric
Default: date
datelikesimpressionsengagementorderstringOptionalSort direction
Default: desc
ascdesccurl "https://schedulala.com/api/v1/analytics/posts?accountId=acc_123abc&sort=engagement&order=desc&limit=5" \-H "Authorization: Bearer sk_live_abc123xyz789..."
{"success": true,"data": [{"id": "665f1c2ab8d9e4f5a6b7c8d9","platform": "instagram","platformPostId": "17895695668004550","postUrl": "https://www.instagram.com/p/ABC123/","content": "Excited to share our latest feature launch...","contentType": "CAROUSEL_ALBUM","postedAt": "2026-05-25T14:00:00.000Z","metrics": {"likes": 342,"comments": 28,"replies": null,"shares": 15,"saves": 89,"impressions": null,"reach": 8200,"views": 12400,"quotes": null,"reposts": null,"bookmarks": null},"engagementRate": 3.1048,"lastFetchedAt": "2026-06-11T06:00:00.000Z"}],"pagination": {"cursor": "NjY1ZjFjMmFiOGQ5ZTRmNWE2YjdjOGQ5","hasMore": true,"limit": 20}}
engagementRate is computed as (likes + comments + replies + shares + reposts + quotes) divided by impressions, views, or reach (the first one the platform reports), as a percentage. When the platform reports none of those denominators, for example Bluesky, it is null. For YouTube it is always null: the YouTube API Services policies do not allow derived metrics, so we only return the raw counts YouTube provides.
Metrics availability by platform
Not every platform exposes every metric. The table below shows which metrics are available on each platform. Unavailable metrics return null.
| Metric | Twitter/X | Bluesky | Threads | TikTok | YouTube | ||||
|---|---|---|---|---|---|---|---|---|---|
likes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
comments | Yes | -- | -- | -- | Yes | Yes | Yes | Yes | Yes |
replies | -- | Yes | Yes | Yes | -- | -- | -- | -- | -- |
shares | Yes | -- | -- | -- | Yes | Yes | -- | Yes | -- |
saves | Yes | -- | -- | -- | -- | -- | Yes | -- | -- |
impressions | -- | Yes | -- | -- | -- | Yes | Yes | -- | -- |
reach | Yes | -- | -- | -- | -- | Yes | -- | -- | -- |
views | Yes | -- | -- | Yes | Yes | -- | -- | Yes | Yes |
quotes | -- | Yes | Yes | Yes | -- | -- | -- | -- | -- |
reposts | -- | Yes | Yes | Yes | -- | -- | -- | -- | -- |
bookmarks | -- | Yes | -- | -- | -- | -- | -- | -- | Yes |
Platforms report comment-style activity under different names: Twitter/X, Bluesky, and Threads use replies; the rest use comments. A few mappings to know: Facebook likes is the total of all reaction types, Pinterest likes is pin reactions, YouTube bookmarks is favorites, and Facebook views is populated for videos and reels only.
Daily aggregated metrics
/api/v1/analytics/dailyDaily aggregated metricsIncludedGet aggregated engagement metrics broken down by day. Useful for charting performance trends over time.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
accountId | string | Optional | Filter to a specific account. Omit for all accounts. |
platform | string | Optional | Filter by platforminstagramtwitterblueskythreadsfacebooklinkedinpinteresttiktokyoutube |
days | integer | Optional | Number of days to look backDefault: 30 |
startDate | string | Optional | Start date (ISO 8601). Overrides days parameter if provided. |
endDate | string | Optional | End date (ISO 8601). Defaults to today. |
accountIdstringOptionalFilter to a specific account. Omit for all accounts.
platformstringOptionalFilter by platform
instagramtwitterblueskythreadsfacebooklinkedinpinteresttiktokyoutubedaysintegerOptionalNumber of days to look back
Default: 30
startDatestringOptionalStart date (ISO 8601). Overrides days parameter if provided.
endDatestringOptionalEnd date (ISO 8601). Defaults to today.
curl "https://schedulala.com/api/v1/analytics/daily?accountId=acc_123abc&days=30" \-H "Authorization: Bearer sk_live_abc123xyz789..."
{"success": true,"daily": [{"date": "2026-02-28","postsPublished": 3,"totalLikes": 215,"totalComments": 18,"totalShares": 7,"totalImpressions": 8400,"avgEngagementRate": 2.85,"platforms": {"instagram": {"posts": 2,"likes": 180,"impressions": 6200},"twitter": {"posts": 1,"likes": 35,"impressions": 2200}}},{"date": "2026-02-27","postsPublished": 1,"totalLikes": 89,"totalComments": 5,"totalShares": 3,"totalImpressions": 3100,"avgEngagementRate": 3.12,"platforms": {"instagram": {"posts": 1,"likes": 89,"impressions": 3100}}}],"summary": {"totalPosts": 45,"totalLikes": 4230,"totalImpressions": 142000,"avgDailyEngagement": 2.98,"trend": 12.5}}
Tip: The trend value in the summary is a percentage comparing the current period to the previous period of the same length. A value of 12.5 means engagement is up 12.5% compared to the prior 30 days.
Best times to post
/api/v1/analytics/best-timeBest times to postIncludedAnalyze your posting history to find the days and hours that drive the most engagement. Results include a heatmap for visualization and platform-specific breakdowns.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
accountId | string | Optional | Filter to a specific account. Omit for aggregate across all accounts. |
platform | string | Optional | Filter by platforminstagramtwitterblueskythreadsfacebooklinkedinpinteresttiktokyoutube |
days | integer | Optional | Number of days of history to analyzeDefault: 90 |
accountIdstringOptionalFilter to a specific account. Omit for aggregate across all accounts.
platformstringOptionalFilter by platform
instagramtwitterblueskythreadsfacebooklinkedinpinteresttiktokyoutubedaysintegerOptionalNumber of days of history to analyze
Default: 90
curl "https://schedulala.com/api/v1/analytics/best-time?accountId=acc_123abc&days=90" \-H "Authorization: Bearer sk_live_abc123xyz789..."
{"success": true,"bestTimes": {"overall": [{"day": "Tuesday","hour": 14,"avgEngagement": 4.2,"postsAnalyzed": 12},{"day": "Thursday","hour": 10,"avgEngagement": 3.8,"postsAnalyzed": 9},{"day": "Saturday","hour": 11,"avgEngagement": 3.5,"postsAnalyzed": 7}],"byPlatform": {"instagram": [{"day": "Tuesday","hour": 14,"avgEngagement": 5.1,"postsAnalyzed": 6}],"twitter": [{"day": "Thursday","hour": 10,"avgEngagement": 3.2,"postsAnalyzed": 5}]},"heatmap": {"Monday": [0.1,0.1,0,0,0,0.2,0.5,1.2,2.1,2.8,3,2.5,2,1.8,2.2,1.5,1,0.8,0.6,0.4,0.3,0.2,0.1,0.1],"Tuesday": [0.1,0.1,0,0,0,0.3,0.6,1.5,2.5,3.2,3.5,3,2.4,2,4.2,2.8,1.2,0.9,0.7,0.5,0.3,0.2,0.1,0.1]},"timezone": "America/New_York","dataPoints": 84}}
Tip: Each heatmap array contains 24 values (one per hour, 0–23) representing the average engagement rate for that day/hour combination. Use these values to build a visual heatmap in your UI.
YouTube accounts are excluded from best-time results: the YouTube API Services policies do not allow derived metrics, so connected YouTube channels never contribute to overall, byPlatform, or the heatmap.
Follower count history
/api/v1/analytics/followersFollower count historyIncludedTrack follower growth over time for a specific account. Includes current count, growth over different time windows, and daily history.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
accountId | string | Required | The account ID to fetch follower data for |
days | integer | Optional | Number of days of history to returnDefault: 30 |
accountIdstringRequiredThe account ID to fetch follower data for
daysintegerOptionalNumber of days of history to return
Default: 30
curl "https://schedulala.com/api/v1/analytics/followers?accountId=acc_123abc&days=30" \-H "Authorization: Bearer sk_live_abc123xyz789..."
{"success": true,"followers": {"current": 15420,"growth": {"7d": {"count": 120,"percentage": 0.78},"30d": {"count": 580,"percentage": 3.91},"90d": {"count": 2100,"percentage": 15.77}},"history": [{"date": "2026-02-28","count": 15420,"change": 45},{"date": "2026-02-27","count": 15375,"change": 32},{"date": "2026-02-26","count": 15343,"change": -5}]}}
Performance by content type
/api/v1/analytics/content-typesPerformance by content typeIncludedCompare how different content types (photo, video, carousel, text) perform across your accounts. Includes a recommendation based on your data.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
accountId | string | Optional | Filter to a specific account. Omit for aggregate data. |
platform | string | Optional | Filter by platforminstagramtwitterblueskythreadsfacebooklinkedinpinteresttiktokyoutube |
days | integer | Optional | Number of days of history to analyzeDefault: 90 |
accountIdstringOptionalFilter to a specific account. Omit for aggregate data.
platformstringOptionalFilter by platform
instagramtwitterblueskythreadsfacebooklinkedinpinteresttiktokyoutubedaysintegerOptionalNumber of days of history to analyze
Default: 90
curl "https://schedulala.com/api/v1/analytics/content-types?accountId=acc_123abc&days=90" \-H "Authorization: Bearer sk_live_abc123xyz789..."
{"success": true,"contentTypes": {"overall": [{"type": "carousel","postCount": 15,"avgLikes": 245,"avgComments": 18,"avgEngagementRate": 4.2,"avgImpressions": 9800},{"type": "video","postCount": 22,"avgLikes": 180,"avgComments": 12,"avgEngagementRate": 3.5,"avgImpressions": 11200},{"type": "photo","postCount": 30,"avgLikes": 120,"avgComments": 8,"avgEngagementRate": 2.8,"avgImpressions": 5400},{"type": "text","postCount": 18,"avgLikes": 65,"avgComments": 15,"avgEngagementRate": 2.1,"avgImpressions": 3800}],"recommendation": "Carousel posts drive 50% higher engagement than your average. Consider posting more carousels, especially on Tuesdays and Thursdays."}}
Manually refresh analytics
/api/v1/analytics/refreshManually refresh analyticsIncludedTrigger a manual refresh of analytics data for a specific account. Analytics are automatically refreshed periodically, but you can use this endpoint to force an immediate update.
Refresh support: Manual refresh is available for Instagram, Twitter/X, Bluesky, Threads, Facebook, and YouTube. LinkedIn, TikTok, and Pinterest analytics are read-only through this API: the read endpoints above cover all nine platforms, but those three are updated only by Schedulala's automatic refresh cycle. Calling refresh for one of them returns a not_supported error.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
accountId | string | Required | The connected account's ID (SocialAccount _id) to refresh analytics for |
accountIdstringRequiredThe connected account's ID (SocialAccount _id) to refresh analytics for
Rate limited: This endpoint can only be called once per hour per account. Calling it more frequently will return a 429 error with a Retry-After header indicating when you can try again.
curl -X POST https://schedulala.com/api/v1/analytics/refresh \-H "Authorization: Bearer sk_live_abc123xyz789..." \-H "Content-Type: application/json" \-d '{ "accountId": "acc_123abc" }'
{"success": true,"data": {"accountId": "acc_123abc","platform": "instagram","status": "completed","postsUpdated": 27,"lastRefreshed": "2026-03-01T10:02:00.000Z"}}
YouTube audience retention
/api/v1/analytics/retentionYouTube audience retentionIncludedPer-video audience retention, available for YouTube only. Unlike the other analytics endpoints, this is a live YouTube Analytics API query with a 7-day cache that is shared with the Schedulala dashboard. The response maps each percentage point of the video to the fraction of viewers still watching at that point, alongside YouTube's relative performance comparison against similar videos.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
platform | string | Optional | The platform. Only youtube is supported.Default: youtubeyoutube |
videoId | string | Required | The YouTube video ID to fetch retention for |
accountId | string | Optional | Which connected channel to use. Defaults to the first connected YouTube channel. |
platformstringOptionalThe platform. Only youtube is supported.
Default: youtube
youtubevideoIdstringRequiredThe YouTube video ID to fetch retention for
accountIdstringOptionalWhich connected channel to use. Defaults to the first connected YouTube channel.
Requirements: The channel must be connected with the yt-analytics.readonly scope; older connections may need to be reconnected to grant it. YouTube's reporting also lags by about 48 hours and needs sufficient watch activity, so very new or low-traffic videos return no retention data.
curl "https://schedulala.com/api/v1/analytics/retention?videoId=dQw4w9WgXcQ" \-H "Authorization: Bearer sk_live_abc123xyz789..."
{"success": true,"platform": "youtube","account": {"id": "UCabc123def456","username": "Your Channel"},"videoId": "dQw4w9WgXcQ","retention": {"0": 1,"5": 0.82,"10": 0.74,"25": 0.61,"50": 0.47,"75": 0.38,"100": 0.29},"relativePerformance": {"0": 1.12,"5": 1.08,"10": 1.05,"25": 1.02,"50": 0.99,"75": 0.97,"100": 0.96}}
Keys in retention and relativePerformance are the percentage of the video elapsed (the full response has a point for each percent); values in retention are the fraction of viewers still watching, and values in relativePerformance are YouTube's own relative retention metric at that point (1.0 = on par with similar videos). Both come straight from the YouTube Analytics API without modification. When the response is served from the shared 7-day cache it also includes fromCache: true; the field is omitted on a live fetch.