The YouTube Analytics API's reports.query
method lets you retrieve many different Analytics reports. Each request uses query parameters to specify a channel ID or content owner, a start date, an end date, and at least one metric. You can also provide additional query parameters, such as dimensions, filters, or sorting instructions.
- Metrics are individual measurements of user activity, such as video views or ratings (likes and dislikes).
- Dimensions are common criteria that are used to aggregate data, such as the date on which the user activity occurred or the country where the users were located.
- Filters are dimension values that specify the data that will be retrieved. For example, you could retrieve data for a specific country, a specific video, or a group of videos.
Note: Content owner reports are only accessible to YouTube content partners who participate in the YouTube Partner Program.
Request
To retrieve YouTube Analytics data via the API, send a GET
request to the following URL:
https://www.googleapis.com/youtube/analytics/v1/reports
Authorization
This request requires authorization with the following scope:
https://www.googleapis.com/auth/yt-analytics.readonly
See the authentication guide for detailed instructions on implementing OAuth 2.0 authentication in your application.
Parameters
The following tables list the API's required, optional, and standard query parameters. Standard parameters are optional parameters that could be used for any request. For example, the standard alt
parameter specifies whether the API response should be in JSON or CSV format. (Since the API currently only supports a single method, the standard parameters are listed below as well.)
Parameters | ||
---|---|---|
Required Parameters | ||
end-date |
string The end date for fetching YouTube Analytics data. The value should be in YYYY-MM-DD format.
|
|
ids |
string Identifies the YouTube channel or content owner for which you are retrieving YouTube Analytics data.
|
|
metrics |
string A comma-separated list of YouTube Analytics metrics, such as views or likes,dislikes . See the Available Reports document for a list of the reports that you can retrieve and the metrics available in each report, and see the Metrics document for definitions of those metrics.
|
|
start-date |
string The start date for fetching YouTube Analytics data. The value should be in YYYY-MM-DD format.
|
|
Optional Parameters | ||
currency |
string The currency that the API will use to specify the following earnings metrics: earnings, adEarnings, grossRevenue, playbackBasedCpm, impressionBasedCpm. The values that the API returns for those metrics are estimates calculated using exchange rates that change on a daily basis. If none of those metrics are requested, the parameter is ignored. The parameter value is a three-letter ISO 4217 currency code from the list of currencies below. The API returns an error if an unsupported currency is specified. The default value is USD . |
|
dimensions |
string A comma-separated list of YouTube Analytics dimensions, such as video or ageGroup,gender . See the Available Reports document for a list of the reports that you can retrieve and the dimensions used for those reports. Also see the Dimensions document for definitions of those dimensions.
|
|
filters |
string A list of filters that should be applied when retrieving YouTube Analytics data. The Available Reports document identifies the dimensions that can be used to filter each report, and the Dimensions document defines those dimensions. If a request uses multiple filters, join them together with a semicolon ( ; ), and the returned result table will satisfy both filters. For example, a filters parameter value of video==dMH0bHeiRNg;country==IT restricts the result set to include data for the given video in Italy.Specifying multiple values for a filter The API supports the ability to specify multiple values for the video , playlist , and channel filters. To do so, specify a separated list of the video, playlist, or channel IDs for which the API response should be filtered. For example, a filters parameter value of video==pd1FJh59zxQ,Zhawgd0REhA;country==IT restricts the result set to include data for the given videos in Italy. The parameter value can specify up to 200 IDs.When specifying multiple values for the same filter, you can also add that filter to the list of dimensions that you specify for the request. This is true even if the filter is not listed as a supported dimension for a particular report. If you do add the filter to the list of dimensions, then the API also uses the filter values to group results. For example, suppose you retrieve a traffic source report, which aggregates viewing statistics based on the manner in which viewers reached your video content. Your request's filters parameter request identifies a list of 10 videos for which data should be returned.
| |
max-results |
integer The maximum number of rows to include in the response. |
|
sort |
string A comma-separated list of dimensions or metrics that determine the sort order for YouTube Analytics data. By default the sort order is ascending. The - prefix causes descending sort order.
|
|
start-index |
integer The 1-based index of the first entity to retrieve. (The default value is 1 .) Use this parameter as a pagination mechanism along with the max-results parameter.
|
|
Standard Parameters | ||
access_token |
OAuth 2.0 token for the current user.
|
|
alt |
Data format for the response.
|
|
callback |
Callback function.
|
|
fields |
Selector specifying a subset of fields to include in the response.
|
|
key |
API key. (REQUIRED*) See the Developers Console.
|
|
prettyPrint |
Returns response with indentations and line breaks.
|
|
quotaUser |
Alternative to userIp .
|
|
userIp |
IP address of the end user for whom the API call is being made.
|
Request body
Do not supply a request body for this method.
Response
As noted in the alt
parameter definition, the API can return responses in JSON or CSV format. Information about the response body for each type is shown below:
{ "kind": "youtubeAnalytics#resultTable", "columnHeaders": [ { "name": string, "dataType": string, "columnType": string }, ... more headers ... ], "rows": [ [ {value}, {value}, ... ] ] }
Properties | |
---|---|
kind |
string This value specifies the type of data included in the API response. For the query method, the kind property value will be youtubeAnalytics#resultTable . However, if the API adds support for other methods, API responses for those methods may introduce other kind property values. |
columnHeaders[] |
list This value specifies information about the data returned in the rows fields. Each item in the columnHeaders list identifies a field returned in the rows value, which contains a list of comma-delimited data.The columnHeaders list begins with the dimensions specified in the API request, which are followed by the metrics specified in the API request. The order of both dimensions and metrics matches the ordering in the API request.For example, if the API request contains the parameters dimensions=ageGroup,gender&metrics=viewerPercentage , the API response returns columns in this order: ageGroup ,gender ,viewerPercentage . |
columnHeaders[].name |
string The name of the dimension or metric. |
columnHeaders[].columnType |
string The type of the column ( DIMENSION or METRIC ). |
columnHeaders[].dataType |
string The type of the data in the column ( STRING , INTEGER , FLOAT , etc.). |
rows[] |
list The list contains all rows of the result table. Each item in the list is an array that contains comma-delimited data corresponding to a single row of data. The order of the comma-delimited data fields will match the order of the columns listed in the columnHeaders field.If no data is available for the given query, the rows element will be omitted from the response.The response for a query with the day dimension will not contain rows for the most recent days. |
day, views, likes, ... "2012-01-01", 12.0, 3, ... "2012-01-02", 16.0, 2, ... "2012-01-03", 18.0, 8, ... ...
Examples
Note: The code samples below may not represent all supported programming languages. See the client libraries documentation for a list of supported languages.
Apps Script
This function uses the YouTube Analytics API to fetch data about the authenticated user's channel, creating a new Google Sheet in the user's Drive with the data.The first part of this sample demonstrates a simple YouTube Analytics API call. This function first fetches the active user's channel ID. Using that ID, the function makes a YouTube Analytics API call to retrieve views, likes, dislikes and shares for the last 30 days. The API returns the data in a response object that contains a 2D array.
The second part of the sample constructs a Spreadsheet. This spreadsheet is placed in the authenticated user's Google Drive with the name 'YouTube Report' and date range in the title. The function populates the spreadsheet with the API response, then locks columns and rows that will define a chart axes. A stacked column chart is added for the spreadsheet.
/** * This function uses the YouTube Analytics API to fetch data about the * authenticated user's channel, creating a new Google Sheet in the user's Drive * with the data. * * The first part of this sample demonstrates a simple YouTube Analytics API * call. This function first fetches the active user's channel ID. Using that * ID, the function makes a YouTube Analytics API call to retrieve views, * likes, dislikes and shares for the last 30 days. The API returns the data * in a response object that contains a 2D array. * * The second part of the sample constructs a Spreadsheet. This spreadsheet * is placed in the authenticated user's Google Drive with the name * 'YouTube Report' and date range in the title. The function populates the * spreadsheet with the API response, then locks columns and rows that will * define a chart axes. A stacked column chart is added for the spreadsheet. */ function spreadsheetAnalytics() { // Get the channel ID var myChannels = YouTube.Channels.list('id', {mine: true}); var channel = myChannels.items[0]; var channelId = channel.id; // Set the dates for our report var today = new Date(); var oneMonthAgo = new Date(); oneMonthAgo.setMonth(today.getMonth() - 1); var todayFormatted = Utilities.formatDate(today, 'UTC', 'yyyy-MM-dd') var oneMonthAgoFormatted = Utilities.formatDate(oneMonthAgo, 'UTC', 'yyyy-MM-dd'); // The YouTubeAnalytics.Reports.query() function has four required parameters and one optional // parameter. The first parameter identifies the channel or content owner for which you are // retrieving data. The second and third parameters specify the start and end dates for the // report, respectively. The fourth parameter identifies the metrics that you are retrieving. // The fifth parameter is an object that contains any additional optional parameters // (dimensions, filters, sort, etc.) that you want to set. var analyticsResponse = YouTubeAnalytics.Reports.query( 'channel==' + channelId, oneMonthAgoFormatted, todayFormatted, 'views,likes,dislikes,shares', { dimensions: 'day', sort: '-day' }); // Create a new Spreadsheet with rows and columns corresponding to our dates var ssName = 'YouTube channel report ' + oneMonthAgoFormatted + ' - ' + todayFormatted; var numRows = analyticsResponse.rows.length; var numCols = analyticsResponse.columnHeaders.length; // Add an extra row for column headers var ssNew = SpreadsheetApp.create(ssName, numRows + 1, numCols); // Get the first sheet var sheet = ssNew.getSheets()[0]; // Get the range for the title columns // Remember, spreadsheets are 1-indexed, whereas arrays are 0-indexed var headersRange = sheet.getRange(1, 1, 1, numCols); var headers = []; // These column headers will correspond with the metrics requested // in the initial call: views, likes, dislikes, shares for(var i in analyticsResponse.columnHeaders) { var columnHeader = analyticsResponse.columnHeaders[i]; var columnName = columnHeader.name; headers[i] = columnName; } // This takes a 2 dimensional array headersRange.setValues([headers]); // Bold and freeze the column names headersRange.setFontWeight('bold'); sheet.setFrozenRows(1); // Get the data range and set the values var dataRange = sheet.getRange(2, 1, numRows, numCols); dataRange.setValues(analyticsResponse.rows); // Bold and freeze the dates var dateHeaders = sheet.getRange(1, 1, numRows, 1); dateHeaders.setFontWeight('bold'); sheet.setFrozenColumns(1); // Include the headers in our range. The headers are used // to label the axes var range = sheet.getRange(1, 1, numRows, numCols); var chart = sheet.newChart() .asColumnChart() .setStacked() .addRange(range) .setPosition(4, 2, 10, 10) .build(); sheet.insertChart(chart); }
Java
The code sample below calls the API's reports.query
method to retrieve YouTube Analytics data. The code retrieves for channel views over time, top videos, and demographic data.
This example uses the Java client library.
package com.google.api.services.samples.youtube.cmdline.analytics; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.samples.youtube.cmdline.Auth; import com.google.api.services.youtube.YouTube; import com.google.api.services.youtube.model.Channel; import com.google.api.services.youtube.model.ChannelListResponse; import com.google.api.services.youtubeAnalytics.YouTubeAnalytics; import com.google.api.services.youtubeAnalytics.model.ResultTable; import com.google.api.services.youtubeAnalytics.model.ResultTable.ColumnHeaders; import com.google.common.collect.Lists; import java.io.IOException; import java.io.PrintStream; import java.math.BigDecimal; import java.util.List; /** * This example uses the YouTube Data and YouTube Analytics APIs to retrieve * YouTube Analytics data. It also uses OAuth 2.0 for authorization. * * @author Christoph Schwab-Ganser and Jeremy Walker */ public class YouTubeAnalyticsReports { /** * Define a global instance of the HTTP transport. */ private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); /** * Define a global instance of the JSON factory. */ private static final JsonFactory JSON_FACTORY = new JacksonFactory(); /** * Define a global instance of a Youtube object, which will be used * to make YouTube Data API requests. */ private static YouTube youtube; /** * Define a global instance of a YoutubeAnalytics object, which will be * used to make YouTube Analytics API requests. */ private static YouTubeAnalytics analytics; /** * This code authorizes the user, uses the YouTube Data API to retrieve * information about the user's YouTube channel, and then fetches and * prints statistics for the user's channel using the YouTube Analytics API. * * @param args command line args (not used). */ public static void main(String[] args) { // These scopes are required to access information about the // authenticated user's YouTube channel as well as Analytics // data for that channel. List<String> scopes = Lists.newArrayList( "https://www.googleapis.com/auth/yt-analytics.readonly", "https://www.googleapis.com/auth/youtube.readonly" ); try { // Authorize the request. Credential credential = Auth.authorize(scopes, "analyticsreports"); // This object is used to make YouTube Data API requests. youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName("youtube-analytics-api-report-example") .build(); // This object is used to make YouTube Analytics API requests. analytics = new YouTubeAnalytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName("youtube-analytics-api-report-example") .build(); // Construct a request to retrieve the current user's channel ID. YouTube.Channels.List channelRequest = youtube.channels().list("id,snippet"); channelRequest.setMine(true); channelRequest.setFields("items(id,snippet/title)"); ChannelListResponse channels = channelRequest.execute(); // List channels associated with the user. List<Channel> listOfChannels = channels.getItems(); // The user's default channel is the first item in the list. Channel defaultChannel = listOfChannels.get(0); String channelId = defaultChannel.getId(); PrintStream writer = System.out; if (channelId == null) { writer.println("No channel found."); } else { writer.println("Default Channel: " + defaultChannel.getSnippet().getTitle() + " ( " + channelId + " )\n"); printData(writer, "Views Over Time.", executeViewsOverTimeQuery(analytics, channelId)); printData(writer, "Top Videos", executeTopVideosQuery(analytics, channelId)); printData(writer, "Demographics", executeDemographicsQuery(analytics, channelId)); } } catch (IOException e) { System.err.println("IOException: " + e.getMessage()); e.printStackTrace(); } catch (Throwable t) { System.err.println("Throwable: " + t.getMessage()); t.printStackTrace(); } } /** * Retrieve the views and unique viewers per day for the channel. * * @param analytics The service object used to access the Analytics API. * @param id The channel ID from which to retrieve data. * @return The API response. * @throws IOException if an API error occurred. */ private static ResultTable executeViewsOverTimeQuery(YouTubeAnalytics analytics, String id) throws IOException { return analytics.reports() .query("channel==" + id, // channel id "2012-01-01", // Start date. "2012-01-14", // End date. "views,uniques") // Metrics. .setDimensions("day") .setSort("day") .execute(); } /** * Retrieve the channel's 10 most viewed videos in descending order. * * @param analytics the analytics service object used to access the API. * @param id the string id from which to retrieve data. * @return the response from the API. * @throws IOException if an API error occurred. */ private static ResultTable executeTopVideosQuery(YouTubeAnalytics analytics, String id) throws IOException { return analytics.reports() .query("channel==" + id, // channel id "2012-01-01", // Start date. "2012-08-14", // End date. "views,subscribersGained,subscribersLost") // Metrics. .setDimensions("video") .setSort("-views") .setMaxResults(10) .execute(); } /** * Retrieve the demographics report for the channel. * * @param analytics the analytics service object used to access the API. * @param id the string id from which to retrieve data. * @return the response from the API. * @throws IOException if an API error occurred. */ private static ResultTable executeDemographicsQuery(YouTubeAnalytics analytics, String id) throws IOException { return analytics.reports() .query("channel==" + id, // channel id "2007-01-01", // Start date. "2012-08-14", // End date. "viewerPercentage") // Metrics. .setDimensions("ageGroup,gender") .setSort("-viewerPercentage") .execute(); } /** * Prints the API response. The channel name is printed along with * each column name and all the data in the rows. * * @param writer stream to output to * @param title title of the report * @param results data returned from the API. */ private static void printData(PrintStream writer, String title, ResultTable results) { writer.println("Report: " + title); if (results.getRows() == null || results.getRows().isEmpty()) { writer.println("No results Found."); } else { // Print column headers. for (ColumnHeaders header : results.getColumnHeaders()) { writer.printf("%30s", header.getName()); } writer.println(); // Print actual data. for (List<Object> row : results.getRows()) { for (int colNum = 0; colNum < results.getColumnHeaders().size(); colNum++) { ColumnHeaders header = results.getColumnHeaders().get(colNum); Object column = row.get(colNum); if ("INTEGER".equals(header.getUnknownKeys().get("dataType"))) { long l = ((BigDecimal) column).longValue(); writer.printf("%30d", l); } else if ("FLOAT".equals(header.getUnknownKeys().get("dataType"))) { writer.printf("%30f", column); } else if ("STRING".equals(header.getUnknownKeys().get("dataType"))) { writer.printf("%30s", column); } else { // default output. writer.printf("%30s", column); } } writer.println(); } writer.println(); } } }
JavaScript
This example uses the JavaScript client library.
(function() { // Retrieve your client ID from the Google Developers Console at // https://console.developers.google.com/. var OAUTH2_CLIENT_ID = 'YOUR_CLIENT_ID'; var OAUTH2_SCOPES = [ 'https://www.googleapis.com/auth/yt-analytics.readonly', 'https://www.googleapis.com/auth/youtube.readonly' ]; var ONE_MONTH_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 30; // Keep track of the currently authenticated user's YouTube channel ID. var channelId; // For information about the Google Chart Tools API, see: // https://developers.google.com/chart/interactive/docs/quick_start google.load('visualization', '1.0', {'packages': ['corechart']}); // Upon loading, the Google APIs JS client automatically invokes this callback. // See http://code.google.com/p/google-api-javascript-client/wiki/Authentication window.onJSClientLoad = function() { gapi.auth.init(function() { window.setTimeout(checkAuth, 1); }); }; // Attempt the immediate OAuth 2.0 client flow as soon as the page loads. // If the currently logged-in Google Account has previously authorized // the client specified as the OAUTH2_CLIENT_ID, then the authorization // succeeds with no user intervention. Otherwise, it fails and the // user interface that prompts for authorization needs to display. function checkAuth() { gapi.auth.authorize({ client_id: OAUTH2_CLIENT_ID, scope: OAUTH2_SCOPES, immediate: true }, handleAuthResult); } // Handle the result of a gapi.auth.authorize() call. function handleAuthResult(authResult) { if (authResult) { // Authorization was successful. Hide authorization prompts and show // content that should be visible after authorization succeeds. $('.pre-auth').hide(); $('.post-auth').show(); loadAPIClientInterfaces(); } else { // Authorization was unsuccessful. Show content related to prompting for // authorization and hide content that should be visible if authorization // succeeds. $('.post-auth').hide(); $('.pre-auth').show(); // Make the #login-link clickable. Attempt a non-immediate OAuth 2.0 // client flow. The current function is called when that flow completes. $('#login-link').click(function() { gapi.auth.authorize({ client_id: OAUTH2_CLIENT_ID, scope: OAUTH2_SCOPES, immediate: false }, handleAuthResult); }); } } // Load the client interfaces for the YouTube Analytics and Data APIs, which // are required to use the Google APIs JS client. More info is available at // http://code.google.com/p/google-api-javascript-client/wiki/GettingStarted#Loading_the_Client function loadAPIClientInterfaces() { gapi.client.load('youtube', 'v3', function() { gapi.client.load('youtubeAnalytics', 'v1', function() { // After both client interfaces load, use the Data API to request // information about the authenticated user's channel. getUserChannel(); }); }); } // Call the Data API to retrieve information about the currently // authenticated user's YouTube channel. function getUserChannel() { // Also see: https://developers.google.com/youtube/v3/docs/channels/list var request = gapi.client.youtube.channels.list({ // Setting the "mine" request parameter's value to "true" indicates that // you want to retrieve the currently authenticated user's channel. mine: true, part: 'id,contentDetails' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { // We need the channel's channel ID to make calls to the Analytics API. // The channel ID value has the form "UCdLFeWKpkLhkguiMZUp8lWA". channelId = response.items[0].id; // Retrieve the playlist ID that uniquely identifies the playlist of // videos uploaded to the authenticated user's channel. This value has // the form "UUdLFeWKpkLhkguiMZUp8lWA". var uploadsListId = response.items[0].contentDetails.relatedPlaylists.uploads; // Use the playlist ID to retrieve the list of uploaded videos. getPlaylistItems(uploadsListId); } }); } // Call the Data API to retrieve the items in a particular playlist. In this // example, we are retrieving a playlist of the currently authenticated user's // uploaded videos. By default, the list returns the most recent videos first. function getPlaylistItems(listId) { // See https://developers.google.com/youtube/v3/docs/playlistitems/list var request = gapi.client.youtube.playlistItems.list({ playlistId: listId, part: 'snippet' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { if ('items' in response) { // The jQuery.map() function iterates through all of the items in // the response and creates a new array that only contains the // specific property we're looking for: videoId. var videoIds = $.map(response.items, function(item) { return item.snippet.resourceId.videoId; }); // Now that we know the IDs of all the videos in the uploads list, // we can retrieve information about each video. getVideoMetadata(videoIds); } else { displayMessage('There are no videos in your channel.'); } } }); } // Given an array of video IDs, this function obtains metadata about each // video and then uses that metadata to display a list of videos. function getVideoMetadata(videoIds) { // https://developers.google.com/youtube/v3/docs/videos/list var request = gapi.client.youtube.videos.list({ // The 'id' property's value is a comma-separated string of video IDs. id: videoIds.join(','), part: 'id,snippet,statistics' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { // Get the jQuery wrapper for the #video-list element before starting // the loop. var videoList = $('#video-list'); $.each(response.items, function() { // Exclude videos that do not have any views, since those videos // will not have any interesting viewcount Analytics data. if (this.statistics.viewCount == 0) { return; } var title = this.snippet.title; var videoId = this.id; // Create a new <li> element that contains an <a> element. // Set the <a> element's text content to the video's title, and // add a click handler that will display Analytics data when invoked. var liElement = $('<li>'); var aElement = $('<a>'); // Setting the href value to '#' ensures that the browser renders the // <a> element as a clickable link. aElement.attr('href', '#'); aElement.text(title); aElement.click(function() { displayVideoAnalytics(videoId); }); // Call the jQuery.append() method to add the new <a> element to // the <li> element, and the <li> element to the parent // list, which is identified by the 'videoList' variable. liElement.append(aElement); videoList.append(liElement); }); if (videoList.children().length == 0) { // Display a message if the channel does not have any viewed videos. displayMessage('Your channel does not have any videos that have been viewed.'); } } }); } // This function requests YouTube Analytics data for a video and displays // the results in a chart. function displayVideoAnalytics(videoId) { if (channelId) { // To use a different date range, modify the ONE_MONTH_IN_MILLISECONDS // variable to a different millisecond delta as desired. var today = new Date(); var lastMonth = new Date(today.getTime() - ONE_MONTH_IN_MILLISECONDS); var request = gapi.client.youtubeAnalytics.reports.query({ // The start-date and end-date parameters must be YYYY-MM-DD strings. 'start-date': formatDateString(lastMonth), 'end-date': formatDateString(today), // At this time, you need to explicitly specify channel==channelId. // See https://developers.google.com/youtube/analytics/v1/#ids ids: 'channel==' + channelId, dimensions: 'day', sort: 'day', // See https://developers.google.com/youtube/analytics/v1/available_reports // for details about the different filters and metrics you can request // if the "dimensions" parameter value is "day". metrics: 'views', filters: 'video==' + videoId }); request.execute(function(response) { // This function is called regardless of whether the request succeeds. // The response contains YouTube Analytics data or an error message. if ('error' in response) { displayMessage(response.error.message); } else { displayChart(videoId, response); } }); } else { // The currently authenticated user's channel ID is not available. displayMessage('The YouTube channel ID for the current user is not available.'); } } // This boilerplate code takes a Date object and returns a YYYY-MM-DD string. function formatDateString(date) { var yyyy = date.getFullYear().toString(); var mm = padToTwoCharacters(date.getMonth() + 1); var dd = padToTwoCharacters(date.getDate()); return yyyy + '-' + mm + '-' + dd; } // If number is a single digit, prepend a '0'. Otherwise, return the number // as a string. function padToTwoCharacters(number) { if (number < 10) { return '0' + number; } else { return number.toString(); } } // Call the Google Chart Tools API to generate a chart of Analytics data. function displayChart(videoId, response) { if ('rows' in response) { hideMessage(); // The columnHeaders property contains an array of objects representing // each column's title -- e.g.: [{name:"day"},{name:"views"}] // We need these column titles as a simple array, so we call jQuery.map() // to get each element's "name" property and create a new array that only // contains those values. var columns = $.map(response.columnHeaders, function(item) { return item.name; }); // The google.visualization.arrayToDataTable() function wants an array // of arrays. The first element is an array of column titles, calculated // above as "columns". The remaining elements are arrays that each // represent a row of data. Fortunately, response.rows is already in // this format, so it can just be concatenated. // See https://developers.google.com/chart/interactive/docs/datatables_dataviews#arraytodatatable var chartDataArray = [columns].concat(response.rows); var chartDataTable = google.visualization.arrayToDataTable(chartDataArray); var chart = new google.visualization.LineChart(document.getElementById('chart')); chart.draw(chartDataTable, { // Additional options can be set if desired as described at: // https://developers.google.com/chart/interactive/docs/reference#visdraw title: 'Views per Day of Video ' + videoId }); } else { displayMessage('No data available for video ' + videoId); } } // This helper method displays a message on the page. function displayMessage(message) { $('#message').text(message).show(); } // This helper method hides a previously displayed message on the page. function hideMessage() { $('#message').hide(); } })();
Python
The code sample below calls the API's reports.query
method to retrieve YouTube Analytics data. By default, the report retrieves the top 10 videos based on viewcounts, and it returns several metrics for those videos, sorting the results in reverse order by viewcount. By setting command line parameters, you can use the same code to retrieve other reports as well.
This example uses the Python client library.
#!/usr/bin/python from datetime import datetime, timedelta import httplib2 import os import sys from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data and YouTube Analytics # APIs for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # https://developers.google.com/youtube/v3/guides/authentication # For more information about the client_secrets.json file format, see: # https://developers.google.com/api-client-library/python/guide/aaa_client_secrets CLIENT_SECRETS_FILE = "client_secrets.json" # These OAuth 2.0 access scopes allow for read-only access to the authenticated # user's account for both YouTube Data API resources and YouTube Analytics Data. YOUTUBE_SCOPES = ["https://www.googleapis.com/auth/youtube.readonly", "https://www.googleapis.com/auth/yt-analytics.readonly"] YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" YOUTUBE_ANALYTICS_API_SERVICE_NAME = "youtubeAnalytics" YOUTUBE_ANALYTICS_API_VERSION = "v1" # This variable defines a message to display if the CLIENT_SECRETS_FILE is # missing. MISSING_CLIENT_SECRETS_MESSAGE = """ WARNING: Please configure OAuth 2.0 To make this sample run you will need to populate the client_secrets.json file found at: %s with information from the Developers Console https://console.developers.google.com/ For more information about the client_secrets.json file format, please visit: https://developers.google.com/api-client-library/python/guide/aaa_client_secrets """ % os.path.abspath(os.path.join(os.path.dirname(__file__), CLIENT_SECRETS_FILE)) def get_authenticated_services(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=" ".join(YOUTUBE_SCOPES), message=MISSING_CLIENT_SECRETS_MESSAGE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: credentials = run_flow(flow, storage, args) http = credentials.authorize(httplib2.Http()) youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=http) youtube_analytics = build(YOUTUBE_ANALYTICS_API_SERVICE_NAME, YOUTUBE_ANALYTICS_API_VERSION, http=http) return (youtube, youtube_analytics) def get_channel_id(youtube): channels_list_response = youtube.channels().list( mine=True, part="id" ).execute() return channels_list_response["items"][0]["id"] def run_analytics_report(youtube_analytics, channel_id, options): # Call the Analytics API to retrieve a report. For a list of available # reports, see: # https://developers.google.com/youtube/analytics/v1/channel_reports analytics_query_response = youtube_analytics.reports().query( ids="channel==%s" % channel_id, metrics=options.metrics, dimensions=options.dimensions, start_date=options.start_date, end_date=options.end_date, max_results=options.max_results, sort=options.sort ).execute() print "Analytics Data for Channel %s" % channel_id for column_header in analytics_query_response.get("columnHeaders", []): print "%-20s" % column_header["name"], print for row in analytics_query_response.get("rows", []): for value in row: print "%-20s" % value, print if __name__ == "__main__": now = datetime.now() one_day_ago = (now - timedelta(days=1)).strftime("%Y-%m-%d") one_week_ago = (now - timedelta(days=7)).strftime("%Y-%m-%d") argparser.add_argument("--metrics", help="Report metrics", default="views,comments,favoritesAdded,favoritesRemoved,likes,dislikes,shares") argparser.add_argument("--dimensions", help="Report dimensions", default="video") argparser.add_argument("--start-date", default=one_week_ago, help="Start date, in YYYY-MM-DD format") argparser.add_argument("--end-date", default=one_day_ago, help="End date, in YYYY-MM-DD format") argparser.add_argument("--max-results", help="Max results", default=10) argparser.add_argument("--sort", help="Sort order", default="-views") args = argparser.parse_args() (youtube, youtube_analytics) = get_authenticated_services(args) try: channel_id = get_channel_id(youtube) run_analytics_report(youtube_analytics, channel_id, args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
Ruby
The code sample below calls the API's reports.query
method to retrieve YouTube Analytics data. By default, the report retrieves the top 10 videos based on viewcounts, and it returns several metrics for those videos, sorting the results in reverse order by viewcount. By setting command line parameters, you can use the same code to retrieve other reports as well.
This example uses the Ruby client library.
#!/usr/bin/ruby require 'rubygems' gem 'google-api-client', '>0.7' require 'google/api_client' require 'google/api_client/client_secrets' require 'google/api_client/auth/file_storage' require 'google/api_client/auth/installed_app' require 'trollop' # These OAuth 2.0 access scopes allow for read-only access to the authenticated # user's account for both YouTube Data API resources and YouTube Analytics Data. YOUTUBE_SCOPES = ['https://www.googleapis.com/auth/youtube.readonly', 'https://www.googleapis.com/auth/yt-analytics.readonly'] YOUTUBE_API_SERVICE_NAME = 'youtube' YOUTUBE_API_VERSION = 'v3' YOUTUBE_ANALYTICS_API_SERVICE_NAME = 'youtubeAnalytics' YOUTUBE_ANALYTICS_API_VERSION = 'v1' def get_authenticated_services client = Google::APIClient.new( :application_name => $PROGRAM_NAME, :application_version => '1.0.0' ) youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION) youtube_analytics = client.discovered_api(YOUTUBE_ANALYTICS_API_SERVICE_NAME, YOUTUBE_ANALYTICS_API_VERSION) file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json") if file_storage.authorization.nil? client_secrets = Google::APIClient::ClientSecrets.load flow = Google::APIClient::InstalledAppFlow.new( :client_id => client_secrets.client_id, :client_secret => client_secrets.client_secret, :scope => YOUTUBE_SCOPES ) client.authorization = flow.authorize(file_storage) else client.authorization = file_storage.authorization end return client, youtube, youtube_analytics end def main now = Time.new.to_i seconds_in_day = 60 * 60 * 24 seconds_in_week = seconds_in_day * 7 one_day_ago = Time.at(now - seconds_in_day).strftime('%Y-%m-%d') one_week_ago = Time.at(now - seconds_in_week).strftime('%Y-%m-%d') opts = Trollop::options do opt :metrics, 'Report metrics', :type => String, :default => 'views,comments,favoritesAdded,favoritesRemoved,likes,dislikes,shares' opt :dimensions, 'Report dimensions', :type => String, :default => 'video' opt 'start-date', 'Start date, in YYYY-MM-DD format', :type => String, :default => one_week_ago opt 'end-date', 'Start date, in YYYY-MM-DD format', :type => String, :default => one_day_ago opt 'start-index', 'Start index', :type => :int, :default => 1 opt 'max-results', 'Max results', :type => :int, :default => 10 opt :sort, 'Sort order', :type => String, :default => '-views' end client, youtube, youtube_analytics = get_authenticated_services begin # Retrieve the channel resource for the authenticated user's channel. channels_response = client.execute!( :api_method => youtube.channels.list, :parameters => { :mine => true, :part => 'id' } ) channels_response.data.items.each do |channel| opts[:ids] = "channel==#{channel.id}" # Call the Analytics API to retrieve a report. For a list of available # reports, see: # https://developers.google.com/youtube/analytics/v1/channel_reports analytics_response = client.execute!( :api_method => youtube_analytics.reports.query, :parameters => opts ) puts "Analytics Data for Channel #{channel.id}" analytics_response.data.columnHeaders.each do |column_header| printf '%-20s', column_header.name end puts analytics_response.data.rows.each do |row| row.each do |value| printf '%-20s', value end puts end end rescue Google::APIClient::TransmissionError => e puts e.result.body end end main
Try it!
Use the API Explorer to call this API and see the API request and response.