Analytics
Overview totals, time series, top posts, decay, cadence, demographics, and label roll-ups.
Analytics endpoints need the analytics scope. Metrics are collected on a schedule in the background, so a post published a minute ago has not been measured yet.
All of these accept workspace_id to scope the answer and accountId to narrow it to one account. Ranges are given either as days or as an explicit from and to.
Overview
GET /v1/analytics/overviewcurl "https://api.fopost.com/v1/analytics/overview?days=30" \
-H "X-API-Key: $FOPOST_API_KEY"Dashboard totals with period-over-period deltas, today's figures, and a per-account breakdown including follower history. This is the one endpoint to call if you only call one.
Time series
GET /v1/analytics/time-seriesDaily buckets of engagement, followers, and post counts. Use days, or from and to for an explicit window. This is what you chart.
Top posts
GET /v1/analytics/top-postsPosts ranked by engagement, or newest first with sort=recent. Takes limit, a range, accountId, and label.
It includes posts published natively on the network, not only ones that went out through FoPost, so the ranking reflects the account rather than the tool.
Demographics
GET /v1/analytics/demographicsAudience composition for the accounts whose networks report it. Networks differ in what they expose and in the minimum audience size they will report at all, so expect gaps rather than treating a missing breakdown as an error.
Posting streak
GET /v1/analytics/posting-streak365 days of posting activity, one bucket per day. This is the contribution-graph view of whether you are actually shipping.
Label roll-up
GET /v1/analytics/labelsAggregates performance by label, which is how you compare campaigns or clients when the posts are spread across accounts. Attach labels at post creation, then read them back here.
Posts table
GET /v1/analytics/posts-tablePosts with their per-account delivery breakdown, for building a table rather than a chart.
Content decay
GET /v1/analytics/decaycurl "https://api.fopost.com/v1/analytics/decay?days=30" \
-H "X-API-Key: $FOPOST_API_KEY"How long a post keeps earning. Each post is measured many times as it ages, so the readings can be grouped into age bands: under an hour, 1-3 hours, and so on up to a week. Every band reports where the average post had got to by that age and shareOfFinal, what fraction of everything it eventually earned that was.
halfLifeBucket is the first band where the average post had passed half its final engagement. On most networks that lands inside the first few hours, which is the number worth arguing with your posting schedule about.
days filters by publish time, not reading time: it selects posts published in the window, then uses every reading taken of them. A post published a minute ago contributes nothing useful yet, and a band with posts: 0 means nothing was measured at that age rather than that nothing happened.
Posting frequency
GET /v1/analytics/frequencyWhether posting more earned more. Weeks run Monday to Sunday in UTC and are grouped into cadence bands by their own post count, so a week with four posts is compared against other four-post weeks rather than against the average. Each band reports the engagement the average post in those weeks earned, and best names the cadence that earned the most per post.
A week with no posts belongs to no band and is left out, so an idle month does not drag a cadence down.
Post timeline
GET /v1/analytics/posts/{id}/timelineEvery reading held for one post, oldest first, with one timeline per delivery, because the same post on two networks decays differently. Each point carries the reading and delta, what moved since the point before it.
id is a FoPost post id, or the URL-encoded permalink of a post made natively on the network:
curl "https://api.fopost.com/v1/analytics/posts/$(printf %s 'https://x.com/acme/status/1' | jq -sRr @uri)/timeline" \
-H "X-API-Key: $FOPOST_API_KEY"A post in a workspace you are not in answers 404, the same as one that does not exist.
Changes since
GET /v1/analytics/changes?since=2026-03-02T00:00:00ZReadings recorded after since, oldest first, with a cursor to pass as the next since. This is how you mirror our metrics into your own store without refetching the whole history: poll on whatever interval suits you, store cursor, pass it back.
Omitting since gives the last seven days. hasMore tells you the page was full and another call will return more; cursor is null when nothing changed.
Posts made outside FoPost
GET /v1/accounts/{id}/native-postsPosts that exist on the account but never went out through FoPost, newest first, with the freshest metrics held for each. Useful for reconciling an account you started managing partway through, or for seeing what a client posted by hand.
Paginate with page and per_page; days narrows to posts published recently. An API key needs the analytics scope as well as accounts.
Collect on demand
POST /v1/analytics/collectForces a collection run for the active accounts instead of waiting for the next scheduled one. It is throttled per user: when you are over the limit, the 429 body carries retryAfter in seconds.
Use it after publishing something you want to measure now. Do not put it on a timer, since the scheduled collection is already doing that.
To refresh a single post rather than every account:
POST /v1/posts/{id}/analytics/collectid is a FoPost post id or a URL-encoded permalink, the same as the timeline endpoint. One post is still a call to the network, so it spends the same per-user budget as the full run and answers the same 429 with retryAfter. An API key needs the analytics scope as well as posts.
Next
Per-network metrics
GET /v1/accounts/{id}/insights?raw=truecurl "https://api.fopost.com/v1/accounts/$ACCOUNT_ID/insights?raw=true" \
-H "X-API-Key: $FOPOST_API_KEY"Every endpoint above answers in one vocabulary, so a number can be compared across networks. This one does the opposite: it answers in the network's own vocabulary, keyed by the metric names the platform itself uses.
That is where the numbers live that have no equivalent anywhere else. Facebook reports ad-break earnings for a monetised Page and splits impressions into paid and organic. Instagram reports how viewers left a story, split into taps forward, taps back, exits and swipes. TikTok reports its four video counts. YouTube reports a daily views series and, per video, an audience-retention curve. LinkedIn reports reactions split by type and page views split by surface. Google Business reports how people found the listing and which search terms surfaced it.
{
"data": {
"platform": "facebook",
"account": {
"fetched_at": "2026-09-20T02:00:00.000Z",
"metrics": [
{ "key": "page_impressions", "label": "Page Impressions", "kind": "count", "value": 41800 },
{
"key": "page_daily_video_ad_break_earnings",
"label": "Ad Break Earnings",
"kind": "currency_usd",
"value": 42.15
}
]
},
"post": {
"external_post_id": "1234567890_9876543210",
"fetched_at": "2026-09-20T02:00:00.000Z",
"metrics": [
{ "key": "post_impressions_paid", "label": "Paid Impressions", "kind": "count", "value": 1500 }
]
}
}
}key is the platform's own metric name and never changes. label is ours and may be reworded, so read key if you are storing anything. kind tells you how to render the value: count, duration_ms, currency_usd, ratio, or series for a value that is an array of points rather than a number.
Both blocks come from the newest collected snapshot, not a live call to the network, so fetched_at is when the numbers were true. A network that reports nothing per post answers an empty post.metrics.
Reads are throttled the same way the rest of the API is, and the endpoint needs the analytics scope. Some networks gate their metrics behind an access grant we have requested and not yet received; those answer 503 with platform_metrics_unavailable rather than an empty set, so a pending grant never reads as a zero.
Related documentation
- API Overview
Base URL, envelopes, pagination, and errors for the FoPost REST API.
- Authentication
API keys, scopes, and workspace binding.
- Publishing
Create a post, target accounts, publish it, and read the per-account result.
- Scheduling
Schedule a post, repeat it, and import a batch from a spreadsheet.
- Media
Upload files, list the media library, and attach media to a post.
- Validation
Check content, text length, and media against platform rules before a post exists.
- Accounts
List connected social accounts, check their health, and refresh credentials.
- Workspaces
Workspaces, labels, and how isolation works across them.