WordPress.com stats via API

Every site I maintain gets Jetpack installed with the Stats module activate. These stats are pretty basic. While they might not be as comprehensive as Google Analytics they are extremely powerful as they are accessible via the WordPress.com API.

WordPress.com Rest API is not WP Rest API

The WordPress.com Rest API is a product of Automatic. It’s a hidden gem and easily confused with the official WP Rest API project. In fact Automatic’s API has been around for a while long before the official project.

Use the Development Console while learning

Here are a few samples of stats you can pull from the WordPress.com Rest API using their development console.

Screen Shot 2016-09-25 at 5.52.18 AM.png
Stats for the month of July
Screen Shot 2016-09-25 at 5.57.52 AM.png
Recent daily views and visitors
Screen Shot 2016-09-25 at 1.33.06 PM.png
Recent monthly views and visitors using an older version of API

Being able to access stats via an API is crazy powerful

The following is a single php file, code below, which will loop through all sites connected via Jetpack and generate a simply dashboard of Stats. Getting authentication configured can be a little tricky however that a bit more then I’m covering here.

Screen Shot 2016-09-28 at 12.49.19 PM.png
Screen Shot 2016-09-28 at 12.50.05 PM.png
<html>
<head>
<title>Dashboard Stats</title>
</head><style>
 body {
    max-width: 600px;
    margin: auto;
    font-size: 16px;
    font-family: helvetica;
    padding: 30px 0px;
 }
 a {
     text-decoration: none;
     color: #1E447B;
     border-bottom: 1px solid #1E447B;
 }
 #controls {
    position: absolute;
    top: 0px;
    left: 0px;
    padding: 10px;
    border: 1px solid #eee;
    margin: 30px;
    border-radius: 13px;
    font-size: 12px;
 }
 #results div {
    padding: 0 0 7px 0;
    margin: 0 0 7px 0;
    border-bottom: 1px dashed #ccc;
    position: relative;
 }
 span.yearly {
     width: 100px;
     display: block;
     float: left;
     text-align: right;
     padding: 0 10px 0 0;
 }

 span.name {
     overflow: hidden;
     white-space: nowrap;
     text-overflow: ellipsis;
     width: 480px;
     display: block;
 }
 span.name small {
    font-size: 11px;
    position: relative;
    top: -2px;
    display: block;
    line-height: 11px;
 }
 span.months {
    display: none;
    padding-left: 111px;
    padding-top: 4px;
    font-size: 12px;
 }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$( document ).ready(function() {
    // Sort by count
    var $wrapper = $('#results');
    $wrapper.find('div').sort(function (a, b) {
        return +b.dataset.count - +a.dataset.count;
    }).appendTo( $wrapper );

    $('#more').click(function () {
        if (this.checked) {
            $(".months").css('display','block');
        } else {
            $(".months").hide();
        }
    });
    $('#sort').click(function () {
        if (this.checked) {
            // Sort by yearly estimate
            var $wrapper = $('#results');
            $wrapper.find('div').sort(function (a, b) {
                return +b.dataset.yearlyestimate - +a.dataset.yearlyestimate;
            }).appendTo( $wrapper );
            $('#results div').each(function() {
                yearly_estimate = $(this).data('yearlyestimate');
                $(this).find('.yearly').text(yearly_estimate);
            });
        } else {
            // Sort by count
            var $wrapper = $('#results');
            $wrapper.find('div').sort(function (a, b) {
                return +b.dataset.count - +a.dataset.count;
            }).appendTo( $wrapper );
            $('#results div').each(function() {
                count = $(this).data('count');
                $(this).find('.yearly').text(count);
            });
        }
    });
});
</script>

<div id="controls">
<input type="checkbox" id="more"> Show More<br />
<input type="checkbox" id="sort"> Sort by Yearly Estimate
</div>

<div id='results'>
<?php

// Connects to WordPress.com and pulls blog ids from anchorhost username (New Method)
$access_key = '#################################';
$curl = curl_init( "https://public-api.wordpress.com/rest/v1/jetpack-blogs/" );
curl_setopt( $curl, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer ' . $access_key ) );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec( $curl );
$blog_ids = json_decode($response, true);
$blog_ids = $blog_ids['blogs']['blogs'];


// Loop through blogs
foreach ($blog_ids as $blog) { 

    // Connect to WordPress.com and pulls stats for the last 12 months
    // Docs: https://developer.wordpress.com/docs/api/1/get/sites/$site/stats/visits/
    $curl = curl_init( "https://public-api.wordpress.com/rest/v1/sites/".$blog['userblog_id']."/stats/visits?unit=month&quantity=12" );
    curl_setopt( $curl, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer ' . $access_key ) );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec( $curl );
    $stats = json_decode($response, true);

    $count = 0;
    $total = 0;
    $months = "";

    // Preps views for last 12 months for html output while calculating usage. 
    foreach ($stats["data"] as $stat) {
        if ($stat[0]) {
            $total = $total + 1;
            $months .= $stat[0] . " - " . $stat[1] . "<br />";
        }
        $count = $count + $stat[1];
    }
    if ($total == 0) {
        $monthly_average = 0;
    } else {
        $monthly_average = round($count / $total);
    }
    $yearly_estimate = $monthly_average * 12;
    echo '<div data-count="'. $count .'" data-blogid="'.$blog['userblog_id'].'" data-monthlyaverage="'.$monthly_average.'" data-yearlyestimate="'.$yearly_estimate.'"><span class="yearly">'. $count. '</span><span class="name">' . $blog['blogname'] . ' <small><a href="' . $blog['siteurl'] . '">' . $blog['domain'] . '</a></small></span><span class="months">' . $months .'<br />Monthly Average: '. $monthly_average . '<br />Yearly Estimate: ' . $yearly_estimate . '</span>';
    echo '</div>'; ?>

<?php } ?>
</div>
</html>