Using the Google Analytics API with PHP: Logging In

By Younes Rafie

How to Use Google Analytics API with PHP

In this series, we’re going to see how we can use the Google Analytics API to interact with our Google Analytics data via PHP. We’ll be using Laravel on Homestead Improved, but you can follow along with any framework on any development environment – Laravel + HI is simply the fastest and recommended starting point.


To be able to follow along, you need to have a Google Analytics account which you can get from the Google Analytics page.

You also need to be familiar with the basic usage of the Google Analytics dashboard.

Google Analytics Dashboard

What are we going to build?

In this article we’re going to build an app that looks like Google Analytics Explorer, but to make it short, we’re going to limit the functionality and discuss how we can extend our demo.

Google Analytics API


The Google Analytics API is divided into a number of APIs. We use each API depending on our needs:

  • Management API:
    Provides access to Google Analytics configuration data like accounts, properties, views, goals…

  • Metadata API:
    Provides access to the list of columns (Dimensions, Metrics) so that we don’t need to hard code them inside our app.

  • Core Reporting API:
    Provides access to dashboard data, and most of the tasks are available through this API.

  • Real Time Reporting API:
    Gives you access to real time data, like the one on your Google Analytics dashboard. At the time of this writing, this API is in beta.

Real Time Dashboard

  • Embed API:
    This API allows you to create and embed dashboards in your website using javascript.

  • MCF Reporting API:
    Multi-Channel Funnels Reporting API enables you to request Multi-Channel Funnels data for an authenticated user, which means you can query data from multiple sources and use it for your own statistics.

In this article, we’re going to be focused on the Management API, Metadata API and Core reporting API. First, let’s start with some basic usage.

Basic Usage

To start using the API, we need to create a new project on the Google Developers Console.
Google Developers Console

You project dashboard should look like this:
Google Console Project Dashboard

Now we have a project ready to use any of the provided Google services. Because we intend to use Google Analytics API, we need to activate it.

When you want to use a Google API you need to provide two things:

1) Your API credentials.
2) Your developer keys.

Go to menu, API & AUTH, select “APIs” and enable Analytics API
Google Console APIs

Under the API & AUTH menu, select the Credentials link, and select Create new client ID.

Select Web Application for our app, then enter your website URL and your login redirect page URL. Because we will be using Laravel in our demo, you can use localhost:8000 for the development phase, and don’t forget to change https to http in your URL.

Google Console Credentials

At the bottom of the page, you have the Public API access. We need to create a new access key.

1) choose the Browser Key option for our demo.
2) on the http referrers box, you can leave the value empty to accept requests from anywhere, or specify your domain address.

Now we are ready to start playing around with the API.

Limits and Quotas

When working with Google Analytics API, we are limited to a number of requests per day, per second, etc. You can read the full doc page for more information.

Project Configuration

I will assume that you already know how to set up a new Laravel project on Homestead Improved.

We need to require "google/api-client": "dev-master" in our composer.json and update the dependencies.

In my app/config/, I will create a file called analytics.php where I can put my configuration.

return [
    'app_name'          => 'Your app name', //Can be anything
    'client_id'         => 'Your ID',//can be found on the credentials page
    'client_secret'     => 'Your secret ID',//on the credentials page
    'api_key'           => 'Your key'//can be found at the bottom of your credentials page

To keep things separated, i will create a folder named src inside my app directory and create a file called GA_Service.php where I can put all request logic.

// app/src/GA_Service.php

class GA_Service{

Trying to access this class somewhere in our code will result in a Class not found exception, so we can take advantage of composer autoloading feature.

In the composer.json file, go to the autoload classmap section and add our path to the list.

// composer.json

    "classmap": [

Don’t forget to run composer dump-autoload after saving the changes.

By default, Laravel includes a file called HomeController.php in the app/controllers directory. We will use it as our main app controller.

Back to the GA_Service class; to communicate with Google APIs we use a class called Google_Client. In our constructor, we will create a new instance and start filling the necessary parameters.

public function __construct( Google_Client $client ){
	$this->client = $client;

private function init(){
		$this->client->setClientId(Config::get('analytics.client_id') );

Instead of instantiating the class inside the constructor, we pass it as a parameter and let Laravel’s IoC resolve it for us. For more details, be sure to check this article out.

The first three lines of the init method are self explanatory; the Config::get method grabs the configuration from the analytics.php file.

The redirect URI method is the redirection URL to be used after Google verification and it should match the one registered previously on the Google Console Dashboard.

The setScope method is where we specify the access level needed for our app:

After setting up our google client we’re going to set our login process:

// app/src/GA_Service.php
public function isLoggedIn(){
	if (isset($_SESSION['token'])) {
	  return true;

	return $this->client->getAccessToken();

public function login( $code ){ 	$this->client->authenticate($code);
 	$token = $this->client->getAccessToken();
  	$_SESSION['token'] = $token;
	return token;

public function getLoginUrl(){
	$authUrl = $this->client->createAuthUrl();
	return $authUrl;
  • isLoggedIn: return true if the user has an access token to be used.
  • getLoginUrl: if the user is not logged in, we get an authentication URL.
  • login: we have already set a redirect URL on the Google API Dashboard, we receive back a $_GET['code'] parameter that we can use to get a token for our requests.

Let’s use what we’ve got for now. Inside our controller:

// app/controllers/HomeController.php

class HomeController extends BaseController {
	private $ga;

	public function __construct( GA_Service $ga ){
		$this->ga = $ga;

	public function index()
		if( $this->ga->isLoggedIn() ){
			return 'Show home page';
            $url = $this->ga->getLoginUrl();
			return View::make('login', [ 'url' => $url ]);



// app/routes.php

Route::get('/', 'HomeController@index');
Route::get('/login', 'HomeController@login');

We inject GA_Service into our controller, and when the user hits our index route, we check if he’s logged in. If not, we generate the authentication URL.

App permission request

After accepting the request permission, you will be redirected to the login page with the code parameter.

// app/controllers/HomeController.php
public function login(){
	if( Input::has('code') ){
		$code = Input::get('code');
		return "Go to the home <a href='/'>page</a>";
		return "Invalide request parameters";

In our login function, we test if the code exists. If so, we pass it to our GA_Service::login function so we can authenticate and get a token for the user.

Wrapping up

In this part we discussed the basic usage of Google Analytics API. At this point, we have a token that we can use to query the list of APIs, and in the next part, we’re going to continue building our demo app using the Google Analytics API.

  • manuel raynaud

    With the Measurement protocol ( you can do more or less the same thing, without creating an application. You only need a tracking ID (UA-XXXXX-X) and some curl.

    Some good lib exist for using it in php, like this one : based on Guzz

  • sebastiaan hilbers

    Why use static Config from out of nowhere? Why use classmap instead of proper namespaces?

  • Adrian Voicu

    Why would you assume that I “already know how to set up a new Laravel project on Homestead Improved”, and where in the introduction of this tutorial did you mention that you will use Laravel? Would have been nice for you to mention that, before we get to the middle of the tutorial.

    • Bruno Skvorc

      Laravel is kind of the simplest starting point, and Homestead Improved is the simplest starting point for *that* starting point. You can do this in any framework and on any development environment, but this combination is the quickest to get started with. We’ll amend the post to reflect that.

      • Roy

        A tutorial should be about doing things properly, not doing them quickly. Take the extra time to walk through the content you’re meant to be teaching rather than trying to cut corners and introduce other, irrelevant technologies.

        • Bruno Skvorc

          Explaining an installation procedure for PHP and Apache/Nginx would have been introducing other, irrelevant technologies. Any dev worth his salt will be using some kind of virtual environment these days for an isolated development experience, and the HI box is the absolute simplest way to getting there, while using the same technologies most devs today use for PHP development and deployment – Ubuntu LTS with Nginx and MySQL, along with a recent version of PHP.

          The “Homestead Improved” quick tip can be consumed in 5 minutes and gets you an environment identical to every other reader’s, so everyone can be using the same context and help each other out in development and deployment problems, if any. As far as properly vs quickly goes, I’d go as far as saying that this is the most proper way of doing it – using a virtual environment for a new PHP app and having dev/prod parity by default.

          I’m open to suggestions, though – what do you think we should change specifically? What do you dislike in this case? Would you rather we just skip to the code, without even a mention of the environment, or should we set it up manually, from Apache/Nginx installation and vhosts to deployment? Let me know. If anyone else feels the same, please, chime in, I’m interested in seeing the public’s perception.

          • Roy

            Unless the environment is specifically relevant to the tutorial then don’t bother mentioning it. You may feel a virtual environment is superior these days, but that doesn’t mean every dev either agrees with you or is using the same setup.

            For example, I often simply set up a simple localhost environment for tinkering around with things like these – some might prefer to spin up something using Vagrant and maybe others will like HI. Why are you making such a decision when it’s irrelevant to the tutorial? I do indeed think you should just skip to the code – if you need any specific environment configuration then just say so at the beginning and move on to the actual tutorial.

          • Bruno Skvorc

            HI *is* a Vagrant box, but I see what you mean. I’ve got an idea to get around this that would make everyone happy in the future, thanks for the input.

  • Roy

    I really recommend when you do tutorials like this that you use a vanilla PHP project, get rid of things like Laravel and Homestead. They’re utterly irrelevant to the tutorial and only serve to get in the way of what you’re trying to teach.

    • canobeano


  • Fauxide

    Block8 removed their php Google-API :(

  • Ärafath Mohamed

    i get this error

    update [–prefer-source] [–prefer-dist] [–dry-run] [–dev] [–no-dev] [–lock] [–no-plugins] [–no-custom-installers] [–no-scripts] [–no-progress] [–with

    -dependencies] [-v|vv|vvv|–verbose] [-o|–optimize-autoloader] [–ignore-platform-reqs] [packages1] … [packagesN]

    • younesrafie

      do you get this error while updating composer?

      • Ärafath Mohamed


    • younesrafie

      can you please post the require section of your composer.json!

      • Ärafath Mohamed

        here my require section
        “require”: {
        “laravel/framework”: “4.2.*”,
        “google/api-client”: “dev-master”

        • younesrafie

          can you change “google/api-client”: “dev-master” to “google/apiclient”: “dev-master” and try again

          • Ärafath Mohamed

            ya.its worked.thanks you :)

    • Ärafath Mohamed

      when i reuest . i get class error and i change Google_AnalyticsService to Google_Service_Analytics this. and error fix. now i getting

      Google_Service_Exception (401)

      Error calling GET (401) Login Required

      • John Rau

        I am getting this error too – did you ever find out how to fix it?

  • Bart Heideman

    Hi Younes, thx for this tutorial!

    I get the following error: View [login] not found. Did I miss something?



    • Bart Heideman

      Ok, got it already;)

      In HomeController I removed this line:
      return View::make(‘login’, [ ‘url’ => $url ]);

      and added this line instead:
      return Redirect::to($url);

  • Ricky

    Brilliant tutorial, helped me a lot. Thanks for sharing.

  • vafrcor

    Good Tutorial, but Mr. Younes forgot to show his “composer.json” that this tutorial need Google API Package + Forgot to write about “login” view.
    I implement this tutorial using Laravel 4.1.28 + Apache (with vhost for my local host domain) and it works (after i completed about requirement).

    • younesrafie

      Glad you like it. I can’t past all the code here, but i provided a link to the final result on github so that you can see the full details :)

  • younesrafie

    Thanks, Glad it helped :)

  • OzanKurt96

    Update please… Nothing works right now… :/

  • Akil Sree

    Iam getting this error Error fetching OAuth2 access token, message: ‘invalid_grant: Code was already redeemed.’ while refreshing the page. How to fix this?

    • younesrafie

      When the server gives you the code to exchange for a token, you are refreshing this page which causes the grant error since this code has already been used. I think you have a redirection problem maybe.

  • Mario

    In composer should be added “google/apiclient”: “1.0.*@beta”. Please fix the post. Very good tutorial!

  • Ozan Kurt

    Deprecated content?

  • Valeria

    Hi, I need to integrate GA API into WordPress. I’ve been looking for a while already, but still can’t find a solution working for me. Could you advise any tutorial that would allow to retrieve a few GA values without full access to the server (I’m on shared hosting) and without using curl (I’m on Windows, it’s a problem)? Thank you in advance.



Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in PHP, once a week, for free.