Analytics
Analytics and normalized metrics for YouTube videos.
Read performance metrics for a published YouTube video. Metrics combine YouTube Analytics with public video statistics as fallback. Pass post as described in Analytics. Use the internal id for Onepostly uploads. Use the native video id plus accountId for outside videos.
Request
import { Configuration, AnalyticsApi } from "@onepostly/sdk";
const analyticsApi = new AnalyticsApi(
new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY }),
);
const { analytics } = await analyticsApi.getAnalytics({ post: postId });
console.log(analytics.subjects);Response
{
"analytics": {
"post": "POST_ID",
"status": "ready",
"fetchedAt": "2026-08-25T10:00:00.000Z",
"subjects": [
{
"scope": "destination",
"subjectId": "DEST_ID",
"accountId": "ACCOUNT_ID",
"platform": "youtube",
"externalPostId": "dQw4w9WgXcQ",
"status": "ready",
"metrics": {
"impressions": 5400,
"reach": null,
"likes": 230,
"comments": 31,
"shares": null,
"saves": null,
"plays": 5400,
"engagement": 261
},
"fetchedAt": "2026-08-25T10:00:00.000Z",
"expiresAt": "2026-08-25T11:00:00.000Z",
"error": null
}
]
}
}Daily timeline
Day by day cumulative metrics per subject. Optional from and to bound the inclusive UTC date range. The default window covers the last 366 days.
const { timeline } = await analyticsApi.getAnalyticsTimeline({
post: postId,
from: "2026-08-01",
to: "2026-08-28",
});
// timeline.subjects[].points[].day, metrics, deltaEach metrics object holds cumulative totals as captured on that UTC day. delta compares them against the previous stored day. A delta entry stays null when either side has no value. Days without a stored snapshot have no data. The API does not backfill them.
Outside posts
Videos uploaded outside Onepostly work the same way once they are synced. Sync by URL then read analytics with the native id plus accountId. Omit url and postId to refresh the recent posts of the account in bulk.
const { found, post } = await posts.syncExternal({
syncExternalBody: { accountId, url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" },
});
if (!found || !post) throw new Error("Post not found on the account.");
const { analytics } = await analyticsApi.getAnalytics({
post: post.externalPostId,
accountId,
});Normalized fields
| Field | Meaning on YouTube |
|---|---|
impressions and plays | View count |
reach | Always null. YouTube Analytics is not queried for it |
likes | Like count |
comments | Comment count |
shares | Share count, when Analytics reports it |
saves | Always null. There is no save concept |
engagement | Likes plus comments, plus shares when present |
Missing values stay null.
Pending semantics
Errors
| Code | Cause | Fix |
|---|---|---|
NOT_PUBLISHED | Destination not published yet | Wait for publish |
ANALYTICS_PERMISSION | Connection lacks yt-analytics.readonly | Reconnect the account |
ANALYTICS_PENDING | Metrics not ready yet | Retry later |
ANALYTICS_FAILED | Hard failure fetching metrics | Retry. Contact support if it persists |