curl "https://api.joinoverlap.com/post-analytics?companyId=YOUR_COMPANY_ID&postId=POST_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch(
'https://api.joinoverlap.com/post-analytics?companyId=YOUR_COMPANY_ID&postId=POST_ID',
{ headers: { Authorization: 'Bearer YOUR_API_KEY' } }
);
const { post, analytics } = await response.json();
import requests
response = requests.get(
"https://api.joinoverlap.com/post-analytics",
params={"companyId": "YOUR_COMPANY_ID", "postId": "POST_ID"},
headers={"Authorization": "Bearer YOUR_API_KEY"},
)
data = response.json()
print(data["analytics"]["views"], data["analytics"]["likes"])
Post Analytics
Retrieve all current analytics for a published post in one call
GET
/
post-analytics
curl "https://api.joinoverlap.com/post-analytics?companyId=YOUR_COMPANY_ID&postId=POST_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch(
'https://api.joinoverlap.com/post-analytics?companyId=YOUR_COMPANY_ID&postId=POST_ID',
{ headers: { Authorization: 'Bearer YOUR_API_KEY' } }
);
const { post, analytics } = await response.json();
import requests
response = requests.get(
"https://api.joinoverlap.com/post-analytics",
params={"companyId": "YOUR_COMPANY_ID", "postId": "POST_ID"},
headers={"Authorization": "Bearer YOUR_API_KEY"},
)
data = response.json()
print(data["analytics"]["views"], data["analytics"]["likes"])
Endpoint
GET https://api.joinoverlap.com/post-analytics?companyId={companyId}&postId={postId}
postIds with GET /posts.
Authentication
Authorization: Bearer YOUR_API_KEY
Query Parameters
| Parameter | Required | Description |
|---|---|---|
companyId | Yes | Your Overlap company or organization identifier. |
postId | Yes | The post id from GET /posts. |
The same lookup is also available at
GET /companies/{companyId}/posts/{postId}/analytics.curl "https://api.joinoverlap.com/post-analytics?companyId=YOUR_COMPANY_ID&postId=POST_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch(
'https://api.joinoverlap.com/post-analytics?companyId=YOUR_COMPANY_ID&postId=POST_ID',
{ headers: { Authorization: 'Bearer YOUR_API_KEY' } }
);
const { post, analytics } = await response.json();
import requests
response = requests.get(
"https://api.joinoverlap.com/post-analytics",
params={"companyId": "YOUR_COMPANY_ID", "postId": "POST_ID"},
headers={"Authorization": "Bearer YOUR_API_KEY"},
)
data = response.json()
print(data["analytics"]["views"], data["analytics"]["likes"])
Response
{
"post": {
"id": "uV9LKKuVU2IiRcwv7UvY",
"platform": "youtube",
"text": "Top agent Jarred Arfa and promoter Danny Hayes say fans finally figured out the game...",
"postUrl": "https://youtu.be/3j6-UUMa6WE",
"nativeId": "3j6-UUMa6WE",
"clipId": "6dd94ba0-908c-4489-897f-4bc02fe96650",
"status": "success",
"mediaUrl": "https://.../exported-6dd94ba0.mp4",
"thumbnailUrl": "https://.../thumb.jpg",
"createdAt": "2026-07-10T19:31:30+00:00"
},
"analytics": {
"views": 969,
"likes": 9,
"comments": 0,
"shares": 0,
"engagementScore": 27.69,
"growthRate": 9.1,
"lastAnalyticsUpdate": "2026-07-10T23:10:31+00:00",
"platformMetrics": {
"youtube": {
"analytics": {
"viewCount": 969,
"likeCount": 9,
"averageViewDuration": 21,
"estimatedMinutesWatched": 346,
"subscribersGained": 1
}
}
}
}
}
analytics.platformMetrics carries the platform’s own advanced metrics from
the most recent refresh — whatever the platform reports (e.g. YouTube
averageViewDuration / estimatedMinutesWatched, TikTok watch time and
retention, Facebook impression breakdowns, X organic metrics). Its shape
mirrors the platform’s analytics API and may change without notice; the
normalized counters above are the stable contract.Data freshness
Overlap refreshes post analytics from the social platforms on a schedule that slows as a post ages.analytics.lastAnalyticsUpdate tells you when the data was last refreshed.
A successful manual refresh also advances the next scheduled refresh using the
same age-based cadence. A profile that returns a rate-limit response has its
remaining queued posts deferred for a later run.
| Post age | Most platforms | X (Twitter) |
|---|---|---|
| First 24 hours | about every 2 hours | every 8 hours |
| 1 to 3 days | every 6 hours | every 8 hours |
| 3 to 7 days | every 12 hours | every 2 days |
| 7 to 30 days | daily | every 2 days |
| 30 to 60 days | every 2 days | weekly |
| 60 to 90 days | every 2 days | monthly |
| 90 days to 1 year | weekly | monthly |
| Over 1 year | monthly | monthly |
- YouTube analytics lag roughly 48 hours behind real time.
- X (Twitter) refreshes for posts older than 60 days pause near the end of a month when the monthly X API allowance runs low, and resume on the 1st. Recent X posts keep refreshing.
- Accounts needing attention — a social account that must be relinked, a TikTok share the creator has not finished, or a Google account missing permissions — are rechecked weekly rather than on the schedule above, until the account is fixed.
- Bluesky does not report per-post view counts, so
viewsstays0there. - Watch-time and other advanced fields in
platformMetricsare only present on platforms that report them.
List Posts
Discover post ids and browse rolled-up metrics.
Analytics Model
Field-by-field response reference.
Was this page helpful?