I remember seeing an ESP8266 project years ago that displayed a Youtubers subscriber count on an LED display. I was really impressed by that project. Recently I wondered if a similar thing could be done with wordpress.com stats, in this case not showing subscribers, but daily views.
I did come across this response to a WordPress forum How can I query blog stats via HTTP? that includes “You can, however, access your blog’s stats at an older (still active) API: http://stats.wordpress.com/csv.php” That post was back in 2013. It looks like that API is still running but as there are newer APIs it may not remain around too long.
While it only provides stats on a limited number of things it does include daily hits and total hits which are the two things that I’m interested in. It is also really easy to use and set up. To use it you only need your site URL and an API key.
Getting the URL and API key
The URL is just the site URL. The API key was just as easy to get. In a browser where I was already logged into my WordPress account I simply went to https://apikey.wordpress.com/. The API key displays on the page.
Testing in a browser
The next bit was to test it in a browser. Going to https://stats.wordpress.com/csv.php displays some information about it and the parameters, that is this:
Required parameters: api_key, blog_id or blog_uri.
Optional parameters: table, post_id, end, days, limit, summarize.
Parameters:
api_key String A secret unique to your WordPress.com user account.
blog_id Integer The number that identifies your blog. Find it in other stats URLs.
blog_uri String The full URL to the root directory of your blog. Including the full path.
table String One of views, postviews, referrers, referrers_grouped, searchterms, clicks, videoplays.
post_id Integer For use with postviews table. Also accepts a comma-separated list of integers.
end String The last day of the desired time frame. Format is 'Y-m-d' (e.g. 2007-05-01) and default is UTC date.
days Integer The length of the desired time frame. Default is 30. "-1" means unlimited.
period String For use with views table and the 'days' parameter. The desired time period grouping. 'week' or 'month'
Use 'days' as the number of results to return (e.g. '&period=week&days=12' to return 12 weeks)
limit Integer The maximum number of records to return. Default is 100. "-1" means unlimited. If days is -1, limit is capped at 500.
summarize Flag If present, summarizes all matching records.
format String The format the data is returned in, 'csv', 'xml' or 'json'. Default is 'csv'.
Non-working query example: ?api_key=123456789abc&blog_id=155&table=referrers&days=30&limit=-1&summarize
Result format is csv with one row per line and column names in first row.
Strings containing double quotes, commas, or "\n" are enclosed in double-quotes. Double-qoutes in strings are escaped by inserting another double-quote.
Example: "pet food" recipe
Becomes: """pet food"" recipe"
Developers, please cache the results for at least 180 seconds.
Next was to try and get the current days hits. I started by constructing a url. The first part with the blog url and api key is the same for all requests. In my case something like:
https://stats.wordpress.com/csv.php?api_key=myaccountkey&blog_uri=www.myblogname.com
I say something like because that url needs to have myaccountkey replaced with the actual key and myblogname changed to work.
The remainder of the url is made up of parameters to get the data I’m after
I tested these:
&days=-1 - lists hits per day for a long period. In my case it seems to go back to when the blog started &days=-1&summarize - displays only the hits for the last day
At this point I started seeing discrepancies with what I see within WordPress with the last days hits. In my case it was all about time zones. These seem to return the number of hits for the current day in UTC. I am UTC + 10 hours so I found I was not getting todays numbers until after 10:00am. Using the parameters below seems to fix it and returns todays numbers that match what I see in WordPress
&period=days&days=1&summarize
For my blog the full url looks like this:
https://stats.wordpress.com/csv.php?api_key=myaccountkey&blog_uri=www.myblogname.com&period=days&days=1&summarize
Next was trying to get the number of hits for all time. I was unable to find a way to return stats that included the current day, so I settled for this:
&days=-1&summarize
It is sometimes a few out but then catches up. I think this too is due to the difference in timezones. Not perfect, but good enough for me.
Writing an Arduino sketch
Next was the task of writing an Arduino sketch. I started with this Random Nerd Tutorial ESP32 HTTP GET and HTTP POST with Arduino IDE (JSON, URL Encoded, Text). I’ve found these tutorials to be really helpful for using the ESP32.
With a few modifications to one of the examples I’ve got it returning data. It returns a string of character, for example
"views"
8
Yes, this really is a small blog. To get that into a variable with just the number as an integer I’ve used subtring and toInt to keep only the part after the 8th character and turn it into an integer that I can use with LED displays.
todaysViews = payload.substring(8).toInt();
I don’t know if there is a better way to do this, but so far it is working.
I’ll list basic code that I started with that sends the number of the day’s views to the serial monitor. I’ve developed it further to run two LED displays and a speaker, but I think it needs more work before it should be released into the wild. I doubt anyone else would want to use the two different displays that I am using. I’ve only used them as I have a thing for LED displays and had some spare ones.

The Arduino code
/*
Sample sketch using ESP32 to fetch stats from wordpress.com
An old API http://stats.wordpress.com/csv.php is used to source the stats. Go to
this URL to get a list of parameters
An API key is required and can be gained by logging into your wordpress account
and going to https://apikey.wordpress.com/
Developers are asked to cache the results for at least 180 seconds (3 minutes)
*/
#include <WiFi.h>
#include <HTTPClient.h>
// Your Wifi network credentials
const char *ssid = "wifiname"; // Replace with WiFi network name
const char *password = "wifipassword"; // Replace with WiFi password
// Worpress URL and key
String BLOGURL = "www.blogname.com"; // The wordpress site URL
String APIKEY = "apikey"; // Replace with Wordpess account API key
// Store stats
int todaysViews;
// For storing last time the stats where checked
unsigned long lastTime = 0;
// Milliseconds between API calls. WordPress request no more than every 180 seconds
unsigned long timerDelay = 300000;
void setup(){
// Serial monitor for displaying results
Serial.begin(115200);
connectToWifi();
// Check stats imediately when connected
updateStats();
}
void loop(){
static unsigned long lastTime = 0;
// Check if it is time to update stats
if ((millis() - lastTime) > timerDelay) {
updateStats();
lastTime = millis();
}
}
void connectToWifi () {
// Connect to Wi-Fi
Serial.print("Connecting to: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("-----------------------");
}
void updateStats() {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
String serverName = "https://stats.wordpress.com/csv.php?api_key=" + APIKEY + "&blog_uri=" + BLOGURL + "&period=days&days=1&summarize";
http.begin(serverName.c_str());
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
// Print payload for debugging
Serial.println("Payload: ");
Serial.println(payload);
Serial.print("Today's views: ");
// Keep only part after 8 characters from start and convert to int
todaysViews = payload.substring(8).toInt();
Serial.println(todaysViews);
Serial.println("-----------------------");
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
}
I don’t know if anyone will find this useful, how long the API will be around or if there are security implications of using it. However, I found it to be an interesting project. Let me know if you have any feedback or know of how this might be achieved with more modern APIs.
Interesting that there’s not a way to grab the stats from a newer API. I took a quick look through the REST API endpoints, and couldn’t find anything related to view statistics… so it seems the legacy API is the only way to grab that data for now.
I picked up a 64×32 LED panel a few months ago and was thinking about building some sort of stats display for Twitter, YT, WP, and others… your post here is motivating me to do that project sooner rather than later. Great post as always, Garry!
LikeLike
Thanks for the feedback Ken. You got further with the REST API than I did. I didn’t really know where to start. I did find this post about using the APIs with PowerShell https://blog.darrenjrobinson.com/using-wordpress-apis-with-powershell/. It says there are two REST APIs so maybe one of them includes statistics, but again it was beyond my skills.
LikeLike