Friday 5 February 2016

Google Analytics api c# example complete reference

Well recently i got a project in which i had to work with GoogleAnalytics API.
Core requirement was to get new visitors and returning visitor of site with in certain period of time with
filters. Filters like page referrer or page which contains few request parameter in URL.

I am much familiar with .net technology so i was keen to get any complete demo on web so o could complete this task in few hours.
After spending one hour on web i found it is too easy to call Google Analytic Api. I follow google's steps and got successfully my record data.
Here i am going to list all steps which is required to accomplish this task.

Step 1.
You must have google account and Google Analytic account.
Make sure you are able to track users and page view using google analytic web. So you will sure that your analytic code is working for a site.
And you have sufficient data to test it out.

Step 2.
Go to Google developer console to manage your API.
There you can select any existing project in drop-down or you can create a new one.

An easy steps are given in below picture to enable Google Analytics Api for a project.
Just enable them.

Step 3.
For a particular project( that you have created, for enabled analytics api) you need to create a service account in order to get
credentials which you will further use in your application.
Just follow the steps given in figure and get Json downloaded with private-key and other details.

"type": "service_account",
"project_id": "my project name",
"private_key_id": "kjdhslgf879dfg7dfg7hgdfhgdfghdfgdfg",
"private_key": "-----BEGIN PRIVATE KEY-----\ndsfsdf;ldsfdsf.........ybdQ=\n-----END PRIVATE KEY-----\n",
"client_email": "",
"client_id": "1163453495872345454961045",
"auth_uri": "",
"token_uri": "",
"auth_provider_x509_cert_url": "",
"client_x509_cert_url": ""

Step 4.
Once you would have service account for a project. You will have "client_email" which you will use to intergrate with
analytics accounts. You need to grant access to service email.
Log into Google Analytics.
After login click on the Admin button on the top of screen.
Select an account/site/blogger you would like your service account to be able to access.
Click on "User Management" under the account section.
Enter the email address that was generated for your service account and give it read and analyze permission.
Now your client_email ( will have access of your analytics account.

Step 5.
Final step in which you will integrate all with code in C#.
I am going to use simple console application so that i could complete all quickly. Because i know you are very annaxious about code.
So i am going to create a console application in which we will get some account related informationa and analytics data for an
account with in time period using some filter. Filter would be based on URL match.
Create a console application.
Run package manager console.
Type "Install-Package Google.Apis.Analytics.v3" and OK

It will install Google.Apis.Analytics.v3 sdk in your application.
For more information Go to google-apis-packages

Make sure you added all given namespace in your application.
using Google.Apis.Analytics.v3;
using Google.Apis.Analytics.v3.Data;
using Google.Apis.Services;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Auth.OAuth2;
using System.Collections.Generic;

Complete Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Google.Apis.Analytics.v3;
using Google.Apis.Analytics.v3.Data;
using Google.Apis.Services;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Auth.OAuth2;
using System.Collections.Generic;
namespace Google_Analytics_API
    class Program
        static void Main(string[] args)
            //that you got in .JSON file
            var privatekey = "-----BEGIN PRIVATE KEY-----\n-------Replace with your key -----dQ=\n-----END PRIVATE KEY-----\n";
            var accountEmailAddress = "--your project--@--your";
                GoogleAnalyticsAPI api = new GoogleAnalyticsAPI(privatekey, accountEmailAddress);
                var profiles = api.GetAvailableProfiles();
                foreach (var profile in profiles)
                    Console.WriteLine("AccountId:" + profile.AccountId);
                    Console.WriteLine("Name:" + profile.Name);
                    Console.WriteLine("WebsiteUrl:" + profile.WebsiteUrl);
//filter =;ga:pagePath=~score
                //more Dimensions & Metrics at
                //Explore query at
                // api.GetAnalyticsData("xxxxxxx" my analytics account id, new string[] { "ga:userType" } Dimensions , new string[] { "ga:newUsers" } Metrics , new string[] { "ga:pagePath=~ref=date" } URL filter, DateTime.Now.AddMonths(-1) month before, DateTime.Now today);
                var data = api.GetAnalyticsData("xxxxxxx", new string[] { "ga:userType" }, new string[] { "ga:newUsers" }, new string[] { "ga:pagePath=~ref=date" }, DateTime.Now.AddMonths(-1), DateTime.Now);
                foreach (var item in data.Rows)
                    foreach (var item1 in item)
            catch (Exception exc)
    public class GoogleAnalyticsAPI
        public AnalyticsService Service { get; set; }
        public GoogleAnalyticsAPI(string privatekey, string accountEmailAddress)
            //var certificate = new X509Certificate2(privatekey, "notasecret", X509KeyStorageFlags.Exportable);
            var credentials = new ServiceAccountCredential(
               new ServiceAccountCredential.Initializer(accountEmailAddress)
                   Scopes = new[] { AnalyticsService.Scope.AnalyticsReadonly }
            Service = new AnalyticsService(new BaseClientService.Initializer()
                HttpClientInitializer = credentials,
                ApplicationName = "WorthlessVariable"
        public AnalyticDataPoint GetAnalyticsData(string profileId, string[] dimensions, string[] metrics, string[] filters, DateTime startDate, DateTime endDate)
            AnalyticDataPoint data = new AnalyticDataPoint();
            if (!profileId.Contains("ga:"))
                profileId = string.Format("ga:{0}", profileId);
            //Make initial call to service.
            //Then check if a next link exists in the response,
            //if so parse and call again using start index param.
            GaData response = null;
                int startIndex = 1;
                if (response != null && !string.IsNullOrEmpty(response.NextLink))
                    Uri uri = new Uri(response.NextLink);
                    var paramerters = uri.Query.Split('&');
                    string s = paramerters.First(i => i.Contains("start-index")).Split('=')[1];
                    startIndex = int.Parse(s);
                var request = BuildAnalyticRequest(profileId, dimensions, metrics, filters, startDate, endDate, startIndex);
                response = request.Execute();
                data.ColumnHeaders = response.ColumnHeaders;
            } while (!string.IsNullOrEmpty(response.NextLink));
            return data;
        private DataResource.GaResource.GetRequest BuildAnalyticRequest(string profileId, string[] dimensions, string[] metrics, string[] filters,
                                                                            DateTime startDate, DateTime endDate, int startIndex)
            DataResource.GaResource.GetRequest request = Service.Data.Ga.Get(profileId, startDate.ToString("yyyy-MM-dd"),
                                                                                endDate.ToString("yyyy-MM-dd"), string.Join(",", metrics));
            request.Dimensions = string.Join(",", dimensions);
            request.StartIndex = startIndex;
            request.Filters = string.Join(",", filters);
            return request;
        public IList<Profile> GetAvailableProfiles()
            var response = Service.Management.Profiles.List("~all", "~all").Execute();
            return response.Items;
        public class AnalyticDataPoint
            public AnalyticDataPoint()
                Rows = new List<IList<string>>();
            public IList<GaData.ColumnHeadersData> ColumnHeaders { get; set; }
            public List<IList<string>> Rows { get; set; }

Error and solution:

Enter valid accountEmailAddres

Error:"invalid_grant", Description:"", Uri:""
solution: Enter valid accountEmailAddress.

User does not have any Google Analytics account

User does not have any Google Analytics account. [403]
Errors [ Message[User does not have any Google Analytics account.] Location[ - ]
Reason[insufficientPermissions] Domain[global]
Solution: Service account email must have access of analytics account under user management in analytics panel.

Unknown dimension(s): ga:xxxx] Location

Unknown dimension(s): ga:xxxx [400]
Errors [Message[Unknown dimension(s): ga:xxxx] Location[ - ] Reason[badRequest] Domain[global]
Solution: Use valid Dimensions & Metrics like (ga:userType, ga:newUsers)
For more Dimensions & Metrics go to