API Reference

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.

  • To request data for a YouTube user, set the ids parameter value to channel==USER_ID, where USER_ID identifies the currently authenticated YouTube user.
  • To request data for a YouTube CMS content owner, set the ids parameter value to contentOwner==OWNER_NAME, where OWNER_NAME is the CMS user ID for the user.

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.

  • Valid values: json,csv
  • Default value: json
callback Callback function.
  • Name of the JavaScript callback function that handles the response.
  • Used in JavaScript JSON-P requests.
fields Selector specifying a subset of fields to include in the response.
  • Use for better performance.
key API key. (REQUIRED*)

See the Developers Console.
  • *Required unless you provide an OAuth 2.0 token.
  • Your API key identifies your project and provides you with API access, quota, and reports.
  • Obtain your project's API key from the Developers Console.
prettyPrint

Returns response with indentations and line breaks.

  • Returns the response in a human-readable format if true.
  • Default value: true.
  • When this is false, it can reduce the response payload size, which might lead to better performance in some environments.
quotaUser Alternative to userIp.
  • Lets you enforce per-user quotas from a server-side application even in cases when the user's IP address is unknown. This can occur, for example, with applications that run cron jobs on App Engine on a user's behalf.
  • You can choose any arbitrary string that uniquely identifies a user, but it is limited to 40 characters.
  • Overrides userIp if both are provided.
  • Learn more about capping usage.
userIp IP address of the end user for whom the API call is being made.
  • Lets you enforce per-user quotas when calling the API from a server-side application.
  • Learn more about capping usage.

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:

JSON
{
  "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.

CSV
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.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.