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.
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/:idnow returns alatest_statsarray (one entry per placement) and, for placement networks, asummary_statsrollup summed across every placement.GET /api/profiles/:id/statsreturns the full timeseries — every snapshot recorded for a profile, ordered byrecorded_at, withfrom/tofilters.
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.
| Network | Placement-scoped? | Typical fields |
|---|---|---|
facebook | Yes (per page) | fan_count, followers_count, page_impressions, page_views_total, page_fan_adds, page_fan_removes |
linkedin | Yes (per organization) | followerCount, shareCount, likeCount, commentCount, clickCount, engagement, allPageViews, overviewPageViews, aboutPageViews, careersPageViews, peoplePageViews, insightsPageViews |
telegram | Yes (per channel) | followers_count, channel_title, channel_username |
instagram | No | followers_count, follows_count, media_count, reach, profile_views, accounts_engaged, total_interactions, website_clicks |
threads | No | followers_count, views, likes, replies, reposts, quotes |
youtube | No | subscriberCount, viewCount, videoCount |
twitter | No | followers_count, following_count, tweet_count, listed_count, like_count |
tiktok | No | follower_count, following_count, likes_count, video_count |
pinterest | No | follower_count, following_count, pin_count, board_count, monthly_views, analytics_30d |
bluesky | No | followersCount, 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 inlatest_stats[].statsbut are excluded fromsummary_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.
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?
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 Stats — records[].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:
- Call
GET /api/profilesto find the profile id. - Call
GET /api/profiles/:idfor the latest snapshot. - Call
GET /api/profiles/:id/statsfor the full timeseries. Passplacement_idfor Facebook, LinkedIn, and Telegram profiles.
No new scopes, no separate billing, no opt-in. Profile stats are recorded on every connected profile starting today.
Postproxy
One API for every social platform
Publish to Instagram, X, LinkedIn, TikTok, YouTube and more with a single request. Free plan, no credit card required.