YouTube Analytics API: reports.query, Scopes, Latency
The YouTube Analytics API returns watch time, views, subscribers gained, and audience data for a channel that authorized your app. You call one method, reports.query, with a channel ID, a date range, metrics, and optional dimensions and filters, using an OAuth token with the yt-analytics.readonly scope. Figures lag two to three days. Adeli returns YouTube channel and video insights through two GET endpoints.
The YouTube Analytics API is Google's API for channel and video metrics over a date range: views, watch time, average view duration, subscribers gained and lost, traffic sources, and viewer demographics. It has one main method, reports.query, and it only answers for channels that authorized your app with OAuth. Below: how it differs from the YouTube Data API and the Reporting API, the request itself, the scopes, the lag, and the limits.
If you haven't set up Google OAuth yet, start with our YouTube API OAuth guide. This post assumes you can get an access token for a channel.
Which YouTube API returns analytics?
Google offers three ways to get YouTube numbers, and they answer different questions. The Data API returns current counters, the Analytics API returns custom reports for a window, and the Reporting API returns fixed daily bulk files.
| YouTube Data API v3 | YouTube Analytics API | YouTube Reporting API | |
|---|---|---|---|
| What you get | Current lifetime counters on a video or channel | Metrics over a date range, grouped by dimensions you choose | A fixed daily report file per job |
| Example numbers | viewCount, likeCount, commentCount, subscriberCount |
estimatedMinutesWatched, averageViewDuration, subscribersGained, viewerPercentage |
The same kind of metrics, one 24-hour period per file |
| Whose channels | Any public video or channel | Channels that authorized your app | Channels or content owners that authorized your app |
| Auth | API key for public data, OAuth for private | OAuth only | OAuth only |
| How you query | videos.list, channels.list |
reports.query with filters and sorting on Google's side |
Schedule a job, then download each day's report and filter it yourself |
Sources: Google's videos resource, channels resource, and Reporting API overview.
Pick the Analytics API when you need a dashboard for a connected channel. Pick the Data API when a current view count is enough. Pick the Reporting API when you want every day's data in your own warehouse and will do the aggregation yourself.
Some Data API fields don't mean what they look like:
subscriberCountis rounded. Google rounds it down to three significant figures, andhiddenSubscriberCounttells you when the owner hides it.videoCountcounts public videos only, even when the owner makes the request.dislikeCountis private. It only comes back when the video's owner authenticated the request.
What do you need before you start?
- A Google Cloud project with the YouTube Analytics API enabled in the API Library. It's a separate API from the YouTube Data API v3. Enable both if you also want titles and thumbnails.
- An OAuth client and a consent screen. Our OAuth guide walks through both.
- An access token from a channel owner that carries an analytics scope (next section).
- The channel's ID, or use
channel==MINEfor the channel that owns the token.
Which OAuth scope does the YouTube Analytics API need?
Request yt-analytics.readonly for views, watch time, and audience metrics. Google's reports.query reference lists the scopes:
| Scope | What it unlocks |
|---|---|
yt-analytics.readonly |
User activity metrics such as views and rating counts |
yt-analytics-monetary.readonly |
The same, plus estimated revenue and ad performance metrics |
youtube |
Managing Analytics groups for a channel owner |
youtubepartner |
Managing groups for a content owner |
Each is prefixed with https://www.googleapis.com/auth/. Only ask for the monetary scope if you show revenue. It reads as a bigger request on the consent screen.
Google's reference also carries a note that reports.query requests now require access to the youtube.readonly scope. The reference doesn't say whether a broader scope such as youtube or youtube.force-ssl meets that requirement, so request youtube.readonly by name alongside yt-analytics.readonly.
If the channel is already connected for uploads, you can add the analytics scope later with incremental authorization (include_granted_scopes=true) instead of asking for everything up front.
How do you call reports.query?
Send a GET to https://youtubeanalytics.googleapis.com/v2/reports with four required parameters: ids, startDate, endDate, and metrics. Everything else narrows or shapes the report.
| Parameter | Required | What it does |
|---|---|---|
ids |
Yes | channel==MINE, channel==CHANNEL_ID, or contentOwner==OWNER_NAME |
startDate, endDate |
Yes | YYYY-MM-DD. Data stops at the last fully processed day |
metrics |
Yes | Comma-separated, such as views,estimatedMinutesWatched |
dimensions |
No | How rows are grouped, such as day, video, country, or ageGroup,gender |
filters |
No | Limits rows, such as video==VIDEO_ID or country==US. Join filters with ; |
sort |
No | A - prefix sorts descending, such as -views |
maxResults, startIndex |
No | Paging. startIndex is 1-based |
Daily channel metrics
curl -G "https://youtubeanalytics.googleapis.com/v2/reports" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
--data-urlencode "ids=channel==MINE" \
--data-urlencode "startDate=2026-09-01" \
--data-urlencode "endDate=2026-09-28" \
--data-urlencode "metrics=views,estimatedMinutesWatched,averageViewDuration,subscribersGained,subscribersLost" \
--data-urlencode "dimensions=day" \
--data-urlencode "sort=day"The response is a table: columnHeaders names each column and rows holds one array per day, in the same order. Map the rows by header name rather than by position, because the order follows your dimensions and metrics strings.
Top videos in the window
curl -G "https://youtubeanalytics.googleapis.com/v2/reports" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
--data-urlencode "ids=channel==MINE" \
--data-urlencode "startDate=2026-09-01" \
--data-urlencode "endDate=2026-09-28" \
--data-urlencode "metrics=views,estimatedMinutesWatched,averageViewDuration" \
--data-urlencode "dimensions=video" \
--data-urlencode "sort=-views" \
--data-urlencode "maxResults=10"Google's channel reports page sets the rules for top-video reports: the video dimension needs a sort, and maxResults can be at most 200. The response gives video IDs only, so call videos.list in the Data API for titles and thumbnails.
One video's demographics
curl -G "https://youtubeanalytics.googleapis.com/v2/reports" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
--data-urlencode "ids=channel==MINE" \
--data-urlencode "startDate=2026-09-01" \
--data-urlencode "endDate=2026-09-28" \
--data-urlencode "metrics=viewerPercentage" \
--data-urlencode "dimensions=ageGroup,gender" \
--data-urlencode "filters=video==VIDEO_ID"Not every metric works with every dimension. Demographics use viewerPercentage, audience retention needs elapsedVideoTimeRatio with a single-video filter, and traffic source reports fail when the number of videos times the days in the range passes 50,000. The channel reports page lists which combinations Google supports.
Which YouTube Analytics metrics matter most?
These are the metrics a channel dashboard usually starts with. Definitions from Google's metrics reference:
| Metric | What it measures |
|---|---|
views |
Views. Google notes its meaning shifts between report types |
engagedViews |
Views past the first frame, or where the user clicked or tapped to play |
estimatedMinutesWatched |
Total minutes watched |
averageViewDuration |
Average playback length, in seconds |
averageViewPercentage |
Average share of the video watched per playback |
subscribersGained, subscribersLost |
Subscribes and unsubscribes. In video reports, only those from that video's watch page |
likes, comments, shares |
Engagement actions in the window |
viewerPercentage |
Share of logged-in viewers in each demographic group |
How fresh is YouTube Analytics data?
Expect a lag of about two to three days. Google's data model page says the underlying data is not real-time and responses don't include the most recent days. A request whose endDate is yesterday returns data up to the last fully processed day and stops there.
That has two practical effects:
- End your default window a few days back. A 28-day window that ends today shows a fake drop in the last few days.
- Use the Data API for live counters. Google recommends
videos.listfor a video's current views or likes.
What are the YouTube Analytics API limits?
The limits come from Google's quota and from the report rules, not from a per-call price. Things to plan for:
- Separate quota. The Analytics API is its own Google Cloud API, so its usage shows on your project's Quotas page, apart from the YouTube Data API's daily units. Google doesn't publish the Analytics API's default limits in its docs, so check them on the Quotas page in the Google Cloud console for
youtubeanalytics.googleapis.com. - Data API calls still count. Titles and thumbnails come from
videos.list, which costs 1 unit per call from the Data API's default 10,000 units a day, per Google's quota and compliance audits page. - Row caps. Top-video reports return at most 200 rows, and detail reports for traffic sources and playback locations return at most 25.
- Small channels get gaps. Demographic reports can come back empty when a channel has too few viewers.
When should I use the YouTube Reporting API instead?
Use the Reporting API when you want every day's data stored on your side. You schedule a job for a report type, and YouTube generates one file per day, each covering a single 24-hour period. Per Google's reports page:
- The first report arrives within 48 hours of creating the job.
- A new job backfills 30 days of historical data.
- Reports stay downloadable for 60 days, and historical backfill reports for 30.
It costs you more work. The Reporting API has no server-side filtering or sorting, and weekly or monthly totals are yours to compute. For a product that shows each customer their own channel, reports.query is usually simpler.
Is there a faster way to get YouTube analytics?
Yes. Let an API that already runs the Google OAuth flow make the reports.query calls. Adeli's YouTube API holds the Google OAuth client, requests yt-analytics.readonly when a channel connects, and refreshes every channel's tokens. You don't enable a Cloud project or map columnHeaders to rows.
Adeli has two YouTube analytics endpoints:
| Adeli endpoint | What it returns |
|---|---|
| YouTube channel insights | Channel details, daily views, minutes watched, average view duration, subscribers gained and lost, likes, comments, shares, the top ten videos, and age, gender, and country breakdowns |
| YouTube video insights | Views, minutes watched, average view duration and percentage, likes, comments, shares, and subscribers gained for up to 50 videos, or the channel's 20 newest |
A channel insights request for a 28-day window:
curl -G "https://app.tryadeli.com/api/v1/analytics/youtube/channel-insights" \
-H "Authorization: Bearer $ADELI_API_KEY" \
--data-urlencode "accountId=$ACCOUNT_ID" \
--data-urlencode "startDate=2026-09-05" \
--data-urlencode "endDate=2026-10-02"And video insights for specific uploads, using the providerId from GET /api/v1/posts:
curl -G "https://app.tryadeli.com/api/v1/analytics/youtube/video-insights" \
-H "Authorization: Bearer $ADELI_API_KEY" \
--data-urlencode "accountId=$ACCOUNT_ID" \
--data-urlencode "videoIds=dQw4w9WgXcQ"How the endpoints behave, per the docs:
- The default window already allows for the lag. Leave out the dates and you get the 28 days ending three days ago. A window covers at most 365 days.
- Missing figures are
null. A video with no data in the window comes back with every metricnull, andchannel.subscribersisnullwhen the channel hides its count. - A missing grant is explicit. A connection without
yt-analytics.readonlyreturns422 connection_expiredwith "Reconnect YouTube to enable analytics", and reconnecting fixes it.
The same API key uploads videos to YouTube and reads Instagram, Facebook, TikTok, and YouTube analytics. A YouTube channel counts as one connected account, and your first 3 connected accounts are free on Adeli's pricing.