The YouTube Analytics API provides a single method that lets you retrieve different Analytics reports. Each request must use query parameters to specify a channel ID or content owner, a start date, an end date, and at least one metric. You may also provide additional query parameters, such as dimensions, filters, or sorting instructions.
The Reports document provides general information about the types of reports you can retrieve and also explains how YouTube calculates your quota usage. In addition, the following documents identify the specific reports you can retrieve, the metrics you can include in each report, and your options for filtering the report data:
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.)
Parameter Name | Value | Description |
---|---|---|
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 | ||
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.
|
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}, ... ] ] }
Property Name | Value | Description |
---|---|---|
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 will begin with the dimensions specified in the API request, which will be followed by the metrics specified in the API request. The order of both dimensions and metrics will match the ordering in the API request. For example, if the API request contains the parameters dimensions=ageGroup,gender&metrics=viewerPercentage , the API response will return 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.
Java
This example uses the Java client library.
-
YouTubeAnalyticsReports.java
package com.google.api.services.samples.youtube.cmdline.youtube_analytics_cmdline_report_sample; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.math.BigDecimal; import java.util.List; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; import com.google.api.client.extensions.java6.auth.oauth2.FileCredentialStore; import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; 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.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; /** * Demo displaying YouTube metrics from a user's channel using the YouTube Data and YouTube * Analytics APIs. It also uses OAuth2 for authorization. * * @author Christoph Schwab-Ganser and Jeremy Walker */ public class YouTubeAnalyticsReports { /** Global instance of the HTTP transport. */ private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); /** Global instance of the JSON factory. */ private static final JsonFactory JSON_FACTORY = new JacksonFactory(); /** Global instance of Youtube object to make general YouTube API requests. */ private static YouTube youtube; /** Global instance of YoutubeAnalytics object to make analytic API requests. */ private static YoutubeAnalytics analytics; /** * Authorizes the installed application to access user's protected YouTube data. * * @param scopes list of scopes needed to access general and analytic YouTube info. */ private static Credential authorize(List<String> scopes) throws Exception { // Load client secrets. GoogleClientSecrets clientSecrets = GoogleClientSecrets.load( JSON_FACTORY, YouTubeAnalyticsReports.class.getResourceAsStream("/client_secrets.json")); // Checks that the defaults have been replaced (Default = "Enter X here"). if (clientSecrets.getDetails().getClientId().startsWith("Enter") || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) { System.err.println( "Enter Client ID and Secret from https://code.google.com/apis/console/?api=youtube" + "into youtube-analytics-cmdline-report-sample/src/main/resources/client_secrets.json"); System.exit(1); } // Set up file credential store. FileCredentialStore credentialStore = new FileCredentialStore( new File(System.getProperty("user.home"), ".credentials/youtube-analytics-api-report.json"), JSON_FACTORY); // Set up authorization code flow. GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes) .setCredentialStore(credentialStore).build(); // Authorize. return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user"); } /** * Authorizes user, gets user's default channel via YouTube Data API, and gets/prints stats on * user's channel using the YouTube Analytics API. * * @param args command line args (not used). */ public static void main(String[] args) { // Scopes required to access YouTube general and analytics information. List<String> scopes = Lists.newArrayList( "https://www.googleapis.com/auth/yt-analytics.readonly", "https://www.googleapis.com/auth/youtube.readonly" ); try { Credential credential = authorize(scopes); // YouTube object used to make all non-analytic API requests. youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName("youtube-analytics-api-report-example") .build(); // YouTube object used to make all analytic API requests. analytics = new YoutubeAnalytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName("youtube-analytics-api-report-example") .build(); // Constructs request to get channel id for current user. YouTube.Channels.List channelRequest = youtube.channels().list("id,snippet"); channelRequest.setMine(true); channelRequest.setFields("items(id,snippet/title)"); ChannelListResponse channels = channelRequest.execute(); // List of channels associated with user. List<Channel> listOfChannels = channels.getItems(); // Grab default channel which is always 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(); } } /** * Returns the views and unique viewers per day. * * @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 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(); } /** * Returns the top video by views. * * @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(); } /** * Returns the demographics report * * @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 output from the API. 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(); } } }
-
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.google.api.services.samples.youtube.cmdline</groupId> <artifactId>YouTubeAnalyticsReport</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>YouTubeAnalyticsReport</name> <url>http://maven.apache.org</url> <properties> <project.youtube.analytics.version>v1-rev8-1.12.0-beta</project.youtube.analytics.version> <project.youtube.version>v3-rev16-1.12.0-beta</project.youtube.version> <project.http.version>1.12.0-beta</project.http.version> <project.oauth.version>1.12.0-beta</project.oauth.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <repositories> <repository> <id>google-api-services</id> <url>http://google-api-client-libraries.appspot.com/mavenrepo</url> </repository> </repositories> <dependencies> <!-- YouTube Analytics support --> <dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-youtubeAnalytics</artifactId> <version>${project.youtube.analytics.version}</version> </dependency> <!-- YouTube Data V3 support --> <dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-youtube</artifactId> <version>${project.youtube.version}</version> </dependency> <dependency> <groupId>com.google.http-client</groupId> <artifactId>google-http-client-jackson2</artifactId> <version>${project.http.version}</version> </dependency> <dependency> <groupId>com.google.oauth-client</groupId> <artifactId>google-oauth-client-jetty</artifactId> <version>${project.oauth.version}</version> </dependency> </dependencies> </project>
-
client_secrets.json
{ "installed": { "client_id": "Enter Client ID", "client_secret": "Enter Client Secret" } }
JavaScript
This example uses the JavaScript client library. The Building a Sample Application document walks you through the steps of building this application and discusses different portions of this code in more detail.
(function() { // Retrieve your client ID from the Google Developers Console at // https://cloud.google.com/console. 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
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://cloud.google.com/console. # 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://cloud.google.com/console 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
This example uses the Ruby client library.
#!/usr/bin/ruby require 'rubygems' require 'google/api_client' # The oauth/oauth_util code is not part of the official Ruby client library. # Download it from: # http://samples.google-api-ruby-client.googlecode.com/git/oauth/oauth_util.rb require 'oauth/oauth_util' require 'trollop' # This code assumes that there's a client_secrets.json file in your current directory, # which contains OAuth 2.0 information for this application, including client_id and # client_secret. You can acquire an ID/secret pair from the API Access tab on the # Google Developers Console <https://cloud.google.com/console> # For more information about using OAuth2 to access Google APIs, please visit: # <https://developers.google.com/accounts/docs/OAuth2> # For more information about the client_secrets.json file format, please visit: # <https://developers.google.com/api-client-library/python/guide/aaa_client_secrets> # Please ensure that you have enabled the YouTube Data & Analytics APIs for your project. # 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' 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 = Google::APIClient.new 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) auth_util = CommandLineOAuthHelper.new(YOUTUBE_SCOPES) client.authorization = auth_util.authorize() # 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
Try it!
Use the API Explorer to call this API and see the API request and response.