Profile stats: follower and engagement timeseries via API

Postproxy now records follower counts and engagement metrics for every connected profile across all ten networks, exposed as a unified timeseries endpoint.

Profile stats: follower and engagement timeseries via API
Quick answer

Postproxy now captures stats snapshots for every connected profile across all ten networks. GET /api/profiles/:id returns the latest snapshot, and GET /api/profiles/:id/stats returns the full timeseries. Facebook pages, LinkedIn organizations, and Telegram channels are scoped per placement, with a summary_stats rollup summed across them.

What changed

Two endpoints joined the Profiles API:

  • GET /api/profiles/:id now returns a latest_stats array (one entry per placement) and, for placement networks, a summary_stats rollup summed across every placement.
  • GET /api/profiles/:id/stats returns the full timeseries — every snapshot recorded for a profile, ordered by recorded_at, with from / to filters.

Which networks are covered?

All ten. Facebook, Instagram, LinkedIn, TikTok, YouTube, X (Twitter), Threads, Pinterest, Bluesky, Telegram — every platform Postproxy publishes to is also polled for profile-level stats.

Three of them — Facebook, LinkedIn, and Telegram — are placement-scoped. A Facebook profile may have many pages, a LinkedIn profile may have many organizations, a Telegram bot may have many channels. Each placement gets its own timeseries; the summary_stats block sums numeric fields across them so a single number is still available without iterating.

For context on the most recent network rollouts, see the announcements for Telegram and Bluesky support and Google Business Profile support.

What fields does each platform expose?

The stats object is a passthrough — keys come straight from each network’s API. They are not normalized into a shared schema, because the platforms do not agree on what “engagement” means and a forced common shape would either drop signal or invent fields that do not exist.

NetworkPlacement-scoped?Typical fields
facebookYes (per page)fan_count, followers_count, page_impressions, page_views_total, page_fan_adds, page_fan_removes
linkedinYes (per organization)followerCount, shareCount, likeCount, commentCount, clickCount, engagement, allPageViews, overviewPageViews, aboutPageViews, careersPageViews, peoplePageViews, insightsPageViews
telegramYes (per channel)followers_count, channel_title, channel_username
instagramNofollowers_count, follows_count, media_count, reach, profile_views, accounts_engaged, total_interactions, website_clicks
threadsNofollowers_count, views, likes, replies, reposts, quotes
youtubeNosubscriberCount, viewCount, videoCount
twitterNofollowers_count, following_count, tweet_count, listed_count, like_count
tiktokNofollower_count, following_count, likes_count, video_count
pinterestNofollower_count, following_count, pin_count, board_count, monthly_views, analytics_30d
blueskyNofollowersCount, followsCount, postsCount

Two filters Postproxy applies on top of the raw passthrough:

  • LinkedIn page-view metrics are collapsed to the rollups — redundant mobile/desktop splits and dead sections (productsPageViews, lifeAtPageViews) are dropped.
  • Non-numeric fields (e.g. Telegram’s channel_title) appear in latest_stats[].stats but are excluded from summary_stats.stats, which sums numeric values only.

A key only appears in a snapshot if the platform returned a value for it on that pull, so individual fields can come and go between records — code that reads stats should treat every key as optional.

How do you read the latest snapshot?

Already calling GET /api/profiles/:id? The new fields are additive — latest_stats and summary_stats show up alongside the existing profile attributes.

Terminal window
curl "https://api.postproxy.dev/api/profiles/prof_abc123" \
-H "Authorization: Bearer YOUR_API_KEY"

For a Facebook profile with two pages, the response shape is:

{
"id": "prof_abc123",
"platform": "facebook",
"name": "Acme Inc.",
"latest_stats": [
{
"placement_id": "111111111111",
"stats": { "fan_count": 12450, "page_impressions": 38210, "page_fan_adds": 42 },
"recorded_at": "2026-05-20T06:14:00Z"
},
{
"placement_id": "222222222222",
"stats": { "fan_count": 880, "page_impressions": 4120, "page_fan_adds": 6 },
"recorded_at": "2026-05-20T06:14:00Z"
}
],
"summary_stats": {
"stats": { "fan_count": 13330, "page_impressions": 42330, "page_fan_adds": 48 },
"recorded_at": "2026-05-20T06:14:00Z"
}
}

For non-placement networks (Bluesky, X, Threads, Instagram, TikTok, YouTube, Pinterest), latest_stats contains a single entry with placement_id: null and summary_stats is null.

If latest_stats is empty, the profile is connected but has not been polled yet.

How do you pull the full timeseries?

Terminal window
curl "https://api.postproxy.dev/api/profiles/prof_abc123/stats?placement_id=111111111111&from=2026-04-01T00:00:00Z" \
-H "Authorization: Bearer YOUR_API_KEY"

Response:

{
"data": {
"profile_id": "prof_abc123",
"platform": "facebook",
"placement_id": "111111111111",
"records": [
{ "stats": { "fan_count": 12380, "page_impressions": 35120 }, "recorded_at": "2026-04-01T06:12:00Z" },
{ "stats": { "fan_count": 12395, "page_impressions": 36040 }, "recorded_at": "2026-04-02T06:12:00Z" }
]
}
}

Records are ordered ascending by recorded_at. from and to accept ISO 8601 timestamps and apply inclusively.

placement_id is required for facebook, linkedin, and telegram — one timeseries per placement, so the endpoint must be scoped to one. Omit it (or pass it; it is ignored) for the other networks.

{ "error": "placement_id is required for linkedin profiles" }

The shape mirrors Post Statsrecords[].stats + recorded_at — so charting code written for post-level timeseries works for profile-level timeseries without modification.

Where this fits

For teams already wiring up Post Stats, Profile Stats slots into the same reporting pipeline:

  • Reporting dashboards. Two queries — profile-level for follower trends, post-level for per-piece performance — cover the whole picture.
  • Client portals. Agencies and white-label tools can surface follower growth charts for each connected account without standing up a separate analytics integration.
  • Internal benchmarking. Compare engagement rate (sum of likes/comments/shares ÷ followers) across networks in one query loop, since both numerator and denominator come from the same endpoint.
  • Multi-brand setups. One profile group per brand keeps each client’s stats isolated under the same API surface.

Getting started

If you already have a Postproxy account:

  1. Call GET /api/profiles to find the profile id.
  2. Call GET /api/profiles/:id for the latest snapshot.
  3. Call GET /api/profiles/:id/stats for the full timeseries. Pass placement_id for Facebook, LinkedIn, and Telegram profiles.

No new scopes, no separate billing, no opt-in. Profile stats are recorded on every connected profile starting today.

Ready to get started?

Start with our free plan and scale as your needs grow. No credit card required.